chromium/chrome/android/features/android_library_factory_tmpl.gni

# Copyright 2019 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//build/config/android/rules.gni")

# Declare an Android library factory target.
#
# This target creates an Android library target containing stripped java
# factory files. The generated target will not contain any .class files as all
# of them are excluded by jar_excluded_patterns. This target is intended to
# generate an empty factory that will be swapped out at build time by the real
# factory.
#
# A good way to limit the number of dependencies for these factory files is to
# encapsulate the creation logic into either the constructor of the internal
# Impl classes or a static create method in the Impl classes. See the sample
# code below as an example.
#
# Specific requirements for the java factory files are listed in the script:
# //chrome/android/features/create_stripped_java_factory.py
#
# Variables:
#   sources: A list of all java factory files to be stripped.
#   deps: Any deps needed by the generated Android library target.
#   generator_deps: If |sources| is generated, any deps needed to generate |sources|.
#
# Example:
#   android_library_factory("foo_java") {
#     sources = [
#       "android/org/chromium/foo/FooFactory.java",
#     ]
#     deps = [
#       ":foo_public_interface"
#     ]
#   }
#
#   //android/org/chromium/foo/FooFactory.java:
#   package org.chromium.foo;
#   public class FooFactory {
#     private FooFactory () {}
#
#     public static Foo createFoo() {
#       return FooImpl.create();
#     }
#   }
#
#   //out/Default/.../generated/org/chromium/foo/FooFactory.java:
#   package org.chromium.foo;
#   public class FooFactory {
#     private FooFactory () {}
#
#     public static Foo createFoo() {
#       return null;
#     }
#   }
#
#   //android/org/chromium/foo/FooImpl.java:
#   package org.chromium.foo;
#   import org.chromium.foo.internal.Parameter;
#   public class FooImpl implements Foo {
#     FooImpl(Parameter parameter) {}
#
#     static Foo create() {
#       return new FooImpl(new Parameter());
#     }
#   }
#
template("android_library_factory") {
  forward_variables_from(invoker, [ "testonly" ])

  # No underscores for factory target name to avoid crbug.com/908819.
  _process_factory_target_name = "${target_name}factory"
  _base_gen_dir = "${target_gen_dir}/${target_name}"

  action_foreach_with_pydeps(_process_factory_target_name) {
    if (defined(invoker.generator_deps)) {
      deps = invoker.generator_deps
    }

    script = "//chrome/android/features/create_stripped_java_factory.py"
    sources = invoker.sources
    outputs =
        [ "$_base_gen_dir/{{source_root_relative_dir}}/{{source_file_part}}" ]
    args = [
      "--output",
      rebase_path(outputs[0], root_build_dir),
      "--input={{source}}",
    ]
  }

  android_library(target_name) {
    deps = [ ":$_process_factory_target_name" ]
    if (defined(invoker.deps)) {
      deps += invoker.deps
    }
    sources = get_target_outputs(":$_process_factory_target_name")
    jar_excluded_patterns = [ "*" ]

    # Mark library as low priority since this one does not contain the actual
    # impl class. The real android_library() which provides the real
    # implementation should be first on the classpath.
    low_classpath_priority = true

    # Although this factory library does not contain the actual impl class, it
    # should still be the one that almost all targets depend on. This is so the
    # real implementation can be provided later.
    preferred_dep = true
  }
}