Refactor mojo_android_application

This relands the following CLs:
https://codereview.chromium.org/1233883003
https://codereview.chromium.org/1227953007

It fixes the issue with the dex file not having the correct name.

TBR=ppi@chromium.org

Review URL: https://codereview.chromium.org/1225393003 .
diff --git a/mojo/public/mojo_application.gni b/mojo/public/mojo_application.gni
index 7c4880e..32bdb7a 100644
--- a/mojo/public/mojo_application.gni
+++ b/mojo/public/mojo_application.gni
@@ -311,30 +311,111 @@
 }
 
 if (is_android) {
+  import("//build/config/android/rules.gni")
+
   # Declares an Android Mojo application consisting of an .so file and a
   # corresponding .dex.jar file.
   #
   # Variables:
-  #   input_so: the .so file to bundle
-  #   input_dex_jar: the .dex.jar file to bundle
-  #   deps / public_deps / data_deps (optional):
-  #       Dependencies. The targets that generate the .so/jar inputs should be
-  #       listed in either deps or public_deps.
+  #   sources (optional): The c++ sources.
+  #   deps (optional): The c++ dependencies.
+  #   java_sources (optional): The java sources.
+  #   java_deps (optional): The java dependencies.
+  #   jni_package (optional): The c++ package for the generated jni headers.
   #   output_name (optional): override for the output file name
+  #   public_deps / data_deps (optional): Dependencies.
   template("mojo_android_application") {
-    assert(defined(invoker.input_so))
-    assert(defined(invoker.input_dex_jar))
+    shared_library_name = "__${target_name}_lib"
+    library_basename = "lib${shared_library_name}.so"
+    if (defined(invoker.jni_package)) {
+      assert(defined(invoker.java_sources))
+      generate_jni_name = "__${target_name}_jni"
+    }
+    if (defined(invoker.java_sources)) {
+      java_library_name = "__${target_name}_java"
+    }
+    android_standalone_library_name = "__${target_name}_java_lib"
+    dex_output_path = "${target_gen_dir}/${target_name}.dex.jar"
+    zip_action_name = "__${target_name}_zip"
+    zip_action_output = "${target_gen_dir}/${target_name}.zip"
+    copy_symbols_target = "__${target_name}_copy_symbols"
+    final_target_name = target_name
 
-    zip_action_name = "${target_name}_zip"
-    zip_action_output = "$target_gen_dir/${target_name}.zip"
-    prepend_action_name = target_name
+    if (defined(invoker.jni_package)) {
+      generate_jni(generate_jni_name) {
+        visibility = [ ":${shared_library_name}" ]
+
+        sources = invoker.java_sources
+        jni_package = invoker.jni_package
+      }
+    }
+
+    shared_library(shared_library_name) {
+      visibility = [
+        ":${copy_symbols_target}",
+        ":${zip_action_name}",
+      ]
+
+      if (defined(invoker.sources)) {
+        sources = invoker.sources
+      }
+
+      deps = []
+      if (defined(invoker.jni_package)) {
+        deps += [ ":${generate_jni_name}" ]
+      }
+      if (defined(invoker.deps)) {
+        deps += invoker.deps
+      }
+    }
+
+    copy(copy_symbols_target) {
+      visibility = [ ":${final_target_name}" ]
+      deps = [
+        ":${shared_library_name}",
+      ]
+
+      sources = [
+        "${root_out_dir}/${library_basename}",
+      ]
+      outputs = [
+        "${root_out_dir}/symbols/${library_basename}",
+      ]
+    }
+
+    if (defined(invoker.java_sources)) {
+      android_library(java_library_name) {
+        visibility = [ ":*" ]
+
+        java_files = invoker.java_sources
+
+        if (defined(invoker.java_deps)) {
+          deps = invoker.java_deps
+        }
+      }
+    }
+
+    android_standalone_library(android_standalone_library_name) {
+      deps = []
+
+      if (defined(invoker.java_sources)) {
+        deps += [ ":${java_library_name}" ]
+      }
+
+      if (defined(invoker.java_deps)) {
+        deps += invoker.java_deps
+      }
+
+      dex_path = dex_output_path
+    }
+
     action(zip_action_name) {
-      visibility = [ ":$prepend_action_name" ]
+      visibility = [ ":${final_target_name}" ]
       script = "//build/android/gn/zip.py"
 
       inputs = [
-        invoker.input_so,
-        invoker.input_dex_jar,
+        "${root_out_dir}/lib.stripped/${library_basename}",
+        dex_output_path,
       ]
 
       output = zip_action_output
@@ -345,8 +426,8 @@
       rebase_inputs = rebase_path(inputs, root_build_dir)
       rebase_output = rebase_path(output, root_build_dir)
       args = [
-        "--inputs=$rebase_inputs",
-        "--output=$rebase_output",
+        "--inputs=${rebase_inputs}",
+        "--output=${rebase_output}",
       ]
 
       if (defined(invoker.deps)) {
@@ -361,12 +442,12 @@
     }
 
     if (defined(invoker.output_name)) {
-      mojo_output = "$root_out_dir/" + invoker.output_name + ".mojo"
+      mojo_output = "${root_out_dir}/" + invoker.output_name + ".mojo"
     } else {
-      mojo_output = "$root_out_dir/" + target_name + ".mojo"
+      mojo_output = "${root_out_dir}/" + target_name + ".mojo"
     }
 
-    action(target_name) {
+    action(final_target_name) {
       script = rebase_path("mojo/public/tools/prepend.py", ".", mojo_root)
 
       input = zip_action_output
@@ -382,13 +463,17 @@
       rebase_input = rebase_path(input, root_build_dir)
       rebase_output = rebase_path(output, root_build_dir)
       args = [
-        "--input=$rebase_input",
-        "--output=$rebase_output",
+        "--input=${rebase_input}",
+        "--output=${rebase_output}",
         "--line=#!mojo mojo:android_handler",
       ]
 
+      deps = [
+        ":${copy_symbols_target}",
+      ]
+
       public_deps = [
-        ":$zip_action_name",
+        ":${zip_action_name}",
       ]
     }
   }