Add the function of signing apex file with signapk tool.

Bug: 196204358
Test: b build //build/bazel/examples/apex/minimal:build.bazel.examples.apex.minimal
Test: jarsigner -verify -verbose build.bazel.examples.apex.minimal.apex
Change-Id: I7556c3b21d221ce67a6f5449321da9af6f75ac48
diff --git a/examples/apex/minimal/Android.bp b/examples/apex/minimal/Android.bp
index 7f96acd..ccef7b9 100644
--- a/examples/apex/minimal/Android.bp
+++ b/examples/apex/minimal/Android.bp
@@ -109,4 +109,6 @@
     binaries: [
         "build.bazel.examples.apex.cc_binary",
     ],
+
+    certificate: ":build.bazel.examples.apex.minimal.certificate"
 }
diff --git a/rules/apex.bzl b/rules/apex.bzl
index 21db21c..78772ac 100644
--- a/rules/apex.bzl
+++ b/rules/apex.bzl
@@ -128,7 +128,7 @@
     android_manifest = ctx.file.android_manifest
 
     # Outputs
-    apex_output_file = ctx.actions.declare_file(ctx.attr.name + ".apex")
+    apex_output_file = ctx.actions.declare_file(ctx.attr.name + ".apex.unsigned")
 
     # Arguments
     args = ctx.actions.args()
@@ -173,6 +173,41 @@
 
     return apex_output_file
 
+# Sign the generated unsigned apex file with signapk
+def _run_signapk(ctx, unsigned_apex_output_file):
+    # Inputs
+    apex_cert_info = ctx.attr.certificate[AndroidAppCertificateInfo]
+    privkey = apex_cert_info.pk8
+    pubkey = apex_cert_info.pem
+
+    inputs = [
+        unsigned_apex_output_file,
+        privkey,
+        pubkey,
+        ctx.executable._signapk,
+    ]
+
+    # Outputs
+    signed_apex_output_file = ctx.actions.declare_file(ctx.attr.name + ".apex")
+    outputs = [signed_apex_output_file]
+
+    # Arguments
+    args = ctx.actions.args()
+    args.add_all(["-a", 4096])
+    args.add_all(["--align-file-size"])
+    args.add_all([pubkey, privkey])
+    args.add_all([unsigned_apex_output_file, signed_apex_output_file])
+
+    ctx.actions.run(
+        inputs = inputs,
+        outputs = outputs,
+        executable = ctx.executable._signapk,
+        arguments = [args],
+        mnemonic = "BazelApexSigning",
+    )
+
+    return signed_apex_output_file
+
 # See the APEX section in the README on how to use this rule.
 def _apex_rule_impl(ctx):
     apex_toolchain = ctx.toolchains["//build/bazel/rules/apex:apex_toolchain_type"].toolchain_info
@@ -180,9 +215,10 @@
     apex_content_inputs, bazel_apexer_wrapper_manifest = _prepare_apexer_wrapper_inputs(ctx)
     apex_manifest_pb = _convert_apex_manifest_json_to_pb(ctx, apex_toolchain)
 
-    apex_output_file = _run_apexer(ctx, apex_toolchain, apex_content_inputs, bazel_apexer_wrapper_manifest, apex_manifest_pb)
+    unsigned_apex_output_file = _run_apexer(ctx, apex_toolchain, apex_content_inputs, bazel_apexer_wrapper_manifest, apex_manifest_pb)
+    signed_apex_output_file = _run_signapk(ctx, unsigned_apex_output_file)
 
-    files_to_build = depset([apex_output_file])
+    files_to_build = depset([signed_apex_output_file])
     return [DefaultInfo(files = files_to_build)]
 
 _apex = rule(
@@ -199,15 +235,15 @@
         "native_shared_libs": attr.label_list(
             providers = [ApexCcInfo],
             aspects = [apex_cc_aspect],
-            cfg = apex_transition
+            cfg = apex_transition,
         ),
         "binaries": attr.label_list(
             providers = [
                 # The dependency must produce _all_ of the providers in _one_ of these lists.
-                [ShBinaryInfo], # sh_binary
-                [StrippedCcBinaryInfo, CcInfo], # cc_binary (stripped)
+                [ShBinaryInfo],  # sh_binary
+                [StrippedCcBinaryInfo, CcInfo],  # cc_binary (stripped)
             ],
-            cfg = apex_transition
+            cfg = apex_transition,
         ),
         "prebuilts": attr.label_list(providers = [PrebuiltEtcInfo], cfg = apex_transition),
         # Required to use apex_transition. This is an acknowledgement to the risks of memory bloat when using transitions.
@@ -218,6 +254,12 @@
             executable = True,
             default = "//build/bazel/rules/apex:bazel_apexer_wrapper",
         ),
+        "_signapk": attr.label(
+            cfg = "host",
+            doc = "The signapk tool.",
+            executable = True,
+            default = "//build/make/tools/signapk",
+        ),
     },
     toolchains = ["//build/bazel/rules/apex:apex_toolchain_type"],
 )
diff --git a/rules/java/BUILD b/rules/java/BUILD
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/rules/java/BUILD
diff --git a/rules/java/library.bzl b/rules/java/library.bzl
new file mode 100644
index 0000000..f45cd51
--- /dev/null
+++ b/rules/java/library.bzl
@@ -0,0 +1,8 @@
+"""Macro wrapping the java_library for bp2build. """
+
+def java_library(name = "", srcs = [], deps = [], javacopts = [], **kwargs):
+    # Disable the error prone check of HashtableContains by default. See https://errorprone.info/bugpattern/HashtableContains
+    # HashtableContains error is reported when compiling //external/bouncycastle:bouncycastle-bcpkix-unbundled
+    opts = ["-Xep:HashtableContains:OFF"] + javacopts
+
+    native.java_library(name, srcs = srcs, deps = deps, javacopts = opts, **kwargs)