Snap for 7264743 from 34532fd620089244cbaa41c362d73d53db043d26 to s-keystone-qcom-release

Change-Id: I9814a7e6390f3ebf4df065b6f325f655fec28da5
diff --git a/.bazelci/postsubmit.yml b/.bazelci/postsubmit.yml
new file mode 100644
index 0000000..c1218a6
--- /dev/null
+++ b/.bazelci/postsubmit.yml
@@ -0,0 +1,22 @@
+---
+platforms:
+  ubuntu1604:
+    build_targets:
+    - "//..."
+    # test_targets:
+    # - "//..."
+  ubuntu1804:
+    build_targets:
+    - "//..."
+    # test_targets:
+    # - "//..."
+  macos:
+    build_targets:
+    - "//..."
+    # test_targets:
+    # - "//..."
+  windows:
+    build_targets:
+    - "//..."
+    # test_targets:
+    # - "//..."
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..dc35af2
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,9 @@
+# This the official list of authors for copyright purposes.
+# This file is distinct from the CONTRIBUTORS files.
+# See the latter for an explanation.
+
+# Names should be added to this file as:
+# Name or Organization <email address>
+# The email address is not required for organizations.
+
+Google LLC
diff --git a/CODEOWNERS b/CODEOWNERS
new file mode 100644
index 0000000..6902cfb
--- /dev/null
+++ b/CODEOWNERS
@@ -0,0 +1 @@
+* @djwhang @jin @ahumesky @mauriciogg @timpeut @git-str
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..99da6f8
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,39 @@
+Want to contribute? Great! First, read this page (including the small print at
+the end).
+
+### Before you contribute
+**Before we can use your code, you must sign the
+[Google Individual Contributor License Agreement](https://developers.google.com/open-source/cla/individual?csw=1)
+(CLA)**, which you can do online.
+
+The CLA is necessary mainly because you own the copyright to your changes,
+even after your contribution becomes part of our codebase, so we need your
+permission to use and distribute your code. We also need to be sure of
+various other things — for instance that you'll tell us if you know that
+your code infringes on other people's patents. You don't have to sign
+the CLA until after you've submitted your code for review and a member has
+approved it, but you must do it before we can put your code into our codebase.
+
+### The small print
+Contributions made by corporations are covered by a different agreement than
+the one above, the
+[Software Grant and Corporate Contributor License Agreement](https://cla.developers.google.com/about/google-corporate).
+
+### Contribution process
+
+1. Explain your idea and discuss your plan with members of the team. The best
+   way to do this is to create
+   an [issue](https://github.com/bazelbuild/rules_android/issues) or comment on
+   an existing issue.
+1. Prepare a git commit with your change. Don't forget to
+   add [tests](https://github.com/bazelbuild/rules_android/tree/master/tests).
+   Run the existing tests with `bazel test //...`. Update
+   [README.md](https://github.com/bazelbuild/rules_android/blob/master/README.md)
+   if appropriate.
+1. [Create a pull request](https://help.github.com/articles/creating-a-pull-request/).
+   This will start the code review process. **All submissions, including
+   submissions by project members, require review.**
+1. You may be asked to make some changes. You'll also need to sign the CLA at
+   this point, if you haven't done so already. Our continuous integration bots
+   will test your change automatically on supported platforms. Once everything
+   looks good, your change will be merged.
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
new file mode 100644
index 0000000..8fc0e51
--- /dev/null
+++ b/CONTRIBUTORS
@@ -0,0 +1,16 @@
+# People who have agreed to one of the CLAs and can contribute patches.
+# The AUTHORS file lists the copyright holders; this file
+# lists people.  For example, Google employees are listed here
+# but not in AUTHORS, because Google holds the copyright.
+#
+# https://developers.google.com/open-source/cla/individual
+# https://developers.google.com/open-source/cla/corporate
+#
+# Names should be added to this file as:
+# Name <email address>
+Daniel Whang <djwhang@google.com>
+Mauricio Galindo <mauriciogg@google.com>
+Stefan Ramsauer <str@google.com>
+Tim Peut <timpeut@google.com>
+Alex Humesky <ahumesky@google.com>
+Jingwen Chen <jingwen@google.com>
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..5ce332f
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,18 @@
+name: "rules_android"
+description:
+    "Bazel build rules for building Android Apps. "
+    "These are the open-sourced Android build rules from Google3."
+
+third_party {
+  url {
+    type: HOMEPAGE
+    value: "https://github.com/bazelbuild/rules_android"
+  }
+  url {
+    type: GIT
+    value: "https://github.com/bazelbuild/rules_android"
+  }
+  version: "ab13c86fafc79b965b7ad6e4d91c821760d869d3"
+  last_upgrade_date { year: 2021 month: 2 day: 12 }
+  license_type: NOTICE
+}
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_APACHE2
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..6cba04f
--- /dev/null
+++ b/README.md
@@ -0,0 +1,51 @@
+# Android support in Bazel
+
+## Disclaimer
+
+NOTE: This branch contains a development preview of the Starlark implementation of Android rules for Bazel. This code is incomplete and may not function as-is.
+
+Bazel 4.0.0 or newer and the following flags are necessary to use these rules:
+```
+--experimental_enable_android_migration_apis
+--experimental_google_legacy_api
+--incompatible_java_common_parameters
+--android_databinding_use_v3_4_args
+--experimental_android_databinding_v2
+```
+
+Also, register the Android toolchains in the `WORKSPACE` file with:
+```
+register_toolchains(
+  "@build_bazel_rules_android//toolchains/android:android_default_toolchain",
+  "@build_bazel_rules_android//toolchains/android_sdk:android_sdk_tools",
+)
+```
+(Assuming that the Android rules repository in the `WORKSPACE` file is named `build_bazel_rules_android`.)
+
+## Overview
+
+This repository contains the Starlark implementation of Android rules in Bazel.
+
+The rules are being incrementally converted from their native implementations
+in the [Bazel source
+tree](https://source.bazel.build/bazel/+/master:src/main/java/com/google/devtools/build/lib/rules/android/).
+
+For the list of Android rules, see the Bazel [documentation](https://docs.bazel.build/versions/master/be/android.html).
+
+## Getting Started
+To use the new Bazel Android rules, add the following to your WORKSPACE file:
+
+    load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+    http_archive(
+        name = "build_bazel_rules_android",
+        urls = ["https://github.com/bazelbuild/rules_android/archive/v0.1.1.zip"],
+        sha256 = "cd06d15dd8bb59926e4d65f9003bfc20f9da4b2519985c27e190cddc8b7a7806",
+        strip_prefix = "rules_android-0.1.1",
+    )
+
+Then, in your BUILD files, import and use the rules:
+
+    load("@build_bazel_rules_android//rules:rules.bzl", "android_library")
+    android_library(
+        ...
+    )
diff --git a/ROADMAP.md b/ROADMAP.md
new file mode 100644
index 0000000..57e46c3
--- /dev/null
+++ b/ROADMAP.md
@@ -0,0 +1,71 @@
+
+# Android Bazel Roadmap
+
+This document describes the major release milestones for the Android Bazel
+Rules. There are three major pillars that we are focused on when developing the
+Android rules - **Performance**, **Features**, and **Developer Experience** -
+and for each milestone we list the main items for each pillar. Progress on each
+item is tracked via an issue.
+
+If you have feedback on this roadmap (including feature and reprioritization
+requests) please open an issue or comment on the existing one.
+
+## Rules Alpha (est. mid 2019)
+
+The primary goal of the Rules Alpha release is to start collecting feedback from
+projects and developers that are interested in being early adopters of the
+rules. Our intention is for Rules Alpha to be a 1:1 identical drop-in
+replacement for the native Android rules, although undoubtedly there will be
+missing features and we cannot always guarantee 100% backwards compatibility.
+
+### Performance
+
+*   Use AAPT2 for resource processing
+*   Use D8 for Dexing
+
+### Features
+
+*   Support android_instrumentation_test on macOS
+*   Support building and testing on Google Cloud Platform Remote Build Execution
+*   Support new Android App Bundle format
+*   Accept APKs directly into android_instrumentation_test
+*   Simplified package and dependency management
+*   Improve Kotlin interoperability
+*   Integration with Bazel's platforms and toolchains support
+*   Modern and correct NDK support
+
+### Developer Experience
+
+*   Documentation for Android with Bazel compatibility across Windows, macOS,
+    Linux
+*   Documentation for Android with Bazel compatibility across Android Studio
+    versions
+*   Stable and reliable CI
+*   NDK documentation and samples
+
+## Rules Beta (est. late 2019)
+
+The goal for the Rules Beta release is to provide a stable, (mostly) feature
+complete version of the rules for all developers and projects. We intend the
+Rules Beta release to be the first version of the rules to be broadly adopted,
+and will comply with Bazel's backwards compatibility guarantees.
+
+### Performance
+
+*   Improve resource processing speed and incrementality
+*   Decouple Java compilation from R.class generation
+*   Launch Bazel mobile-install v2
+
+### Features
+
+*   New android_application rule for app packaging / sourceless binary /
+    android_application
+*   Improved support for AAR creation
+*   Support Databinding 3.4.0 (v2)
+*   Support `bazel coverage` for all test rules
+*   Integration with Android Lint
+
+### Developer Experience
+
+*   Document best practices
+*   Best in class tutorials and migration guides
diff --git a/WORKSPACE b/WORKSPACE
new file mode 100644
index 0000000..9c8339a
--- /dev/null
+++ b/WORKSPACE
@@ -0,0 +1,3 @@
+workspace(name = "build_bazel_rules_android")
+
+register_toolchains("//android/toolchains/emulator:all")
diff --git a/rules/BUILD b/rules/BUILD
new file mode 100644
index 0000000..b233605
--- /dev/null
+++ b/rules/BUILD
@@ -0,0 +1,18 @@
+exports_files([
+    "data_binding_annotation_template.txt",
+    "res_v3_dummy_AndroidManifest.xml",
+    "res_v3_dummy_R.txt",
+    "robolectric_properties_template.txt",
+])
+
+alias(
+    name = "ResourceProcessorBusyBox",
+    actual = "@bazel_tools//tools/android:busybox",
+    visibility =  ["//visibility:public"],
+)
+
+alias(
+    name = "current_java_runtime",
+    actual = "@bazel_tools//tools/jdk:current_java_runtime",
+    visibility = ["//visibility:public"],
+)
diff --git a/rules/aar_import/BUILD b/rules/aar_import/BUILD
new file mode 100644
index 0000000..50d41fe
--- /dev/null
+++ b/rules/aar_import/BUILD
@@ -0,0 +1,21 @@
+# The aar_import rule.
+
+load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
+
+licenses(["notice"])
+
+exports_files(["rule.bzl"])
+
+filegroup(
+    name = "all_files",
+    srcs = glob(["**"]),
+)
+
+bzl_library(
+    name = "bzl",
+    srcs = glob(["*.bzl"]),
+    deps = [
+        "@rules_android//rules:common_bzl",
+        "@rules_android//rules/flags:bzl",
+    ],
+)
diff --git a/rules/aar_import/attrs.bzl b/rules/aar_import/attrs.bzl
new file mode 100644
index 0000000..5ac9c7a
--- /dev/null
+++ b/rules/aar_import/attrs.bzl
@@ -0,0 +1,64 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Attributes."""
+
+load(
+    "@rules_android//rules:attrs.bzl",
+    _attrs = "attrs",
+)
+
+ATTRS = _attrs.add(
+    dict(
+        aar = attr.label(
+            allow_single_file = [".aar"],
+            mandatory = True,
+        ),
+        data = attr.label_list(allow_files = True),
+        deps = attr.label_list(
+            allow_files = False,
+            providers = [JavaInfo],
+        ),
+        exports = attr.label_list(
+            allow_files = False,
+            allow_rules = ["aar_import", "java_import"],
+        ),
+        has_lint_jar = attr.bool(
+            default = False,
+            doc = "Whether the aar contains a lint.jar. This is required to " +
+                  "know at analysis time if a lint jar is included in the aar.",
+        ),
+        package = attr.string(
+            doc = "Package to use while processing the aar at analysis time. " +
+                  "This needs to be the same value as the manifest's package.",
+        ),
+        srcjar = attr.label(
+            allow_single_file = [".srcjar"],
+            doc =
+                "A srcjar file that contains the source code for the JVM " +
+                "artifacts stored within the AAR.",
+        ),
+        _flags = attr.label(
+            default = "@rules_android//rules/flags",
+        ),
+        _java_toolchain = attr.label(
+            default = Label("//tools/jdk:toolchain_android_only"),
+        ),
+        _host_javabase = attr.label(
+            cfg = "host",
+            default = Label("//tools/jdk:current_java_runtime"),
+        ),
+    ),
+    _attrs.DATA_CONTEXT,
+)
diff --git a/rules/aar_import/impl.bzl b/rules/aar_import/impl.bzl
new file mode 100644
index 0000000..96baa2b
--- /dev/null
+++ b/rules/aar_import/impl.bzl
@@ -0,0 +1,547 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Implementation."""
+
+load(
+    "@rules_android//rules:acls.bzl",
+    _acls = "acls",
+)
+load(
+    "@rules_android//rules:common.bzl",
+    _common = "common",
+)
+load("@rules_android//rules:intellij.bzl", "intellij")
+load(
+    "@rules_android//rules:java.bzl",
+    _java = "java",
+)
+load("@rules_android//rules:providers.bzl", "AndroidLintRulesInfo")
+load(
+    "@rules_android//rules:resources.bzl",
+    _resources = "resources",
+)
+load(
+    "@rules_android//rules:utils.bzl",
+    _get_android_toolchain = "get_android_toolchain",
+    _utils = "utils",
+)
+
+RULE_PREFIX = "_aar"
+ANDROID_MANIFEST = "AndroidManifest.xml"
+LINT_JAR = "lint.jar"
+_UNEXPECTED_LINT_JAR_ERROR = (
+    "In target %s, has_lint_jar attribute is required when the aar contains " +
+    "a lint.jar file."
+)
+
+def _create_aar_artifact(ctx, name):
+    return ctx.actions.declare_file("%s/%s/%s" % (RULE_PREFIX, ctx.label.name, name))
+
+def _create_aar_tree_artifact(ctx, name):
+    return ctx.actions.declare_directory("%s/unzipped/%s/%s" % (RULE_PREFIX, name, ctx.label.name))
+
+# Create an action to extract a file (specified by the parameter filename) from an AAR file.
+def _extract_single_file(
+        ctx,
+        out_file,
+        aar,
+        filename,
+        unzip_tool):
+    args = ctx.actions.args()
+    args.add(aar)
+    args.add(filename)
+    args.add("-d", out_file.dirname)
+
+    ctx.actions.run(
+        executable = unzip_tool,
+        arguments = [args],
+        inputs = [aar],
+        outputs = [out_file],
+        mnemonic = "AarFileExtractor",
+        progress_message = "Extracting %s from %s" % (filename, aar.basename),
+    )
+
+def _extract_resources(
+        ctx,
+        out_resources_dir,
+        out_assets_dir,
+        aar,
+        aar_resources_extractor_tool):
+    args = ctx.actions.args()
+    args.add("--input_aar", aar)
+    args.add("--output_res_dir", out_resources_dir.path)
+    args.add("--output_assets_dir", out_assets_dir.path)
+    ctx.actions.run(
+        executable = aar_resources_extractor_tool,
+        arguments = [args],
+        inputs = [aar],
+        outputs = [out_resources_dir, out_assets_dir],
+        mnemonic = "AarResourcesExtractor",
+        progress_message = "Extracting resources and assets from %s" % aar.basename,
+    )
+
+def _extract_native_libs(
+        ctx,
+        output_zip,
+        aar,
+        android_cpu,
+        aar_native_libs_zip_creator_tool):
+    args = ctx.actions.args()
+    args.add("--input_aar", aar)
+    args.add("--cpu", android_cpu)
+    args.add("--output_zip", output_zip)
+    ctx.actions.run(
+        executable = aar_native_libs_zip_creator_tool,
+        arguments = [args],
+        inputs = [aar],
+        outputs = [output_zip],
+        mnemonic = "AarNativeLibsFilter",
+        progress_message = "Filtering AAR native libs by architecture",
+    )
+
+def _process_resources(
+        ctx,
+        aar,
+        manifest,
+        deps,
+        aar_resources_extractor_tool,
+        unzip_tool):
+    # Extract resources and assets, if they exist.
+    resources = _create_aar_tree_artifact(ctx, "resources")
+    assets = _create_aar_tree_artifact(ctx, "assets")
+    _extract_resources(
+        ctx,
+        resources,
+        assets,
+        aar,
+        aar_resources_extractor_tool,
+    )
+
+    resources_ctx = _resources.process_starlark(
+        ctx,
+        manifest = manifest,
+        assets = [assets],
+        assets_dir = assets.path,
+        resource_files = [resources],
+        stamp_manifest = False,
+        deps = ctx.attr.deps,
+        exports = ctx.attr.exports,
+        exports_manifest = getattr(ctx.attr, "exports_manifest", True),
+
+        # Tool and Processing related inputs
+        aapt = _get_android_toolchain(ctx).aapt2.files_to_run,
+        android_jar = ctx.attr._android_sdk[AndroidSdkInfo].android_jar,
+        android_kit = _get_android_toolchain(ctx).android_kit.files_to_run,
+        busybox = _get_android_toolchain(ctx).android_resources_busybox.files_to_run,
+        java_toolchain = _common.get_java_toolchain(ctx),
+        host_javabase = _common.get_host_javabase(ctx),
+        instrument_xslt = _utils.only(_get_android_toolchain(ctx).add_g3itr_xslt.files.to_list()),
+        xsltproc = _get_android_toolchain(ctx).xsltproc_tool.files_to_run,
+    )
+
+    # TODO: replace android_data
+    # data_ctx = android_data.make_context(ctx.actions, ctx.attr)
+    # resource_apk = android_data.process_aar_import_data(
+    #     data_ctx,
+    #     resources,
+    #     assets,
+    #     manifest,
+    #     deps = deps,
+    # )
+    # resources_ctx["validation_results"].append(
+    #     _utils.only(resource_apk[AndroidResourcesInfo].direct_android_resources.to_list()).java_class_jar,
+    # )
+    # resources_ctx["providers"].append(resource_apk[AndroidResourcesInfo])
+    # resources_ctx["providers"].append(resource_apk[AndroidAssetsInfo])
+
+    if not _acls.in_aar_propagate_resources(str(ctx.label)):
+        resources_ctx["providers"] = []
+
+    return struct(**resources_ctx)
+
+def _extract_jars(
+        ctx,
+        out_jars_tree_artifact,
+        out_jars_params_file,
+        aar,
+        aar_embedded_jars_extractor_tool):
+    args = ctx.actions.args()
+    args.add("--input_aar", aar)
+    args.add("--output_dir", out_jars_tree_artifact.path)
+    args.add("--output_singlejar_param_file", out_jars_params_file)
+    ctx.actions.run(
+        executable = aar_embedded_jars_extractor_tool,
+        arguments = [args],
+        inputs = [aar],
+        outputs = [out_jars_tree_artifact, out_jars_params_file],
+        mnemonic = "AarEmbeddedJarsExtractor",
+        progress_message = "Extracting classes.jar and libs/*.jar from %s" % aar.basename,
+    )
+
+def _merge_jars(
+        ctx,
+        out_jar,
+        jars_tree_artifact,
+        jars_param_file,
+        single_jar_tool):
+    args = ctx.actions.args()
+    args.add("--output", out_jar)
+    args.add("--dont_change_compression")
+    args.add("--normalize")
+    args.add("@" + jars_param_file.path)
+    ctx.actions.run(
+        executable = single_jar_tool,
+        arguments = [args],
+        inputs = [jars_tree_artifact, jars_param_file],
+        outputs = [out_jar],
+        mnemonic = "AarJarsMerger",
+        progress_message = "Merging AAR embedded jars",
+    )
+
+def _extract_and_merge_jars(
+        ctx,
+        out_jar,
+        aar,
+        aar_embedded_jars_extractor_tool,
+        single_jar_tool):
+    """Extracts all the Jars within the AAR and produces a single jar.
+
+    An AAR may have multiple Jar files embedded within it. This method
+    extracts and merges all Jars.
+    """
+    jars_tree_artifact = _create_aar_tree_artifact(ctx, "jars")
+    jars_params_file = _create_aar_artifact(ctx, "jar_merging_params")
+    _extract_jars(
+        ctx,
+        jars_tree_artifact,
+        jars_params_file,
+        aar,
+        aar_embedded_jars_extractor_tool,
+    )
+    _merge_jars(
+        ctx,
+        out_jar,
+        jars_tree_artifact,
+        jars_params_file,
+        single_jar_tool,
+    )
+
+def _create_import_deps_check(
+        ctx,
+        jars_to_check,
+        declared_deps,
+        transitive_deps,
+        bootclasspath,
+        jdeps_output,
+        import_deps_checker_tool,
+        host_javabase):
+    args = ctx.actions.args()
+    args.add_all(jars_to_check, before_each = "--input")
+    args.add_all(declared_deps, before_each = "--directdep")
+    args.add_all(transitive_deps, before_each = "--classpath_entry")
+    args.add_all(bootclasspath, before_each = "--bootclasspath_entry")
+    args.add("--checking_mode=error")
+    args.add("--jdeps_output", jdeps_output)
+    args.add("--rule_label", ctx.label)
+
+    _java.run(
+        ctx = ctx,
+        host_javabase = host_javabase,
+        executable = import_deps_checker_tool,
+        arguments = [args],
+        inputs = depset(
+            jars_to_check,
+            transitive = [
+                declared_deps,
+                transitive_deps,
+                bootclasspath,
+            ],
+        ),
+        outputs = [jdeps_output],
+        mnemonic = "ImportDepsChecker",
+        progress_message = "Checking the completeness of the deps for %s" % jars_to_check,
+    )
+
+def _process_jars(
+        ctx,
+        out_jar,
+        aar,
+        source_jar,
+        r_java,
+        deps,
+        exports,
+        enable_desugar_java8,
+        enable_imports_deps_check,
+        bootclasspath,
+        desugar_java8_extra_bootclasspath,
+        aar_embedded_jars_extractor_tool,
+        import_deps_checker_tool,
+        single_jar_tool,
+        java_toolchain,
+        host_javabase):
+    providers = []
+    validation_results = []
+    r_java_info = [r_java] if r_java else []
+
+    # An aar may have multple Jar files, extract and merge into a single jar.
+    _extract_and_merge_jars(
+        ctx,
+        out_jar,
+        aar,
+        aar_embedded_jars_extractor_tool,
+        single_jar_tool,
+    )
+
+    java_infos = deps + exports
+
+    if enable_desugar_java8:
+        bootclasspath = depset(transitive = [
+            desugar_java8_extra_bootclasspath,
+            bootclasspath,
+        ])
+
+    merged_java_info = java_common.merge(java_infos + r_java_info)
+    jdeps_artifact = _create_aar_artifact(ctx, "jdeps.proto")
+    _create_import_deps_check(
+        ctx,
+        [out_jar],
+        merged_java_info.compile_jars,
+        merged_java_info.transitive_compile_time_jars,
+        bootclasspath,
+        jdeps_artifact,
+        import_deps_checker_tool,
+        host_javabase,
+    )
+    if enable_imports_deps_check:
+        validation_results.append(jdeps_artifact)
+
+    java_info = JavaInfo(
+        out_jar,
+        compile_jar = java_common.stamp_jar(
+            actions = ctx.actions,
+            jar = out_jar,
+            target_label = ctx.label,
+            java_toolchain = java_toolchain,
+        ),
+        source_jar = source_jar,
+        neverlink = False,
+        deps = r_java_info + java_infos,  # TODO(djwhang): Exports are not deps.
+        exports =
+            (r_java_info if _acls.in_aar_import_exports_r_java(str(ctx.label)) else []) +
+            java_infos,  # TODO(djwhang): Deps are not exports.
+        # TODO(djwhang): AarImportTest is not expecting jdeps, enable or remove it completely
+        # jdeps = jdeps_artifact,
+    )
+    providers.append(java_info)
+
+    return struct(
+        java_info = java_info,
+        providers = providers,
+        validation_results = validation_results,
+    )
+
+def _validate_rule(
+        ctx,
+        aar,
+        manifest,
+        checks):
+    package = _java.resolve_package_from_label(ctx.label, ctx.attr.package)
+    validation_output = ctx.actions.declare_file("%s_validation_output" % ctx.label.name)
+
+    args = ctx.actions.args()
+    args.add("-aar", aar)
+    inputs = [aar]
+    args.add("-label", str(ctx.label))
+    if _acls.in_aar_import_pkg_check(str(ctx.label)):
+        args.add("-pkg", package)
+        args.add("-manifest", manifest)
+        inputs.append(manifest)
+    if ctx.attr.has_lint_jar:
+        args.add("-has_lint_jar")
+    args.add("-output", validation_output)
+
+    ctx.actions.run(
+        executable = checks,
+        arguments = [args],
+        inputs = inputs,
+        outputs = [validation_output],
+        mnemonic = "ValidateAAR",
+        progress_message = "Validating aar_import %s" % str(ctx.label),
+    )
+    return validation_output
+
+def _process_lint_rules(
+        ctx,
+        aar,
+        unzip_tool):
+    providers = []
+
+    if ctx.attr.has_lint_jar:
+        lint_jar = _create_aar_artifact(ctx, LINT_JAR)
+        _extract_single_file(
+            ctx,
+            lint_jar,
+            aar,
+            LINT_JAR,
+            unzip_tool,
+        )
+        providers.append(AndroidLintRulesInfo(
+            lint_jar = lint_jar,
+        ))
+
+    providers.extend(_utils.collect_providers(
+        AndroidLintRulesInfo,
+        ctx.attr.exports,
+    ))
+    return providers
+
+def impl(ctx):
+    """The rule implementation.
+
+    Args:
+      ctx: The context.
+
+    Returns:
+      A list of providers.
+    """
+    providers = []
+    validation_outputs = []
+
+    aar = _utils.only(ctx.files.aar)
+    unzip_tool = _get_android_toolchain(ctx).unzip_tool.files_to_run
+
+    # Extract the AndroidManifest.xml from the AAR.
+    android_manifest = _create_aar_artifact(ctx, ANDROID_MANIFEST)
+    _extract_single_file(
+        ctx,
+        android_manifest,
+        aar,
+        ANDROID_MANIFEST,
+        unzip_tool,
+    )
+
+    resources_ctx = _process_resources(
+        ctx,
+        aar = aar,
+        manifest = android_manifest,
+        deps = ctx.attr.deps,
+        aar_resources_extractor_tool =
+            _get_android_toolchain(ctx).aar_resources_extractor.files_to_run,
+        unzip_tool = unzip_tool,
+    )
+    providers.extend(resources_ctx.providers)
+
+    merged_jar = _create_aar_artifact(ctx, "classes_and_libs_merged.jar")
+    jvm_ctx = _process_jars(
+        ctx,
+        out_jar = merged_jar,
+        aar = aar,
+        source_jar = ctx.file.srcjar,
+        deps = _utils.collect_providers(JavaInfo, ctx.attr.deps),
+        r_java = resources_ctx.r_java,
+        exports = _utils.collect_providers(JavaInfo, ctx.attr.exports),
+        enable_desugar_java8 = ctx.fragments.android.desugar_java8,
+        enable_imports_deps_check =
+            _acls.in_aar_import_deps_checker(str(ctx.label)),
+        aar_embedded_jars_extractor_tool =
+            _get_android_toolchain(ctx).aar_embedded_jars_extractor.files_to_run,
+        bootclasspath =
+            ctx.attr._java_toolchain[java_common.JavaToolchainInfo].bootclasspath,
+        desugar_java8_extra_bootclasspath =
+            _get_android_toolchain(ctx).desugar_java8_extra_bootclasspath.files,
+        import_deps_checker_tool =
+            _get_android_toolchain(ctx).import_deps_checker.files_to_run,
+        single_jar_tool =
+            ctx.attr._java_toolchain[java_common.JavaToolchainInfo].single_jar,
+        java_toolchain =
+            ctx.attr._java_toolchain[java_common.JavaToolchainInfo],
+        host_javabase = ctx.attr._host_javabase,
+    )
+    providers.extend(jvm_ctx.providers)
+    validation_outputs.extend(jvm_ctx.validation_results)
+
+    native_libs = _create_aar_artifact(ctx, "native_libs.zip")
+    _extract_native_libs(
+        ctx,
+        native_libs,
+        aar = aar,
+        android_cpu = ctx.fragments.android.android_cpu,
+        aar_native_libs_zip_creator_tool =
+            _get_android_toolchain(ctx).aar_native_libs_zip_creator.files_to_run,
+    )
+    native_libs_infos = _utils.collect_providers(
+        AndroidNativeLibsInfo,
+        ctx.attr.deps,
+        ctx.attr.exports,
+    )
+    providers.append(
+        AndroidNativeLibsInfo(
+            depset(
+                [native_libs],
+                transitive = [info.native_libs for info in native_libs_infos],
+            ),
+        ),
+    )
+
+    lint_providers = _process_lint_rules(
+        ctx,
+        aar = aar,
+        unzip_tool = unzip_tool,
+    )
+    providers.extend(lint_providers)
+
+    validation_outputs.append(_validate_rule(
+        ctx,
+        aar = aar,
+        manifest = android_manifest,
+        checks = _get_android_toolchain(ctx).aar_import_checks.files_to_run,
+    ))
+
+    providers.append(
+        intellij.make_android_ide_info(
+            ctx,
+            java_package = _java.resolve_package_from_label(ctx.label, ctx.attr.package),
+            manifest = resources_ctx.merged_manifest,
+            defines_resources = resources_ctx.defines_resources,
+            merged_manifest = resources_ctx.merged_manifest,
+            resources_apk = resources_ctx.resources_apk,
+            r_jar = _utils.only(resources_ctx.r_java.outputs.jars) if resources_ctx.r_java else None,
+            java_info = jvm_ctx.java_info,
+            signed_apk = None,  # signed_apk, always empty for aar_import
+            apks_under_test = [],  # apks_under_test, always empty for aar_import
+            native_libs = dict(),  # nativelibs, always empty for aar_import
+            idlclass = _get_android_toolchain(ctx).idlclass.files_to_run,
+            host_javabase = _common.get_host_javabase(ctx),
+        ),
+    )
+
+    providers.append(OutputGroupInfo(_validation = depset(validation_outputs)))
+
+    # There isn't really any use case for building an aar_import target on its own, so the files to
+    # build could be empty. The R class JAR and merged JARs are added here as a sanity check for
+    # Bazel developers so that `bazel build java/com/my_aar_import` will fail if the resource
+    # processing or JAR merging steps fail.
+    files_to_build = []
+    files_to_build.extend(resources_ctx.validation_results)  # TODO(djwhang): This should be validation.
+    files_to_build.append(merged_jar)
+
+    providers.append(
+        DefaultInfo(
+            files = depset(files_to_build),
+            runfiles = ctx.runfiles(),
+        ),
+    )
+
+    return providers
diff --git a/rules/aar_import/rule.bzl b/rules/aar_import/rule.bzl
new file mode 100644
index 0000000..fa78a88
--- /dev/null
+++ b/rules/aar_import/rule.bzl
@@ -0,0 +1,26 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""aar_import rule."""
+
+load(":attrs.bzl", _ATTRS = "ATTRS")
+load(":impl.bzl", _impl = "impl")
+
+aar_import = rule(
+    attrs = _ATTRS,
+    fragments = ["android"],
+    implementation = _impl,
+    provides = [AndroidNativeLibsInfo, JavaInfo],
+    toolchains = ["@rules_android//toolchains/android:toolchain_type"],
+)
diff --git a/rules/acls.bzl b/rules/acls.bzl
new file mode 100644
index 0000000..ade99db
--- /dev/null
+++ b/rules/acls.bzl
@@ -0,0 +1,318 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Access Control Lists.
+
+To create a new list:
+  1. Create new .bzl file in this directory with a list of targets.
+  2. Create matching method in this file.
+  3. Add matching method to struct.
+
+To check an ACL:
+  1. Import the `acls` struct.
+  2. Check `acls.list_name(fqn)` using the //fully/qualified:target
+
+To update a list:
+  1. Directly add/remove/edit targets in the appropriate .bzl file
+"""
+
+load("@rules_android//rules/acls:aar_import_deps_checker.bzl", "AAR_IMPORT_DEPS_CHECKER_FALLBACK", "AAR_IMPORT_DEPS_CHECKER_ROLLOUT")
+load("@rules_android//rules/acls:aar_import_explicit_exports_manifest.bzl", "AAR_IMPORT_EXPLICIT_EXPORTS_MANIFEST")
+load("@rules_android//rules/acls:aar_import_exports_r_java.bzl", "AAR_IMPORT_EXPORTS_R_JAVA")
+load("@rules_android//rules/acls:aar_import_package_check.bzl", "AAR_IMPORT_PKG_CHECK_FALLBACK", "AAR_IMPORT_PKG_CHECK_ROLLOUT")
+load("@rules_android//rules/acls:aar_propagate_resources.bzl", "AAR_PROPAGATE_RESOURCES_FALLBACK", "AAR_PROPAGATE_RESOURCES_ROLLOUT")
+load("@rules_android//rules/acls:ait_install_snapshots.bzl", "APP_INSTALLATION_SNAPSHOT", "APP_INSTALLATION_SNAPSHOT_FALLBACK")
+load("@rules_android//rules/acls:ait_virtual_device.bzl", "AIT_VIRTUAL_DEVICE_FALLBACK", "AIT_VIRTUAL_DEVICE_ROLLOUT")
+load("@rules_android//rules/acls:allow_resource_conflicts.bzl", "ALLOW_RESOURCE_CONFLICTS")
+load("@rules_android//rules/acls:android_archive_dogfood.bzl", "ANDROID_ARCHIVE_DOGFOOD")
+load("@rules_android//rules/acls:android_test_lockdown.bzl", "ANDROID_TEST_LOCKDOWN_GENERATOR_FUNCTIONS", "ANDROID_TEST_LOCKDOWN_TARGETS")
+load("@rules_android//rules/acls:android_device_plugin_rollout.bzl", "ANDROID_DEVICE_PLUGIN_FALLBACK", "ANDROID_DEVICE_PLUGIN_ROLLOUT")
+load("@rules_android//rules/acls:android_instrumentation_binary_starlark_resources.bzl", "ANDROID_INSTRUMENTATION_BINARY_STARLARK_RESOURCES_FALLBACK", "ANDROID_INSTRUMENTATION_BINARY_STARLARK_RESOURCES_ROLLOUT")
+load("@rules_android//rules/acls:android_feature_splits_dogfood.bzl", "ANDROID_FEATURE_SPLITS_DOGFOOD")
+load("@rules_android//rules/acls:android_library_implicit_exports.bzl", "ANDROID_LIBRARY_IMPLICIT_EXPORTS", "ANDROID_LIBRARY_IMPLICIT_EXPORTS_GENERATOR_FUNCTIONS")
+load("@rules_android//rules/acls:android_library_resources_without_srcs.bzl", "ANDROID_LIBRARY_RESOURCES_WITHOUT_SRCS", "ANDROID_LIBRARY_RESOURCES_WITHOUT_SRCS_GENERATOR_FUNCTIONS")
+load("@rules_android//rules/acls:android_lint_rollout.bzl", "ANDROID_LINT_ROLLOUT")
+load("@rules_android//rules/acls:android_build_stamping_rollout.bzl", "ANDROID_BUILD_STAMPING_FALLBACK", "ANDROID_BUILD_STAMPING_ROLLOUT")
+load("@rules_android//rules/acls:b122039567.bzl", "B122039567")
+load("@rules_android//rules/acls:b123854163.bzl", "B123854163")
+load("@rules_android//rules/acls:dex2oat_opts.bzl", "CAN_USE_DEX2OAT_OPTIONS")
+load("@rules_android//rules/acls:fix_application_id.bzl", "FIX_APPLICATION_ID_FALLBACK", "FIX_APPLICATION_ID_ROLLOUT")
+load("@rules_android//rules/acls:fix_export_exporting_rollout.bzl", "FIX_EXPORT_EXPORTING_FALLBACK", "FIX_EXPORT_EXPORTING_ROLLOUT")
+load("@rules_android//rules/acls:fix_resource_transitivity_rollout.bzl", "FIX_RESOURCE_TRANSITIVITY_FALLBACK", "FIX_RESOURCE_TRANSITIVITY_ROLLOUT")
+load("@rules_android//rules/acls:host_dex2oat_rollout.bzl", "AIT_USE_HOST_DEX2OAT_ROLLOUT", "AIT_USE_HOST_DEX2OAT_ROLLOUT_FALLBACK")
+load("@rules_android//rules/acls:install_apps_in_data.bzl", "INSTALL_APPS_IN_DATA")
+load("@rules_android//rules/acls:local_test_multi_proto.bzl", "LOCAL_TEST_MULTI_PROTO_PKG")
+load("@rules_android//rules/acls:local_test_rollout.bzl", "LOCAL_TEST_FALLBACK", "LOCAL_TEST_ROLLOUT")
+load("@rules_android//rules/acls:local_test_starlark_resources.bzl", "LOCAL_TEST_STARLARK_RESOURCES_FALLBACK", "LOCAL_TEST_STARLARK_RESOURCES_ROLLOUT")
+load("@rules_android//rules/acls:nitrogen_test_runner_rollout.bzl", "NITROGEN_AT_TEST_RUNNER_ROLLOUT", "NITROGEN_TEST_RUNNER_FALLBACK", "NITROGEN_TEST_RUNNER_ROLLOUT")
+load("@rules_android//rules/acls:android_test_platform_rollout.bzl", "ANDROID_TEST_PLATFORM_FALLBACK", "ANDROID_TEST_PLATFORM_ROLLOUT")
+load("@rules_android//rules/acls:sourceless_binary_rollout.bzl", "SOURCELESS_BINARY_FALLBACK", "SOURCELESS_BINARY_ROLLOUT")
+load("@rules_android//rules/acls:test_to_instrument_test_rollout.bzl", "TEST_TO_INSTRUMENT_TEST_FALLBACK", "TEST_TO_INSTRUMENT_TEST_ROLLOUT")
+load(
+    "@rules_android//rules/acls:partial_jetification_targets.bzl",
+    "PARTIAL_JETIFICATION_TARGETS_FALLBACK",
+    "PARTIAL_JETIFICATION_TARGETS_ROLLOUT",
+)
+load("@rules_android//rules/acls:kt_android_library_rollout.bzl", "KT_ANDROID_LIBRARY_FALLBACK", "KT_ANDROID_LIBRARY_ROLLOUT")
+
+def _in_aar_import_deps_checker(fqn):
+    return not _matches(fqn, AAR_IMPORT_DEPS_CHECKER_FALLBACK_DICT) and _matches(fqn, AAR_IMPORT_DEPS_CHECKER_ROLLOUT_DICT)
+
+def _in_aar_import_explicit_exports_manifest(fqn):
+    return _matches(fqn, AAR_IMPORT_EXPLICIT_EXPORTS_MANIFEST_DICT)
+
+def _in_aar_import_exports_r_java(fqn):
+    return _matches(fqn, AAR_IMPORT_EXPORTS_R_JAVA_DICT)
+
+def _in_aar_import_pkg_check(fqn):
+    return not _matches(fqn, AAR_IMPORT_PKG_CHECK_FALLBACK_DICT) and _matches(fqn, AAR_IMPORT_PKG_CHECK_ROLLOUT_DICT)
+
+def _in_aar_propagate_resources(fqn):
+    return not _matches(fqn, AAR_PROPAGATE_RESOURCES_FALLBACK_DICT) and _matches(fqn, AAR_PROPAGATE_RESOURCES_ROLLOUT_DICT)
+
+def _in_ait_virtual_device(fqn):
+    return not _matches(fqn, AIT_VIRTUAL_DEVICE_FALLBACK_DICT) and _matches(fqn, AIT_VIRTUAL_DEVICE_ROLLOUT_DICT)
+
+def _in_android_archive_dogfood(fqn):
+    return _matches(fqn, ANDROID_ARCHIVE_DOGFOOD_DICT)
+
+def _in_android_device_plugin_rollout(fqn):
+    return not _matches(fqn, ANDROID_DEVICE_PLUGIN_FALLBACK_DICT) and _matches(fqn, ANDROID_DEVICE_PLUGIN_ROLLOUT_DICT)
+
+def _in_android_instrumentation_binary_starlark_resources(fqn):
+    return not _matches(fqn, ANDROID_INSTRUMENTATION_BINARY_STARLARK_RESOURCES_FALLBACK_DICT) and _matches(fqn, ANDROID_INSTRUMENTATION_BINARY_STARLARK_RESOURCES_ROLLOUT_DICT)
+
+def _in_android_feature_splits_dogfood(fqn):
+    return _matches(fqn, ANDROID_FEATURE_SPLITS_DOGFOOD_DICT)
+
+def _in_android_lint_rollout(fqn):
+    return _matches(fqn, ANDROID_LINT_ROLLOUT_DICT)
+
+def _in_android_build_stamping_rollout(fqn):
+    return not _matches(fqn, ANDROID_BUILD_STAMPING_FALLBACK_DICT) and _matches(fqn, ANDROID_BUILD_STAMPING_ROLLOUT_DICT)
+
+def _in_android_test_lockdown_allowlist(fqn, generator):
+    return _matches(fqn, ANDROID_TEST_LOCKDOWN_TARGETS_DICT) or generator in ANDROID_TEST_LOCKDOWN_GENERATOR_FUNCTIONS_DICT
+
+def _in_b122039567(fqn):
+    return _matches(fqn, B122039567_DICT)
+
+def _in_b123854163(fqn):
+    return _matches(fqn, B123854163_DICT)
+
+def _in_android_library_implicit_exports(fqn):
+    return _matches(fqn, ANDROID_LIBRARY_IMPLICIT_EXPORTS_DICT)
+
+def _in_android_library_implicit_exports_generator_functions(gfn):
+    return gfn in ANDROID_LIBRARY_IMPLICIT_EXPORTS_GENERATOR_FUNCTIONS_DICT
+
+def _in_android_library_resources_without_srcs(fqn):
+    return _matches(fqn, ANDROID_LIBRARY_RESOURCES_WITHOUT_SRCS_DICT)
+
+def _in_android_library_resources_without_srcs_generator_functions(gfn):
+    return gfn in ANDROID_LIBRARY_RESOURCES_WITHOUT_SRCS_GENERATOR_FUNCTIONS_DICT
+
+def _in_app_installation_snapshot(fqn):
+    return not _matches(fqn, APP_INSTALLATION_SNAPSHOT_FALLBACK_DICT) and _matches(fqn, APP_INSTALLATION_SNAPSHOT_DICT)
+
+def _in_dex2oat_opts(fqn):
+    return _matches(fqn, CAN_USE_DEX2OAT_OPTIONS_DICT)
+
+def _in_fix_application_id(fqn):
+    return not _matches(fqn, FIX_APPLICATION_ID_FALLBACK_DICT) and _matches(fqn, FIX_APPLICATION_ID_ROLLOUT_DICT)
+
+def _in_fix_export_exporting_rollout(fqn):
+    return not _matches(fqn, FIX_EXPORT_EXPORTING_FALLBACK_DICT) and _matches(fqn, FIX_EXPORT_EXPORTING_ROLLOUT_DICT)
+
+def _in_fix_resource_transivity_rollout(fqn):
+    return not _matches(fqn, FIX_RESOURCE_TRANSIVITY_FALLBACK_DICT) and _matches(fqn, FIX_RESOURCE_TRANSIVITY_ROLLOUT_DICT)
+
+def _in_host_dex2oat_rollout(fqn):
+    return not _matches(fqn, AIT_USE_HOST_DEX2OAT_ROLLOUT_FALLBACK_DICT) and _matches(fqn, AIT_USE_HOST_DEX2OAT_ROLLOUT_DICT)
+
+def _in_install_apps_in_data(fqn):
+    return _matches(fqn, AIT_INSTALL_APPS_IN_DATA_DICT)
+
+def _in_local_test_multi_proto(fqn):
+    return _matches(fqn, LOCAL_TEST_MULTI_PROTO_PKG_DICT)
+
+def _in_local_test_rollout(fqn):
+    return not _matches(fqn, LOCAL_TEST_FALLBACK_DICT) and _matches(fqn, LOCAL_TEST_ROLLOUT_DICT)
+
+def _in_local_test_starlark_resources(fqn):
+    return not _matches(fqn, LOCAL_TEST_STARLARK_RESOURCES_FALLBACK_DICT) and _matches(fqn, LOCAL_TEST_STARLARK_RESOURCES_ROLLOUT_DICT)
+
+def _in_nitrogen_test_runner_rollout(fqn):
+    return not _matches(fqn, NITROGEN_TEST_RUNNER_FALLBACK_DICT) and _matches(fqn, NITROGEN_TEST_RUNNER_ROLLOUT_DICT)
+
+def _in_nitrogen_at_test_runner_rollout(fqn):
+    return not _matches(fqn, NITROGEN_TEST_RUNNER_FALLBACK_DICT) and _matches(fqn, NITROGEN_AT_TEST_RUNNER_ROLLOUT_DICT)
+
+def _in_android_test_platform_rollout(fqn):
+    return not _matches(fqn, ANDROID_TEST_PLATFORM_FALLBACK_DICT) and _matches(fqn, ANDROID_TEST_PLATFORM_ROLLOUT_DICT)
+
+def _in_sourceless_binary_rollout(fqn):
+    return not _matches(fqn, SOURCELESS_BINARY_FALLBACK_DICT) and _matches(fqn, SOURCELESS_BINARY_ROLLOUT_DICT)
+
+def _in_test_to_instrument_test_rollout(fqn):
+    return not _matches(fqn, TEST_TO_INSTRUMENT_TEST_FALLBACK_DICT) and _matches(fqn, TEST_TO_INSTRUMENT_TEST_ROLLOUT_DICT)
+
+def _in_allow_resource_conflicts(fqn):
+    return _matches(fqn, ALLOW_RESOURCE_CONFLICTS_DICT)
+
+def _in_partial_jetification_targets(fqn):
+    return not _matches(fqn, PARTIAL_JETIFICATION_TARGETS_FALLBACK_DICT) and _matches(fqn, PARTIAL_JETIFICATION_TARGETS_ROLLOUT_DICT)
+
+def _in_kt_android_library_rollout(fqn):
+    return not _matches(fqn, KT_ANDROID_LIBRARY_FALLBACK_DICT) and _matches(fqn, KT_ANDROID_LIBRARY_ROLLOUT_DICT)
+
+def _make_dict(lst):
+    """Do not use this method outside of this file."""
+    return {t: True for t in lst}
+
+AAR_IMPORT_DEPS_CHECKER_FALLBACK_DICT = _make_dict(AAR_IMPORT_DEPS_CHECKER_FALLBACK)
+AAR_IMPORT_DEPS_CHECKER_ROLLOUT_DICT = _make_dict(AAR_IMPORT_DEPS_CHECKER_ROLLOUT)
+AAR_IMPORT_EXPLICIT_EXPORTS_MANIFEST_DICT = _make_dict(AAR_IMPORT_EXPLICIT_EXPORTS_MANIFEST)
+AAR_IMPORT_EXPORTS_R_JAVA_DICT = _make_dict(AAR_IMPORT_EXPORTS_R_JAVA)
+AAR_IMPORT_PKG_CHECK_FALLBACK_DICT = _make_dict(AAR_IMPORT_PKG_CHECK_FALLBACK)
+AAR_IMPORT_PKG_CHECK_ROLLOUT_DICT = _make_dict(AAR_IMPORT_PKG_CHECK_ROLLOUT)
+AAR_PROPAGATE_RESOURCES_FALLBACK_DICT = _make_dict(AAR_PROPAGATE_RESOURCES_FALLBACK)
+AAR_PROPAGATE_RESOURCES_ROLLOUT_DICT = _make_dict(AAR_PROPAGATE_RESOURCES_ROLLOUT)
+AIT_VIRTUAL_DEVICE_FALLBACK_DICT = _make_dict(AIT_VIRTUAL_DEVICE_FALLBACK)
+AIT_VIRTUAL_DEVICE_ROLLOUT_DICT = _make_dict(AIT_VIRTUAL_DEVICE_ROLLOUT)
+ANDROID_ARCHIVE_DOGFOOD_DICT = _make_dict(ANDROID_ARCHIVE_DOGFOOD)
+ANDROID_DEVICE_PLUGIN_ROLLOUT_DICT = _make_dict(ANDROID_DEVICE_PLUGIN_ROLLOUT)
+ANDROID_DEVICE_PLUGIN_FALLBACK_DICT = _make_dict(ANDROID_DEVICE_PLUGIN_FALLBACK)
+ANDROID_INSTRUMENTATION_BINARY_STARLARK_RESOURCES_ROLLOUT_DICT = _make_dict(ANDROID_INSTRUMENTATION_BINARY_STARLARK_RESOURCES_ROLLOUT)
+ANDROID_INSTRUMENTATION_BINARY_STARLARK_RESOURCES_FALLBACK_DICT = _make_dict(ANDROID_INSTRUMENTATION_BINARY_STARLARK_RESOURCES_FALLBACK)
+ANDROID_FEATURE_SPLITS_DOGFOOD_DICT = _make_dict(ANDROID_FEATURE_SPLITS_DOGFOOD)
+ANDROID_LIBRARY_IMPLICIT_EXPORTS_DICT = _make_dict(ANDROID_LIBRARY_IMPLICIT_EXPORTS)
+ANDROID_LIBRARY_IMPLICIT_EXPORTS_GENERATOR_FUNCTIONS_DICT = _make_dict(ANDROID_LIBRARY_IMPLICIT_EXPORTS_GENERATOR_FUNCTIONS)
+ANDROID_LIBRARY_RESOURCES_WITHOUT_SRCS_DICT = _make_dict(ANDROID_LIBRARY_RESOURCES_WITHOUT_SRCS)
+ANDROID_LIBRARY_RESOURCES_WITHOUT_SRCS_GENERATOR_FUNCTIONS_DICT = _make_dict(ANDROID_LIBRARY_RESOURCES_WITHOUT_SRCS_GENERATOR_FUNCTIONS)
+ANDROID_LINT_ROLLOUT_DICT = _make_dict(ANDROID_LINT_ROLLOUT)
+ANDROID_BUILD_STAMPING_ROLLOUT_DICT = _make_dict(ANDROID_BUILD_STAMPING_ROLLOUT)
+ANDROID_BUILD_STAMPING_FALLBACK_DICT = _make_dict(ANDROID_BUILD_STAMPING_FALLBACK)
+ANDROID_TEST_LOCKDOWN_GENERATOR_FUNCTIONS_DICT = _make_dict(ANDROID_TEST_LOCKDOWN_GENERATOR_FUNCTIONS)
+ANDROID_TEST_LOCKDOWN_TARGETS_DICT = _make_dict(ANDROID_TEST_LOCKDOWN_TARGETS)
+APP_INSTALLATION_SNAPSHOT_DICT = _make_dict(APP_INSTALLATION_SNAPSHOT)
+APP_INSTALLATION_SNAPSHOT_FALLBACK_DICT = _make_dict(APP_INSTALLATION_SNAPSHOT_FALLBACK)
+B122039567_DICT = _make_dict(B122039567)
+B123854163_DICT = _make_dict(B123854163)
+CAN_USE_DEX2OAT_OPTIONS_DICT = _make_dict(CAN_USE_DEX2OAT_OPTIONS)
+FIX_APPLICATION_ID_FALLBACK_DICT = _make_dict(FIX_APPLICATION_ID_FALLBACK)
+FIX_APPLICATION_ID_ROLLOUT_DICT = _make_dict(FIX_APPLICATION_ID_ROLLOUT)
+FIX_RESOURCE_TRANSIVITY_FALLBACK_DICT = _make_dict(FIX_RESOURCE_TRANSITIVITY_FALLBACK)
+FIX_RESOURCE_TRANSIVITY_ROLLOUT_DICT = _make_dict(FIX_RESOURCE_TRANSITIVITY_ROLLOUT)
+FIX_EXPORT_EXPORTING_FALLBACK_DICT = _make_dict(FIX_EXPORT_EXPORTING_FALLBACK)
+FIX_EXPORT_EXPORTING_ROLLOUT_DICT = _make_dict(FIX_EXPORT_EXPORTING_ROLLOUT)
+AIT_USE_HOST_DEX2OAT_ROLLOUT_DICT = _make_dict(AIT_USE_HOST_DEX2OAT_ROLLOUT)
+AIT_USE_HOST_DEX2OAT_ROLLOUT_FALLBACK_DICT = _make_dict(AIT_USE_HOST_DEX2OAT_ROLLOUT_FALLBACK)
+AIT_INSTALL_APPS_IN_DATA_DICT = _make_dict(INSTALL_APPS_IN_DATA)
+LOCAL_TEST_MULTI_PROTO_PKG_DICT = _make_dict(LOCAL_TEST_MULTI_PROTO_PKG)
+LOCAL_TEST_FALLBACK_DICT = _make_dict(LOCAL_TEST_FALLBACK)
+LOCAL_TEST_ROLLOUT_DICT = _make_dict(LOCAL_TEST_ROLLOUT)
+LOCAL_TEST_STARLARK_RESOURCES_FALLBACK_DICT = _make_dict(LOCAL_TEST_STARLARK_RESOURCES_FALLBACK)
+LOCAL_TEST_STARLARK_RESOURCES_ROLLOUT_DICT = _make_dict(LOCAL_TEST_STARLARK_RESOURCES_ROLLOUT)
+NITROGEN_TEST_RUNNER_FALLBACK_DICT = _make_dict(NITROGEN_TEST_RUNNER_FALLBACK)
+NITROGEN_TEST_RUNNER_ROLLOUT_DICT = _make_dict(NITROGEN_TEST_RUNNER_ROLLOUT)
+NITROGEN_AT_TEST_RUNNER_ROLLOUT_DICT = _make_dict(NITROGEN_AT_TEST_RUNNER_ROLLOUT)
+ANDROID_TEST_PLATFORM_FALLBACK_DICT = _make_dict(ANDROID_TEST_PLATFORM_FALLBACK)
+ANDROID_TEST_PLATFORM_ROLLOUT_DICT = _make_dict(ANDROID_TEST_PLATFORM_ROLLOUT)
+SOURCELESS_BINARY_FALLBACK_DICT = _make_dict(SOURCELESS_BINARY_FALLBACK)
+SOURCELESS_BINARY_ROLLOUT_DICT = _make_dict(SOURCELESS_BINARY_ROLLOUT)
+TEST_TO_INSTRUMENT_TEST_FALLBACK_DICT = _make_dict(TEST_TO_INSTRUMENT_TEST_FALLBACK)
+TEST_TO_INSTRUMENT_TEST_ROLLOUT_DICT = _make_dict(TEST_TO_INSTRUMENT_TEST_ROLLOUT)
+ALLOW_RESOURCE_CONFLICTS_DICT = _make_dict(ALLOW_RESOURCE_CONFLICTS)
+PARTIAL_JETIFICATION_TARGETS_ROLLOUT_DICT = _make_dict(PARTIAL_JETIFICATION_TARGETS_ROLLOUT)
+PARTIAL_JETIFICATION_TARGETS_FALLBACK_DICT = _make_dict(PARTIAL_JETIFICATION_TARGETS_FALLBACK)
+KT_ANDROID_LIBRARY_ROLLOUT_DICT = _make_dict(KT_ANDROID_LIBRARY_ROLLOUT)
+KT_ANDROID_LIBRARY_FALLBACK_DICT = _make_dict(KT_ANDROID_LIBRARY_FALLBACK)
+
+def _matches(fqn, dct):
+    if not fqn.startswith("//"):
+        fail("Fully qualified target should start with '//', got: " + fqn)
+
+    if fqn in dct:
+        return True
+
+    pkg_and_target = fqn.split(":")
+    if len(pkg_and_target) != 2:
+        fail("Expected fully qualified target, got: " + fqn)
+    pkg = pkg_and_target[0]
+
+    if (pkg + ":__pkg__") in dct:
+        return True
+
+    pkg = pkg.lstrip("//")
+    pkg_parts = pkg.split("/")
+    ancestor_pkg = "//"
+
+    if (ancestor_pkg + ":__subpackages__") in dct:
+        return True
+
+    for pkg_part in pkg_parts:
+        ancestor_pkg = (
+            (ancestor_pkg + "/" + pkg_part) if ancestor_pkg != "//" else ("//" + pkg_part)
+        )
+        if (ancestor_pkg + ":__subpackages__") in dct:
+            return True
+
+    return False
+
+acls = struct(
+    in_aar_import_deps_checker = _in_aar_import_deps_checker,
+    in_aar_import_pkg_check = _in_aar_import_pkg_check,
+    in_aar_import_explicit_exports_manifest = _in_aar_import_explicit_exports_manifest,
+    in_aar_import_exports_r_java = _in_aar_import_exports_r_java,
+    in_aar_propagate_resources = _in_aar_propagate_resources,
+    in_ait_virtual_device = _in_ait_virtual_device,
+    in_b122039567 = _in_b122039567,
+    in_b123854163 = _in_b123854163,
+    in_android_archive_dogfood = _in_android_archive_dogfood,
+    in_android_device_plugin_rollout = _in_android_device_plugin_rollout,
+    in_android_instrumentation_binary_starlark_resources = _in_android_instrumentation_binary_starlark_resources,
+    in_android_feature_splits_dogfood = _in_android_feature_splits_dogfood,
+    in_android_library_implicit_exports = _in_android_library_implicit_exports,
+    in_android_library_implicit_exports_generator_functions = _in_android_library_implicit_exports_generator_functions,
+    in_android_library_resources_without_srcs = _in_android_library_resources_without_srcs,
+    in_android_library_resources_without_srcs_generator_functions = _in_android_library_resources_without_srcs_generator_functions,
+    in_android_lint_rollout = _in_android_lint_rollout,
+    in_android_build_stamping_rollout = _in_android_build_stamping_rollout,
+    in_android_test_lockdown_allowlist = _in_android_test_lockdown_allowlist,
+    in_app_installation_snapshot = _in_app_installation_snapshot,
+    in_dex2oat_opts = _in_dex2oat_opts,
+    in_fix_application_id = _in_fix_application_id,
+    in_fix_export_exporting_rollout = _in_fix_export_exporting_rollout,
+    in_fix_resource_transivity_rollout = _in_fix_resource_transivity_rollout,
+    in_host_dex2oat_rollout = _in_host_dex2oat_rollout,
+    in_install_apps_in_data = _in_install_apps_in_data,
+    in_local_test_multi_proto = _in_local_test_multi_proto,
+    in_local_test_rollout = _in_local_test_rollout,
+    in_local_test_starlark_resources = _in_local_test_starlark_resources,
+    in_nitrogen_test_runner_rollout = _in_nitrogen_test_runner_rollout,
+    in_nitrogen_at_test_runner_rollout = _in_nitrogen_at_test_runner_rollout,
+    in_android_test_platform_rollout = _in_android_test_platform_rollout,
+    in_sourceless_binary_rollout = _in_sourceless_binary_rollout,
+    in_test_to_instrument_test_rollout = _in_test_to_instrument_test_rollout,
+    in_allow_resource_conflicts = _in_allow_resource_conflicts,
+    in_partial_jetification_targets = _in_partial_jetification_targets,
+    in_kt_android_library_rollout = _in_kt_android_library_rollout,
+)
+
+# Visible for testing
+testing = struct(
+    matches = _matches,
+    make_dict = _make_dict,
+)
diff --git a/rules/acls/BUILD b/rules/acls/BUILD
new file mode 100644
index 0000000..3c45ae3
--- /dev/null
+++ b/rules/acls/BUILD
@@ -0,0 +1,6 @@
+load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
+
+bzl_library(
+    name = "bzl",
+    srcs = glob(["*.bzl"]),
+)
diff --git a/rules/acls/aar_import_deps_checker.bzl b/rules/acls/aar_import_deps_checker.bzl
new file mode 100644
index 0000000..dabfd31
--- /dev/null
+++ b/rules/acls/aar_import_deps_checker.bzl
@@ -0,0 +1,27 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allowlist to run ImportDepsChecker on aar_import.
+
+See b/148478031 for context.
+"""
+
+# keep sorted
+AAR_IMPORT_DEPS_CHECKER_ROLLOUT = [
+    "//:__subpackages__",
+]
+
+# keep sorted
+AAR_IMPORT_DEPS_CHECKER_FALLBACK = [
+]
diff --git a/rules/acls/aar_import_explicit_exports_manifest.bzl b/rules/acls/aar_import_explicit_exports_manifest.bzl
new file mode 100644
index 0000000..fb3a0b9
--- /dev/null
+++ b/rules/acls/aar_import_explicit_exports_manifest.bzl
@@ -0,0 +1,19 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for aar_import rule to explcitly set exports_manifest."""
+
+# keep sorted
+AAR_IMPORT_EXPLICIT_EXPORTS_MANIFEST = [
+]
diff --git a/rules/acls/aar_import_exports_r_java.bzl b/rules/acls/aar_import_exports_r_java.bzl
new file mode 100644
index 0000000..c0a07a4
--- /dev/null
+++ b/rules/acls/aar_import_exports_r_java.bzl
@@ -0,0 +1,19 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for aar_import rule to export the R.java."""
+
+# keep sorted
+AAR_IMPORT_EXPORTS_R_JAVA = [
+]
diff --git a/rules/acls/aar_import_package_check.bzl b/rules/acls/aar_import_package_check.bzl
new file mode 100644
index 0000000..54b2b51
--- /dev/null
+++ b/rules/acls/aar_import_package_check.bzl
@@ -0,0 +1,21 @@
+# Copyright 2021 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for checking the package value with the manifest."""
+AAR_IMPORT_PKG_CHECK_ROLLOUT = [
+    "//:__subpackages__",
+]
+
+AAR_IMPORT_PKG_CHECK_FALLBACK = [
+]
diff --git a/rules/acls/aar_propagate_resources.bzl b/rules/acls/aar_propagate_resources.bzl
new file mode 100644
index 0000000..48ab3ba
--- /dev/null
+++ b/rules/acls/aar_propagate_resources.bzl
@@ -0,0 +1,24 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allowlist for propagating resources and assets from aar_import (b/138322659)."""
+
+# keep sorted
+AAR_PROPAGATE_RESOURCES_ROLLOUT = [
+    "//:__subpackages__",
+]
+
+# keep sorted
+AAR_PROPAGATE_RESOURCES_FALLBACK = [
+]
diff --git a/rules/acls/ait_install_snapshots.bzl b/rules/acls/ait_install_snapshots.bzl
new file mode 100644
index 0000000..ff11e64
--- /dev/null
+++ b/rules/acls/ait_install_snapshots.bzl
@@ -0,0 +1,23 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Packages in this list will use devices with app installation snapshots."""
+
+# keep sorted
+APP_INSTALLATION_SNAPSHOT = [
+]
+
+# keep sorted
+APP_INSTALLATION_SNAPSHOT_FALLBACK = [
+]
diff --git a/rules/acls/ait_virtual_device.bzl b/rules/acls/ait_virtual_device.bzl
new file mode 100644
index 0000000..f5ec1b6
--- /dev/null
+++ b/rules/acls/ait_virtual_device.bzl
@@ -0,0 +1,21 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for switching to virtual_device in android_instrumentation_test."""
+AIT_VIRTUAL_DEVICE_ROLLOUT = [
+    "//:__subpackages__",
+]
+
+AIT_VIRTUAL_DEVICE_FALLBACK = [
+]
diff --git a/rules/acls/allow_resource_conflicts.bzl b/rules/acls/allow_resource_conflicts.bzl
new file mode 100644
index 0000000..d4f9742
--- /dev/null
+++ b/rules/acls/allow_resource_conflicts.bzl
@@ -0,0 +1,20 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+""" Packages of android_binary, android_test, and android_local_test targets that are allowed to contain resource conflicts.
+
+See b/125484033.
+"""
+
+ALLOW_RESOURCE_CONFLICTS = []
diff --git a/rules/acls/android_archive_dogfood.bzl b/rules/acls/android_archive_dogfood.bzl
new file mode 100644
index 0000000..2320db3
--- /dev/null
+++ b/rules/acls/android_archive_dogfood.bzl
@@ -0,0 +1,20 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allowlist for targets able to use the android_archive rule."""
+
+# keep sorted
+ANDROID_ARCHIVE_DOGFOOD = [
+    "//:__subpackages__",
+]
diff --git a/rules/acls/android_binary_starlark_resources.bzl b/rules/acls/android_binary_starlark_resources.bzl
new file mode 100644
index 0000000..0291cb6
--- /dev/null
+++ b/rules/acls/android_binary_starlark_resources.bzl
@@ -0,0 +1,22 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for rollout of Starlark resource processing pipeline in android_binary."""
+
+ANDROID_BINARY_STARLARK_RESOURCES_ROLLOUT = [
+    "//:__subpackages__",
+]
+
+ANDROID_BINARY_STARLARK_RESOURCES_FALLBACK = [
+]
diff --git a/rules/acls/android_build_stamping_rollout.bzl b/rules/acls/android_build_stamping_rollout.bzl
new file mode 100644
index 0000000..5b1169a
--- /dev/null
+++ b/rules/acls/android_build_stamping_rollout.bzl
@@ -0,0 +1,22 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for build stamping in the Android Rules."""
+
+# keep sorted
+ANDROID_BUILD_STAMPING_ROLLOUT = [
+]
+
+# keep sorted
+ANDROID_BUILD_STAMPING_FALLBACK = []
diff --git a/rules/acls/android_device_plugin_rollout.bzl b/rules/acls/android_device_plugin_rollout.bzl
new file mode 100644
index 0000000..310da7d
--- /dev/null
+++ b/rules/acls/android_device_plugin_rollout.bzl
@@ -0,0 +1,26 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow and fallback lists for ATP Device Plugin rollout."""
+
+# Targets for ATP Device Plugin Rollout
+ANDROID_DEVICE_PLUGIN_ROLLOUT = [
+    "//:__subpackages__",
+]
+
+_READY_TO_ROLLOUT_IN_NEXT_RELEASE = [
+]
+
+ANDROID_DEVICE_PLUGIN_FALLBACK = [
+] + _READY_TO_ROLLOUT_IN_NEXT_RELEASE
diff --git a/rules/acls/android_feature_splits_dogfood.bzl b/rules/acls/android_feature_splits_dogfood.bzl
new file mode 100644
index 0000000..159ef42
--- /dev/null
+++ b/rules/acls/android_feature_splits_dogfood.bzl
@@ -0,0 +1,24 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allowlist for packages able to use Android feature splits.
+
+Dynamic feature splits are still in development and at this stage are only suitable for use
+in an experimental capacity.
+"""
+
+# keep sorted
+ANDROID_FEATURE_SPLITS_DOGFOOD = [
+    "//:__subpackages__",
+]
diff --git a/rules/acls/android_instrumentation_binary_starlark_resources.bzl b/rules/acls/android_instrumentation_binary_starlark_resources.bzl
new file mode 100644
index 0000000..0e55315
--- /dev/null
+++ b/rules/acls/android_instrumentation_binary_starlark_resources.bzl
@@ -0,0 +1,22 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for rollout of Starlark resource processing pipeline in instrumentation binaries."""
+
+ANDROID_INSTRUMENTATION_BINARY_STARLARK_RESOURCES_ROLLOUT = [
+    "//:__subpackages__",
+]
+
+ANDROID_INSTRUMENTATION_BINARY_STARLARK_RESOURCES_FALLBACK = [
+]
diff --git a/rules/acls/android_library_implicit_exports.bzl b/rules/acls/android_library_implicit_exports.bzl
new file mode 100644
index 0000000..521c2ac
--- /dev/null
+++ b/rules/acls/android_library_implicit_exports.bzl
@@ -0,0 +1,23 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for b/144163743 - deprecated implicit exports."""
+
+# These macros can create android_library targets with deps and no srcs with no way for
+# their users to control this.
+ANDROID_LIBRARY_IMPLICIT_EXPORTS_GENERATOR_FUNCTIONS = [
+]
+
+ANDROID_LIBRARY_IMPLICIT_EXPORTS = [
+]
diff --git a/rules/acls/android_library_resources_without_srcs.bzl b/rules/acls/android_library_resources_without_srcs.bzl
new file mode 100644
index 0000000..b376e30
--- /dev/null
+++ b/rules/acls/android_library_resources_without_srcs.bzl
@@ -0,0 +1,19 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for b/144163743, allowing implicit export of deps when resources and deps are present."""
+
+ANDROID_LIBRARY_RESOURCES_WITHOUT_SRCS_GENERATOR_FUNCTIONS = []
+
+ANDROID_LIBRARY_RESOURCES_WITHOUT_SRCS = ["//:__subpackages__"]
diff --git a/rules/acls/android_library_starlark_resources.bzl b/rules/acls/android_library_starlark_resources.bzl
new file mode 100644
index 0000000..46e68a5
--- /dev/null
+++ b/rules/acls/android_library_starlark_resources.bzl
@@ -0,0 +1,23 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for diff test for android_library native resource processing vs Starlark processed resources."""
+
+# keep sorted
+ANDROID_LIBRARY_STARLARK_RESOURCES_ROLLOUT = [
+    "//:__subpackages__",
+]
+
+ANDROID_LIBRARY_STARLARK_RESOURCES_FALLBACK = [
+]
diff --git a/rules/acls/android_lint_rollout.bzl b/rules/acls/android_lint_rollout.bzl
new file mode 100644
index 0000000..65f9ff7
--- /dev/null
+++ b/rules/acls/android_lint_rollout.bzl
@@ -0,0 +1,19 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for Android Lint in the Android Rules."""
+
+# keep sorted
+ANDROID_LINT_ROLLOUT = [
+]
diff --git a/rules/acls/android_test_lockdown.bzl b/rules/acls/android_test_lockdown.bzl
new file mode 100644
index 0000000..8dce844
--- /dev/null
+++ b/rules/acls/android_test_lockdown.bzl
@@ -0,0 +1,21 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allowlist of macro and targets that are allowed to use android_test."""
+
+ANDROID_TEST_LOCKDOWN_GENERATOR_FUNCTIONS = [
+]
+
+ANDROID_TEST_LOCKDOWN_TARGETS = [
+]
diff --git a/rules/acls/android_test_platform_rollout.bzl b/rules/acls/android_test_platform_rollout.bzl
new file mode 100644
index 0000000..47b879e
--- /dev/null
+++ b/rules/acls/android_test_platform_rollout.bzl
@@ -0,0 +1,26 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow and fallback lists for Android Test Platform rollout"""
+
+# Targets for Android Test Platform Rollout
+ANDROID_TEST_PLATFORM_ROLLOUT = [
+    "//:__subpackages__",
+]
+
+_READY_TO_ROLLOUT_IN_NEXT_RELEASE = [
+]
+
+ANDROID_TEST_PLATFORM_FALLBACK = [
+] + _READY_TO_ROLLOUT_IN_NEXT_RELEASE
diff --git a/rules/acls/android_test_starlark_resources.bzl b/rules/acls/android_test_starlark_resources.bzl
new file mode 100644
index 0000000..2510931
--- /dev/null
+++ b/rules/acls/android_test_starlark_resources.bzl
@@ -0,0 +1,17 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for diff test for android_test native vs Starlark processed resources."""
+
+ANDROID_TEST_STARLARK_RESOURCES = []
diff --git a/rules/acls/b122039567.bzl b/rules/acls/b122039567.bzl
new file mode 100644
index 0000000..907b08e
--- /dev/null
+++ b/rules/acls/b122039567.bzl
@@ -0,0 +1,18 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for b/122039567."""
+
+B122039567 = [
+]
diff --git a/rules/acls/b123854163.bzl b/rules/acls/b123854163.bzl
new file mode 100644
index 0000000..d23efb5
--- /dev/null
+++ b/rules/acls/b123854163.bzl
@@ -0,0 +1,18 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for b/123854163."""
+
+B123854163 = [
+]
diff --git a/rules/acls/dex2oat_opts.bzl b/rules/acls/dex2oat_opts.bzl
new file mode 100644
index 0000000..b935a1f
--- /dev/null
+++ b/rules/acls/dex2oat_opts.bzl
@@ -0,0 +1,19 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Packages in this list are allowed to specify custom dex2oat options."""
+
+# keep sorted
+CAN_USE_DEX2OAT_OPTIONS = [
+]
diff --git a/rules/acls/fix_application_id.bzl b/rules/acls/fix_application_id.bzl
new file mode 100644
index 0000000..41c18b7
--- /dev/null
+++ b/rules/acls/fix_application_id.bzl
@@ -0,0 +1,27 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allowlist for fixing the implicit application ID in manifest processing.
+
+See b/111923269 for context.
+"""
+
+# keep sorted
+FIX_APPLICATION_ID_ROLLOUT = [
+    "//:__subpackages__",
+]
+
+# keep sorted
+FIX_APPLICATION_ID_FALLBACK = [
+]
diff --git a/rules/acls/fix_export_exporting_rollout.bzl b/rules/acls/fix_export_exporting_rollout.bzl
new file mode 100644
index 0000000..cb68adf
--- /dev/null
+++ b/rules/acls/fix_export_exporting_rollout.bzl
@@ -0,0 +1,24 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allowlist for making exports actually be exported."""
+
+# keep sorted
+FIX_EXPORT_EXPORTING_ROLLOUT = [
+    "//:__subpackages__",
+]
+
+# keep sorted
+FIX_EXPORT_EXPORTING_FALLBACK = [
+]
diff --git a/rules/acls/fix_resource_transitivity_rollout.bzl b/rules/acls/fix_resource_transitivity_rollout.bzl
new file mode 100644
index 0000000..bdde15f
--- /dev/null
+++ b/rules/acls/fix_resource_transitivity_rollout.bzl
@@ -0,0 +1,22 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allowlist for fixing resource dependencies passing through rules with no manifest."""
+
+# keep sorted
+FIX_RESOURCE_TRANSITIVITY_ROLLOUT = [
+    "//:__subpackages__",
+]
+
+FIX_RESOURCE_TRANSITIVITY_FALLBACK = []
diff --git a/rules/acls/host_dex2oat_rollout.bzl b/rules/acls/host_dex2oat_rollout.bzl
new file mode 100644
index 0000000..b3da4ee
--- /dev/null
+++ b/rules/acls/host_dex2oat_rollout.bzl
@@ -0,0 +1,27 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Whitelist for using host dex2oat with android_instrumentation_test."""
+
+ANDROID_TEST_HOST_DEX2OAT_ROLLOUT = [
+    "//...",
+]
+
+# keep sorted
+AIT_USE_HOST_DEX2OAT_ROLLOUT = [
+    "//:__subpackages__",
+]
+
+AIT_USE_HOST_DEX2OAT_ROLLOUT_FALLBACK = [
+]
diff --git a/rules/acls/install_apps_in_data.bzl b/rules/acls/install_apps_in_data.bzl
new file mode 100644
index 0000000..58994bf
--- /dev/null
+++ b/rules/acls/install_apps_in_data.bzl
@@ -0,0 +1,18 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Whitelist for using installing apps in data attr in android_instrumentation_test."""
+
+INSTALL_APPS_IN_DATA = [
+]
diff --git a/rules/acls/kt_android_library_rollout.bzl b/rules/acls/kt_android_library_rollout.bzl
new file mode 100644
index 0000000..50c43a4
--- /dev/null
+++ b/rules/acls/kt_android_library_rollout.bzl
@@ -0,0 +1,24 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list to rollout the kt_android_library rule from rules_android."""
+
+# keep sorted
+KT_ANDROID_LIBRARY_ROLLOUT = [
+    "//:__subpackages__",
+]
+
+# keep sorted
+KT_ANDROID_LIBRARY_FALLBACK = [
+]
diff --git a/rules/acls/library_rollout.bzl b/rules/acls/library_rollout.bzl
new file mode 100644
index 0000000..cb42a88
--- /dev/null
+++ b/rules/acls/library_rollout.bzl
@@ -0,0 +1,23 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for Starlark android_library rollout"""
+
+LIBRARY_ROLLOUT = [
+    # keep sorted
+    "//:__subpackages__",
+]
+
+LIBRARY_FALLBACK = [
+]
diff --git a/rules/acls/library_rollout_override.bzl b/rules/acls/library_rollout_override.bzl
new file mode 100644
index 0000000..805bf0f
--- /dev/null
+++ b/rules/acls/library_rollout_override.bzl
@@ -0,0 +1,17 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""A Starlark android_library rollout override switch, for testing."""
+
+LIBRARY_ROLLOUT_OVERRIDE = None  # A tristate: None, True or False.
diff --git a/rules/acls/local_test_multi_proto.bzl b/rules/acls/local_test_multi_proto.bzl
new file mode 100644
index 0000000..e0bc06b
--- /dev/null
+++ b/rules/acls/local_test_multi_proto.bzl
@@ -0,0 +1,23 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allowlist for android_local_test targets allowed to depend on java_proto_library.
+
+See b/120162253 for context.
+"""
+
+LOCAL_TEST_MULTI_PROTO = [
+]
+
+LOCAL_TEST_MULTI_PROTO_PKG = [x + ":__pkg__" for x in LOCAL_TEST_MULTI_PROTO]
diff --git a/rules/acls/local_test_rollout.bzl b/rules/acls/local_test_rollout.bzl
new file mode 100644
index 0000000..889d82c
--- /dev/null
+++ b/rules/acls/local_test_rollout.bzl
@@ -0,0 +1,22 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow and fallback lists for Starlark android_local_test rollout"""
+
+LOCAL_TEST_ROLLOUT = [
+    "//:__subpackages__",
+]
+
+LOCAL_TEST_FALLBACK = [
+]
diff --git a/rules/acls/local_test_starlark_resources.bzl b/rules/acls/local_test_starlark_resources.bzl
new file mode 100644
index 0000000..19c1777
--- /dev/null
+++ b/rules/acls/local_test_starlark_resources.bzl
@@ -0,0 +1,22 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for android_local_test Starlark processed resources."""
+
+LOCAL_TEST_STARLARK_RESOURCES_ROLLOUT = [
+]
+
+LOCAL_TEST_STARLARK_RESOURCES_FALLBACK = [
+    "//:__subpackages__",
+]
diff --git a/rules/acls/nitrogen_test_runner_rollout.bzl b/rules/acls/nitrogen_test_runner_rollout.bzl
new file mode 100644
index 0000000..891671e
--- /dev/null
+++ b/rules/acls/nitrogen_test_runner_rollout.bzl
@@ -0,0 +1,28 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow and fallback lists for Nitrogen rollout"""
+
+# Nitrogen targets for android_instrumentation_test rollout
+NITROGEN_TEST_RUNNER_ROLLOUT = [
+    "//:__subpackages__",
+]
+
+# Nitrogen targets for android_test rollout
+NITROGEN_AT_TEST_RUNNER_ROLLOUT = [
+    "//:__subpackages__",
+]
+
+NITROGEN_TEST_RUNNER_FALLBACK = [
+]
diff --git a/rules/acls/partial_jetification_targets.bzl b/rules/acls/partial_jetification_targets.bzl
new file mode 100644
index 0000000..490c3ea
--- /dev/null
+++ b/rules/acls/partial_jetification_targets.bzl
@@ -0,0 +1,20 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for targets or subsets of targets to partially jetify at build time"""
+
+PARTIAL_JETIFICATION_TARGETS_ROLLOUT = [
+]
+
+PARTIAL_JETIFICATION_TARGETS_FALLBACK = []
diff --git a/rules/acls/sourceless_binary_rollout.bzl b/rules/acls/sourceless_binary_rollout.bzl
new file mode 100644
index 0000000..132ba10
--- /dev/null
+++ b/rules/acls/sourceless_binary_rollout.bzl
@@ -0,0 +1,21 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for sourceless android_binary rollout"""
+
+SOURCELESS_BINARY_ROLLOUT = [
+]
+
+SOURCELESS_BINARY_FALLBACK = [
+]
diff --git a/rules/acls/starlark_resources_diff.bzl b/rules/acls/starlark_resources_diff.bzl
new file mode 100644
index 0000000..ed7752e
--- /dev/null
+++ b/rules/acls/starlark_resources_diff.bzl
@@ -0,0 +1,18 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for diff test for native vs Starlark resource processing pipelines."""
+
+STARLARK_RESOURCES_DIFF = [
+]
diff --git a/rules/acls/test_to_instrument_test_rollout.bzl b/rules/acls/test_to_instrument_test_rollout.bzl
new file mode 100644
index 0000000..835880d
--- /dev/null
+++ b/rules/acls/test_to_instrument_test_rollout.bzl
@@ -0,0 +1,21 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Allow list for android_test to android_instrumentation_test rollout"""
+
+TEST_TO_INSTRUMENT_TEST_ROLLOUT = [
+]
+
+TEST_TO_INSTRUMENT_TEST_FALLBACK = [
+]
diff --git a/rules/android_binary.bzl b/rules/android_binary.bzl
new file mode 100644
index 0000000..1760e75
--- /dev/null
+++ b/rules/android_binary.bzl
@@ -0,0 +1,42 @@
+# Copyright 2019 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel rule for building an APK."""
+
+load(":migration_tag_DONOTUSE.bzl", "add_migration_tag")
+load("@rules_android//rules/android_packaged_resources:rule.bzl", "android_packaged_resources_macro")
+
+def android_binary(**attrs):
+    """Bazel android_binary rule.
+
+    https://docs.bazel.build/versions/master/be/android.html#android_binary
+
+    Args:
+      **attrs: Rule attributes
+    """
+    packaged_resources_name = ":%s_RESOURCES_DO_NOT_USE" % attrs["name"]
+    android_packaged_resources_macro(
+        **dict(
+            attrs,
+            name = packaged_resources_name[1:],
+            visibility = ["//visibility:private"],
+        )
+    )
+
+    attrs.pop("$enable_manifest_merging", None)
+
+    native.android_binary(
+        application_resources = packaged_resources_name,
+        **add_migration_tag(attrs)
+    )
diff --git a/rules/android_library/BUILD b/rules/android_library/BUILD
new file mode 100644
index 0000000..09ca5b8
--- /dev/null
+++ b/rules/android_library/BUILD
@@ -0,0 +1,21 @@
+# The android_library rule.
+
+load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
+
+licenses(["notice"])
+
+exports_files(["rule.bzl"])
+
+filegroup(
+    name = "all_files",
+    srcs = glob(["**"]),
+)
+
+bzl_library(
+    name = "bzl",
+    srcs = glob(["*.bzl"]),
+    deps = [
+        "@rules_android//rules:common_bzl",
+        "@rules_android//rules/flags:bzl",
+    ],
+)
diff --git a/rules/android_library/attrs.bzl b/rules/android_library/attrs.bzl
new file mode 100644
index 0000000..16a18e7
--- /dev/null
+++ b/rules/android_library/attrs.bzl
@@ -0,0 +1,73 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Attributes."""
+
+load(
+    "@rules_android//rules:attrs.bzl",
+    _attrs = "attrs",
+)
+
+ATTRS = _attrs.add(
+    dict(
+        deps = attr.label_list(
+            providers = [
+                [CcInfo],
+                [JavaInfo],
+            ],
+        ),
+        enable_data_binding = attr.bool(default = False),
+        exported_plugins = attr.label_list(
+            allow_rules = [
+                "java_plugin",
+            ],
+            cfg = "host",
+        ),
+        exports = attr.label_list(
+            providers = [
+                [CcInfo],
+                [JavaInfo],
+            ],
+        ),
+        exports_manifest =
+            _attrs.tristate.create(default = _attrs.tristate.no),
+        idl_import_root = attr.string(),
+        idl_parcelables = attr.label_list(allow_files = [".aidl"]),
+        idl_preprocessed = attr.label_list(allow_files = [".aidl"]),
+        idl_srcs = attr.label_list(allow_files = [".aidl"]),
+        neverlink = attr.bool(default = False),
+        proguard_specs = attr.label_list(allow_files = True),
+        srcs = attr.label_list(
+            allow_files = [".java", ".srcjar"],
+        ),
+        # TODO(b/127517031): Remove these entries once fixed.
+        _defined_assets = attr.bool(default = False),
+        _defined_assets_dir = attr.bool(default = False),
+        _defined_idl_import_root = attr.bool(default = False),
+        _defined_idl_parcelables = attr.bool(default = False),
+        _defined_idl_srcs = attr.bool(default = False),
+        _defined_local_resources = attr.bool(default = False),
+        _java_toolchain = attr.label(
+            cfg = "host",
+            default = Label("//tools/jdk:toolchain_android_only"),
+        ),
+        # TODO(str): Remove when fully migrated to android_instrumentation_test
+        _android_test_migration = attr.bool(default = False),
+        _flags = attr.label(
+            default = "@rules_android//rules/flags",
+        ),
+    ),
+    _attrs.COMPILATION,
+    _attrs.DATA_CONTEXT,
+)
diff --git a/rules/android_library/impl.bzl b/rules/android_library/impl.bzl
new file mode 100644
index 0000000..232899c
--- /dev/null
+++ b/rules/android_library/impl.bzl
@@ -0,0 +1,534 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Implementation."""
+
+load("@rules_android//rules:acls.bzl", "acls")
+load("@rules_android//rules:attrs.bzl", _attrs = "attrs")
+load("@rules_android//rules:common.bzl", _common = "common")
+load("@rules_android//rules:data_binding.bzl", _data_binding = "data_binding")
+load("@rules_android//rules:idl.bzl", _idl = "idl")
+load("@rules_android//rules:intellij.bzl", _intellij = "intellij")
+load("@rules_android//rules:java.bzl", _java = "java")
+load(
+    "@rules_android//rules:processing_pipeline.bzl",
+    "ProviderInfo",
+    "processing_pipeline",
+)
+load("@rules_android//rules:proguard.bzl", _proguard = "proguard")
+load("@rules_android//rules:resources.bzl", _resources = "resources")
+load("@rules_android//rules:utils.bzl", "get_android_sdk", "get_android_toolchain", "log", "utils")
+load("@rules_android//rules/flags:flags.bzl", _flags = "flags")
+
+_USES_DEPRECATED_IMPLICIT_EXPORT_ERROR = (
+    "The android_library rule will be deprecating the use of deps to export " +
+    "targets implicitly. " +
+    "Please use android_library.exports to explicitly specify the exported " +
+    "targets of %s."
+)
+
+_SRCS_CONTAIN_RESOURCE_LABEL_ERROR = (
+    "The srcs attribute of an android_library rule should not contain label " +
+    "with resources %s"
+)
+
+_IDL_IMPORT_ROOT_SET_WITHOUT_SRCS_OR_PARCELABLES_ERROR = (
+    "The 'idl_import_root' attribute of the android_library rule was set, " +
+    "but neither 'idl_srcs' nor 'idl_parcelables' were specified."
+)
+
+_IDL_SRC_FROM_DIFFERENT_PACKAGE_ERROR = (
+    "Do not import '%s' directly. You should either move the file to this " +
+    "package or depend on an appropriate rule there."
+)
+
+# Android library AAR context attributes.
+_PROVIDERS = "providers"
+_VALIDATION_OUTPUTS = "validation_outputs"
+
+_AARContextInfo = provider(
+    "Android library AAR context object",
+    fields = {
+        _PROVIDERS: "The list of all providers to propagate.",
+        _VALIDATION_OUTPUTS: "List of outputs given to OutputGroupInfo _validation group",
+    },
+)
+
+def _uses_deprecated_implicit_export(ctx):
+    if not ctx.attr.deps:
+        return False
+    return not (ctx.files.srcs or
+                ctx.files.idl_srcs or
+                ctx.attr._defined_assets or
+                ctx.files.resource_files or
+                ctx.attr.manifest)
+
+def _uses_resources_and_deps_without_srcs(ctx):
+    if not ctx.attr.deps:
+        return False
+    if not (ctx.attr._defined_assets or
+            ctx.files.resource_files or
+            ctx.attr.manifest):
+        return False
+    return not (ctx.files.srcs or ctx.files.idl_srcs)
+
+def _check_deps_without_java_srcs(ctx):
+    if not ctx.attr.deps or ctx.files.srcs or ctx.files.idl_srcs:
+        return False
+    gfn = getattr(ctx.attr, "generator_function", "")
+    if _uses_deprecated_implicit_export(ctx):
+        if (acls.in_android_library_implicit_exports_generator_functions(gfn) or
+            acls.in_android_library_implicit_exports(str(ctx.label))):
+            return True
+        else:
+            # TODO(b/144163743): add a test for this.
+            log.error(_USES_DEPRECATED_IMPLICIT_EXPORT_ERROR % ctx.label)
+    if _uses_resources_and_deps_without_srcs(ctx):
+        if (acls.in_android_library_resources_without_srcs_generator_functions(gfn) or
+            acls.in_android_library_resources_without_srcs(str(ctx.label))):
+            return True
+    return False
+
+def _validate_rule_context(ctx):
+    # Verify that idl_import_root is specified with idl_src or idl_parcelables.
+    if (ctx.attr._defined_idl_import_root and
+        not (ctx.attr._defined_idl_srcs or ctx.attr._defined_idl_parcelables)):
+        log.error(_IDL_IMPORT_ROOT_SET_WITHOUT_SRCS_OR_PARCELABLES_ERROR)
+
+    # Verify that idl_srcs are not from another package.
+    for idl_src in ctx.attr.idl_srcs:
+        if ctx.label.package != idl_src.label.package:
+            log.error(_IDL_SRC_FROM_DIFFERENT_PACKAGE_ERROR % idl_src.label)
+
+    return struct(
+        enable_deps_without_srcs = _check_deps_without_java_srcs(ctx),
+    )
+
+def _exceptions_processor(ctx, **unused_ctxs):
+    return ProviderInfo(
+        name = "exceptions_ctx",
+        value = _validate_rule_context(ctx),
+    )
+
+def _process_resources(ctx, java_package, **unused_ctxs):
+    # exports_manifest can be overridden by a bazel flag.
+    if ctx.attr.exports_manifest == _attrs.tristate.auto:
+        exports_manifest = ctx.fragments.android.get_exports_manifest_default
+    else:
+        exports_manifest = ctx.attr.exports_manifest == _attrs.tristate.yes
+
+    # Process Android Resources
+    resources_ctx = _resources.process(
+        ctx,
+        manifest = ctx.file.manifest,
+        resource_files = ctx.attr.resource_files,
+        defined_assets = ctx.attr._defined_assets,
+        assets = ctx.attr.assets,
+        defined_assets_dir = ctx.attr._defined_assets_dir,
+        assets_dir = ctx.attr.assets_dir,
+        exports_manifest = exports_manifest,
+        java_package = java_package,
+        custom_package = ctx.attr.custom_package,
+        neverlink = ctx.attr.neverlink,
+        enable_data_binding = ctx.attr.enable_data_binding,
+        deps = ctx.attr.deps,
+        exports = ctx.attr.exports,
+
+        # Processing behavior changing flags.
+        enable_res_v3 = _flags.get(ctx).android_enable_res_v3,
+        # TODO(b/144163743): remove fix_resource_transitivity, which was only added to emulate
+        # misbehavior on the Java side.
+        fix_resource_transitivity = bool(ctx.attr.srcs),
+        fix_export_exporting = acls.in_fix_export_exporting_rollout(str(ctx.label)),
+        android_test_migration = ctx.attr._android_test_migration,
+
+        # Tool and Processing related inputs
+        aapt = get_android_toolchain(ctx).aapt2.files_to_run,
+        android_jar = get_android_sdk(ctx).android_jar,
+        android_kit = get_android_toolchain(ctx).android_kit.files_to_run,
+        busybox = get_android_toolchain(ctx).android_resources_busybox.files_to_run,
+        java_toolchain = _common.get_java_toolchain(ctx),
+        host_javabase = _common.get_host_javabase(ctx),
+        instrument_xslt = utils.only(get_android_toolchain(ctx).add_g3itr_xslt.files.to_list()),
+        res_v3_dummy_manifest = utils.only(
+            get_android_toolchain(ctx).res_v3_dummy_manifest.files.to_list(),
+        ),
+        res_v3_dummy_r_txt = utils.only(
+            get_android_toolchain(ctx).res_v3_dummy_r_txt.files.to_list(),
+        ),
+        xsltproc = get_android_toolchain(ctx).xsltproc_tool.files_to_run,
+        zip_tool = get_android_toolchain(ctx).zip_tool.files_to_run,
+    )
+
+    # TODO(b/139305816): Remove the ability for android_library to be added in
+    # the srcs attribute of another android_library.
+    if resources_ctx.defines_resources:
+        # Verify that srcs do no contain labels.
+        for src in ctx.attr.srcs:
+            if AndroidResourcesInfo in src:
+                log.error(_SRCS_CONTAIN_RESOURCE_LABEL_ERROR %
+                          src[AndroidResourcesInfo].label)
+
+    return ProviderInfo(
+        name = "resources_ctx",
+        value = resources_ctx,
+    )
+
+def _process_idl(ctx, **unused_sub_ctxs):
+    return ProviderInfo(
+        name = "idl_ctx",
+        value = _idl.process(
+            ctx,
+            idl_srcs = ctx.files.idl_srcs,
+            idl_parcelables = ctx.files.idl_parcelables,
+            idl_import_root =
+                ctx.attr.idl_import_root if ctx.attr._defined_idl_import_root else None,
+            idl_preprocessed = ctx.files.idl_preprocessed,
+            deps = utils.collect_providers(AndroidIdlInfo, ctx.attr.deps),
+            exports = utils.collect_providers(AndroidIdlInfo, ctx.attr.exports),
+            aidl = get_android_sdk(ctx).aidl,
+            aidl_lib = get_android_sdk(ctx).aidl_lib,
+            aidl_framework = get_android_sdk(ctx).framework_aidl,
+        ),
+    )
+
+def _process_data_binding(ctx, java_package, resources_ctx, **unused_sub_ctxs):
+    return ProviderInfo(
+        name = "db_ctx",
+        value = _data_binding.process(
+            ctx,
+            defines_resources = resources_ctx.defines_resources,
+            enable_data_binding = ctx.attr.enable_data_binding,
+            java_package = java_package,
+            deps = utils.collect_providers(DataBindingV2Info, ctx.attr.deps),
+            exports = utils.collect_providers(DataBindingV2Info, ctx.attr.exports),
+            data_binding_exec = get_android_toolchain(ctx).data_binding_exec.files_to_run,
+            data_binding_annotation_processor =
+                get_android_toolchain(ctx).data_binding_annotation_processor[JavaInfo],
+            data_binding_annotation_template =
+                utils.only(get_android_toolchain(ctx).data_binding_annotation_template.files.to_list()),
+        ),
+    )
+
+def _process_proguard(ctx, idl_ctx, **unused_sub_ctxs):
+    return ProviderInfo(
+        name = "proguard_ctx",
+        value = _proguard.process(
+            ctx,
+            proguard_configs = ctx.files.proguard_specs,
+            proguard_spec_providers = utils.collect_providers(
+                ProguardSpecProvider,
+                ctx.attr.deps,
+                ctx.attr.exports,
+                ctx.attr.plugins,
+                ctx.attr.exported_plugins,
+                idl_ctx.idl_deps,
+            ),
+            proguard_allowlister =
+                get_android_toolchain(ctx).proguard_allowlister.files_to_run,
+        ),
+    )
+
+def _process_jvm(ctx, exceptions_ctx, resources_ctx, idl_ctx, db_ctx, **unused_sub_ctxs):
+    java_info = _java.compile_android(
+        ctx,
+        ctx.outputs.lib_jar,
+        ctx.outputs.lib_src_jar,
+        srcs = ctx.files.srcs + idl_ctx.idl_java_srcs + db_ctx.java_srcs,
+        javac_opts = ctx.attr.javacopts + db_ctx.javac_opts,
+        r_java = resources_ctx.r_java,
+        deps =
+            utils.collect_providers(JavaInfo, ctx.attr.deps, idl_ctx.idl_deps),
+        exports = utils.collect_providers(JavaInfo, ctx.attr.exports),
+        plugins = (
+            utils.collect_providers(JavaInfo, ctx.attr.plugins) +
+            db_ctx.java_plugins
+        ),
+        exported_plugins = utils.collect_providers(
+            JavaInfo,
+            ctx.attr.exported_plugins,
+        ),
+        annotation_processor_additional_outputs = (
+            db_ctx.java_annotation_processor_additional_outputs
+        ),
+        annotation_processor_additional_inputs = (
+            db_ctx.java_annotation_processor_additional_inputs
+        ),
+        enable_deps_without_srcs = exceptions_ctx.enable_deps_without_srcs,
+        neverlink = ctx.attr.neverlink,
+        strict_deps = "DEFAULT",
+        java_toolchain = _common.get_java_toolchain(ctx),
+    )
+
+    return ProviderInfo(
+        name = "jvm_ctx",
+        value = struct(
+            java_info = java_info,
+            providers = [java_info],
+        ),
+    )
+
+def _process_aar(ctx, java_package, resources_ctx, proguard_ctx, **unused_ctx):
+    aar_ctx = {
+        _PROVIDERS: [],
+        _VALIDATION_OUTPUTS: [],
+    }
+
+    starlark_aar = _resources.make_aar(
+        ctx,
+        manifest = resources_ctx.starlark_processed_manifest,
+        assets = ctx.files.assets,
+        assets_dir = ctx.attr.assets_dir,
+        resource_files = resources_ctx.starlark_processed_resources if not ctx.attr.neverlink else [],
+        class_jar = ctx.outputs.lib_jar,
+        r_txt = resources_ctx.starlark_r_txt,
+        proguard_specs = proguard_ctx.proguard_configs,
+        busybox = get_android_toolchain(ctx).android_resources_busybox.files_to_run,
+        host_javabase = _common.get_host_javabase(ctx),
+    )
+
+    # TODO(b/170409221): Clean this up once Starlark migration is complete. Create and propagate
+    # a native aar info provider with the Starlark artifacts to avoid breaking downstream
+    # targets.
+    if not ctx.attr.neverlink:
+        aar_ctx[_PROVIDERS].append(AndroidLibraryAarInfo(
+            aar = starlark_aar,
+            manifest = resources_ctx.starlark_processed_manifest,
+            aars_from_deps = utils.collect_providers(
+                AndroidLibraryAarInfo,
+                ctx.attr.deps,
+                ctx.attr.exports,
+            ),
+            defines_local_resources = resources_ctx.defines_resources,
+        ))
+
+    return ProviderInfo(
+        name = "aar_ctx",
+        value = _AARContextInfo(**aar_ctx),
+    )
+
+def _process_native(ctx, idl_ctx, **unused_ctx):
+    return ProviderInfo(
+        name = "native_ctx",
+        value = struct(
+            providers = [
+                AndroidNativeLibsInfo(
+                    depset(
+                        transitive = [
+                            p.native_libs
+                            for p in utils.collect_providers(
+                                AndroidNativeLibsInfo,
+                                ctx.attr.deps,
+                                ctx.attr.exports,
+                            )
+                        ],
+                        order = "preorder",
+                    ),
+                ),
+                AndroidCcLinkParamsInfo(
+                    cc_common.merge_cc_infos(
+                        cc_infos = [
+                                       info.cc_info
+                                       for info in utils.collect_providers(
+                                           JavaCcLinkParamsInfo,
+                                           ctx.attr.deps,
+                                           ctx.attr.exports,
+                                           idl_ctx.idl_deps,
+                                       )
+                                   ] +
+                                   [
+                                       info.link_params
+                                       for info in utils.collect_providers(
+                                           AndroidCcLinkParamsInfo,
+                                           ctx.attr.deps,
+                                           ctx.attr.exports,
+                                           idl_ctx.idl_deps,
+                                       )
+                                   ] +
+                                   utils.collect_providers(
+                                       CcInfo,
+                                       ctx.attr.deps,
+                                       ctx.attr.exports,
+                                       idl_ctx.idl_deps,
+                                   ),
+                    ),
+                ),
+            ],
+        ),
+    )
+
+def _process_intellij(ctx, java_package, resources_ctx, idl_ctx, jvm_ctx, **unused_sub_ctxs):
+    android_ide_info = _intellij.make_android_ide_info(
+        ctx,
+        java_package = java_package,
+        manifest = ctx.file.manifest,
+        defines_resources = resources_ctx.defines_resources,
+        merged_manifest = resources_ctx.merged_manifest,
+        resources_apk = resources_ctx.resources_apk,
+        r_jar = utils.only(resources_ctx.r_java.outputs.jars) if resources_ctx.r_java else None,
+        idl_import_root = idl_ctx.idl_import_root,
+        idl_srcs = idl_ctx.idl_srcs,
+        idl_java_srcs = idl_ctx.idl_java_srcs,
+        java_info = jvm_ctx.java_info,
+        signed_apk = None,  # signed_apk, always empty for android_library.
+        aar = getattr(ctx.outputs, "aar", None),  # Deprecate aar for android_library.
+        apks_under_test = [],  # apks_under_test, always empty for android_library
+        native_libs = dict(),  # nativelibs, always empty for android_library
+        idlclass = get_android_toolchain(ctx).idlclass.files_to_run,
+        host_javabase = _common.get_host_javabase(ctx),
+    )
+    return ProviderInfo(
+        name = "intellij_ctx",
+        value = struct(
+            android_ide_info = android_ide_info,
+            providers = [android_ide_info],
+        ),
+    )
+
+def _process_coverage(ctx, **unused_ctx):
+    return ProviderInfo(
+        name = "coverage_ctx",
+        value = struct(
+            providers = [
+                coverage_common.instrumented_files_info(
+                    ctx,
+                    dependency_attributes = ["assets", "deps", "exports"],
+                ),
+            ],
+        ),
+    )
+
+# Order dependent, as providers will not be available to downstream processors
+# that may depend on the provider. Iteration order for a dictionary is based on
+# insertion.
+PROCESSORS = dict(
+    ExceptionsProcessor = _exceptions_processor,
+    ResourceProcessor = _process_resources,
+    IdlProcessor = _process_idl,
+    DataBindingProcessor = _process_data_binding,
+    JvmProcessor = _process_jvm,
+    ProguardProcessor = _process_proguard,
+    AarProcessor = _process_aar,
+    NativeProcessor = _process_native,
+    IntelliJProcessor = _process_intellij,
+    CoverageProcessor = _process_coverage,
+)
+
+# TODO(b/119560471): Deprecate the usage of legacy providers.
+def _make_legacy_provider(intellij_ctx, jvm_ctx, providers):
+    return struct(
+        android = _intellij.make_legacy_android_provider(intellij_ctx.android_ide_info),
+        java = struct(
+            annotation_processing = jvm_ctx.java_info.annotation_processing,
+            compilation_info = jvm_ctx.java_info.compilation_info,
+            outputs = jvm_ctx.java_info.outputs,
+            source_jars = depset(jvm_ctx.java_info.source_jars),
+            transitive_deps = jvm_ctx.java_info.transitive_compile_time_jars,
+            transitive_exports = jvm_ctx.java_info.transitive_exports,
+            transitive_runtime_deps = jvm_ctx.java_info.transitive_runtime_jars,
+            transitive_source_jars = jvm_ctx.java_info.transitive_source_jars,
+        ),
+        providers = providers,
+    )
+
+def finalize(
+        ctx,
+        resources_ctx,
+        intellij_ctx,
+        jvm_ctx,
+        proguard_ctx,
+        providers,
+        validation_outputs,
+        **unused_ctxs):
+    """Creates the DefaultInfo and OutputGroupInfo providers.
+
+    Args:
+      ctx: The context.
+      resources_ctx: ProviderInfo. The resources ctx.
+      intellij_ctx: ProviderInfo. The intellij ctx.
+      jvm_ctx: ProviderInfo. The jvm ctx.
+      proguard_ctx: ProviderInfo. The proguard ctx.
+      providers: sequence of providers. The providers to propagate.
+      validation_outputs: sequence of Files. The validation outputs.
+      **unused_ctxs: Unused ProviderInfo.
+
+    Returns:
+      A struct with Android and Java legacy providers and a list of providers.
+    """
+    transitive_runfiles = []
+    if not ctx.attr.neverlink:
+        for p in utils.collect_providers(
+            DefaultInfo,
+            ctx.attr.deps,
+            ctx.attr.exports,
+        ):
+            transitive_runfiles.append(p.data_runfiles.files)
+            transitive_runfiles.append(p.default_runfiles.files)
+    runfiles = ctx.runfiles(
+        files = (
+            (resources_ctx.r_java.runtime_output_jars if resources_ctx.r_java and not ctx.attr.neverlink else []) +
+            ([ctx.outputs.lib_jar] if (ctx.attr.srcs or ctx.attr.idl_srcs) and not ctx.attr.neverlink else [])
+        ),
+        transitive_files = depset(transitive = transitive_runfiles),
+        collect_default = True,
+    )
+    files = [ctx.outputs.lib_jar]
+    if getattr(ctx.outputs, "resources_src_jar", None):
+        files.append(ctx.outputs.resources_src_jar)
+    if getattr(ctx.outputs, "resources_jar", None):
+        files.append(ctx.outputs.resources_jar)
+
+    providers.extend([
+        DefaultInfo(
+            files = depset(files),
+            runfiles = runfiles,
+        ),
+        OutputGroupInfo(
+            compilation_outputs = depset([ctx.outputs.lib_jar]),
+            _source_jars = depset(
+                [ctx.outputs.lib_src_jar],
+                transitive = [jvm_ctx.java_info.transitive_source_jars],
+            ),
+            _hidden_top_level_INTERNAL_ = depset(
+                resources_ctx.validation_results,
+                transitive = [
+                    info._hidden_top_level_INTERNAL_
+                    for info in utils.collect_providers(
+                        OutputGroupInfo,
+                        ctx.attr.deps,
+                        ctx.attr.exports,
+                    )
+                ] + [proguard_ctx.transitive_proguard_configs],
+            ),
+            _validation = depset(validation_outputs),
+        ),
+    ])
+    return _make_legacy_provider(intellij_ctx, jvm_ctx, providers)
+
+_PROCESSING_PIPELINE = processing_pipeline.make_processing_pipeline(
+    processors = PROCESSORS,
+    finalize = finalize,
+)
+
+def impl(ctx):
+    """The rule implementation.
+
+    Args:
+      ctx: The context.
+
+    Returns:
+      A legacy struct provider.
+    """
+    java_package = _java.resolve_package_from_label(ctx.label, ctx.attr.custom_package)
+    return processing_pipeline.run(ctx, java_package, _PROCESSING_PIPELINE)
diff --git a/rules/android_library/rule.bzl b/rules/android_library/rule.bzl
new file mode 100644
index 0000000..f267b37
--- /dev/null
+++ b/rules/android_library/rule.bzl
@@ -0,0 +1,135 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""android_library rule."""
+
+load(":attrs.bzl", _ATTRS = "ATTRS")
+load(":impl.bzl", _impl = "impl")
+load(
+    "@rules_android//rules:attrs.bzl",
+    _attrs = "attrs",
+)
+
+def _outputs(_defined_local_resources):
+    outputs = dict(
+        lib_jar = "lib%{name}.jar",
+        lib_src_jar = "lib%{name}-src.jar",
+        aar = "%{name}.aar",
+    )
+
+    if _defined_local_resources:
+        # TODO(b/177261846): resource-related predeclared outputs need to be re-pointed at the
+        # corresponding artifacts in the Starlark pipeline.
+        outputs.update(
+            dict(
+                resources_src_jar = "_migrated/%{name}.srcjar",
+                resources_txt = "_migrated/%{name}_symbols/R.txt",
+                resources_jar = "_migrated/%{name}_resources.jar",
+            ),
+        )
+
+    return outputs
+
+def make_rule(
+        attrs = _ATTRS,
+        implementation = _impl,
+        outputs = _outputs,
+        additional_toolchains = []):
+    """Makes the rule.
+
+    Args:
+      attrs: A dict. The attributes for the rule.
+      implementation: A function. The rule's implementation method.
+
+    Returns:
+      A rule.
+    """
+    return rule(
+        attrs = attrs,
+        fragments = [
+            "android",
+            "java",
+        ],
+        implementation = implementation,
+        provides = [
+            AndroidCcLinkParamsInfo,
+            AndroidIdeInfo,
+            AndroidIdlInfo,
+            AndroidLibraryResourceClassJarProvider,
+            AndroidNativeLibsInfo,
+            JavaInfo,
+        ],
+        outputs = outputs,
+        toolchains = [
+            "@rules_android//toolchains/android:toolchain_type",
+            "@rules_android//toolchains/android_sdk:toolchain_type",
+        ] + additional_toolchains,
+        _skylark_testable = True,
+    )
+
+android_library = make_rule()
+
+def _is_defined(name, attrs):
+    return name in attrs and attrs[name] != None
+
+def attrs_metadata(attrs):
+    """Adds additional metadata for specific android_library attrs.
+
+    Bazel native rules have additional capabilities when inspecting attrs that
+    are not available in Starlark. For example, native rules are able to
+    determine if an attribute was set by a user and make decisions based on this
+    knowledge - sometimes the behavior may differ if the user specifies the
+    default value of the attribute. As such the Starlark android_library uses
+    this shim to provide similar capabilities.
+
+    Args:
+      attrs: The attributes passed to the android_library rule.
+
+    Returns:
+      A dictionary containing attr values with additional metadata.
+    """
+
+    # Required for the outputs.
+    attrs["$defined_local_resources"] = bool(
+        attrs.get("assets") or
+        attrs.get("assets_dir") or
+        attrs.get("assets_dir") == "" or
+        attrs.get("export_manifest") or
+        attrs.get("manifest") or
+        attrs.get("resource_files"),
+    )
+
+    # TODO(b/116691720): Remove normalization when bug is fixed.
+    if _is_defined("exports_manifest", attrs):
+        attrs["exports_manifest"] = _attrs.tristate.normalize(
+            attrs.get("exports_manifest"),
+        )
+
+    # TODO(b/127517031): Remove these entries once fixed.
+    attrs["$defined_assets"] = _is_defined("assets", attrs)
+    attrs["$defined_assets_dir"] = _is_defined("assets_dir", attrs)
+    attrs["$defined_idl_import_root"] = _is_defined("idl_import_root", attrs)
+    attrs["$defined_idl_parcelables"] = _is_defined("idl_parcelables", attrs)
+    attrs["$defined_idl_srcs"] = _is_defined("idl_srcs", attrs)
+    return attrs
+
+def android_library_macro(**attrs):
+    """Bazel android_library rule.
+
+    https://docs.bazel.build/versions/master/be/android.html#android_library
+
+    Args:
+      **attrs: Rule attributes
+    """
+    android_library(**attrs_metadata(attrs))
diff --git a/rules/android_local_test.bzl b/rules/android_local_test.bzl
new file mode 100644
index 0000000..9b1fe39
--- /dev/null
+++ b/rules/android_local_test.bzl
@@ -0,0 +1,27 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel rule for Android local test."""
+
+load(":migration_tag_DONOTUSE.bzl", _add_migration_tag = "add_migration_tag")
+
+def android_local_test(**attrs):
+    """Bazel android_local_test rule.
+
+    https://docs.bazel.build/versions/master/be/android.html#android_local_test
+
+    Args:
+      **attrs: Rule attributes
+    """
+    native.android_local_test(**_add_migration_tag(attrs))
diff --git a/rules/android_ndk_repository.bzl b/rules/android_ndk_repository.bzl
new file mode 100644
index 0000000..34aa2e3
--- /dev/null
+++ b/rules/android_ndk_repository.bzl
@@ -0,0 +1,25 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel rule for Android ndk repository."""
+
+def android_ndk_repository(**attrs):
+    """Bazel android_ndk_repository rule.
+
+    https://docs.bazel.build/versions/master/be/android.html#android_ndk_repository
+
+    Args:
+      **attrs: Rule attributes
+    """
+    native.android_ndk_repository(**attrs)
diff --git a/rules/android_packaged_resources/BUILD b/rules/android_packaged_resources/BUILD
new file mode 100644
index 0000000..f858689
--- /dev/null
+++ b/rules/android_packaged_resources/BUILD
@@ -0,0 +1,25 @@
+# Starlark Resource Packaging for Android Rules.
+
+load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
+
+package(
+    default_visibility =
+        ["//third_party/bazel_rules/rules_android"],
+)
+
+licenses(["notice"])
+
+exports_files(["rule.bzl"])
+
+filegroup(
+    name = "all_files",
+    srcs = glob(["**"]),
+)
+
+bzl_library(
+    name = "bzl",
+    srcs = glob(["*.bzl"]),
+    deps = [
+        "@rules_android//rules:common_bzl",
+    ],
+)
diff --git a/rules/android_packaged_resources/attrs.bzl b/rules/android_packaged_resources/attrs.bzl
new file mode 100644
index 0000000..5a7bca7
--- /dev/null
+++ b/rules/android_packaged_resources/attrs.bzl
@@ -0,0 +1,69 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Attributes."""
+
+load(
+    "@rules_android//rules:attrs.bzl",
+    _attrs = "attrs",
+)
+
+ATTRS = _attrs.replace(
+    _attrs.add(
+        dict(
+            deps = attr.label_list(
+                allow_files = True,
+                allow_rules = [
+                    "aar_import",
+                    "android_library",
+                    "cc_library",
+                    "java_import",
+                    "java_library",
+                    "java_lite_proto_library",
+                ],
+                providers = [
+                    [CcInfo],
+                    [JavaInfo],
+                    ["AndroidResourcesInfo", "AndroidAssetsInfo"],
+                ],
+                cfg = android_common.multi_cpu_configuration,
+            ),
+            enable_data_binding = attr.bool(),
+            instruments = attr.label(),
+            manifest_values = attr.string_dict(),
+            manifest_merger = attr.string(
+                default = "auto",
+                values = ["auto", "legacy", "android", "force_android"],
+            ),
+            native_target = attr.label(
+                allow_files = False,
+                allow_rules = ["android_binary", "android_test"],
+            ),
+            resource_configuration_filters = attr.string_list(),
+            densities = attr.string_list(),
+            nocompress_extensions = attr.string_list(),
+            shrink_resources = _attrs.tristate.create(
+                default = _attrs.tristate.auto,
+            ),
+            _defined_resource_files = attr.bool(default = False),
+            _enable_manifest_merging = attr.bool(default = True),
+        ),
+        _attrs.COMPILATION,
+        _attrs.DATA_CONTEXT,
+    ),
+    # TODO(b/167599192): don't override manifest attr to remove .xml file restriction.
+    manifest = attr.label(
+        allow_single_file = True,
+    ),
+)
diff --git a/rules/android_packaged_resources/impl.bzl b/rules/android_packaged_resources/impl.bzl
new file mode 100644
index 0000000..e3d6ac0
--- /dev/null
+++ b/rules/android_packaged_resources/impl.bzl
@@ -0,0 +1,111 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Implementation."""
+
+load("@rules_android//rules:acls.bzl", "acls")
+load("@rules_android//rules:java.bzl", "java")
+load(
+    "@rules_android//rules:processing_pipeline.bzl",
+    "ProviderInfo",
+    "processing_pipeline",
+)
+load("@rules_android//rules:resources.bzl", _resources = "resources")
+load("@rules_android//rules:utils.bzl", "compilation_mode", "get_android_toolchain", "utils")
+
+def _process_resources(ctx, java_package, **unused_ctxs):
+    packaged_resources_ctx = _resources.package(
+        ctx,
+        assets = ctx.files.assets,
+        assets_dir = ctx.attr.assets_dir,
+        resource_files = ctx.files.resource_files,
+        manifest = ctx.file.manifest,
+        manifest_values = utils.expand_make_vars(ctx, ctx.attr.manifest_values),
+        resource_configs = ctx.attr.resource_configuration_filters,
+        densities = ctx.attr.densities,
+        nocompress_extensions = ctx.attr.nocompress_extensions,
+        java_package = java_package,
+        compilation_mode = compilation_mode.get(ctx),
+        shrink_resources = ctx.attr.shrink_resources,
+        use_android_resource_shrinking = ctx.fragments.android.use_android_resource_shrinking,
+        use_android_resource_cycle_shrinking = ctx.fragments.android.use_android_resource_cycle_shrinking,
+        use_legacy_manifest_merger = use_legacy_manifest_merger(ctx),
+        should_throw_on_conflict = not acls.in_allow_resource_conflicts(str(ctx.label)),
+        enable_data_binding = ctx.attr.enable_data_binding,
+        enable_manifest_merging = ctx.attr._enable_manifest_merging,
+        deps = ctx.attr.deps,
+        instruments = ctx.attr.instruments,
+        aapt = get_android_toolchain(ctx).aapt2.files_to_run,
+        android_jar = ctx.attr._android_sdk[AndroidSdkInfo].android_jar,
+        legacy_merger = ctx.attr._android_manifest_merge_tool.files_to_run,
+        xsltproc = ctx.attr._xsltproc_tool.files_to_run,
+        instrument_xslt = ctx.file._add_g3itr_xslt,
+        busybox = get_android_toolchain(ctx).android_resources_busybox.files_to_run,
+        host_javabase = ctx.attr._host_javabase,
+    )
+    return ProviderInfo(
+        name = "packaged_resources_ctx",
+        value = packaged_resources_ctx,
+    )
+
+def use_legacy_manifest_merger(ctx):
+    """Whether legacy manifest merging is enabled.
+
+    Args:
+      ctx: The context.
+
+    Returns:
+      Boolean indicating whether legacy manifest merging is enabled.
+    """
+    manifest_merger = ctx.attr.manifest_merger
+    android_manifest_merger = ctx.fragments.android.manifest_merger
+
+    if android_manifest_merger == "force_android":
+        return False
+    if manifest_merger == "auto":
+        manifest_merger = android_manifest_merger
+
+    return manifest_merger == "legacy"
+
+def finalize(ctx, providers, validation_outputs, **unused_ctxs):
+    providers.append(
+        OutputGroupInfo(
+            _validation = depset(validation_outputs),
+        ),
+    )
+    return providers
+
+# Order dependent, as providers will not be available to downstream processors
+# that may depend on the provider. Iteration order for a dictionary is based on
+# insertion.
+PROCESSORS = dict(
+    ResourceProcessor = _process_resources,
+)
+
+_PROCESSING_PIPELINE = processing_pipeline.make_processing_pipeline(
+    processors = PROCESSORS,
+    finalize = finalize,
+)
+
+def impl(ctx):
+    """The rule implementation.
+
+    Args:
+      ctx: The context.
+
+    Returns:
+      A list of providers.
+    """
+    java_package = java.resolve_package_from_label(ctx.label, ctx.attr.custom_package)
+    return processing_pipeline.run(ctx, java_package, _PROCESSING_PIPELINE)
diff --git a/rules/android_packaged_resources/rule.bzl b/rules/android_packaged_resources/rule.bzl
new file mode 100644
index 0000000..db3f96a
--- /dev/null
+++ b/rules/android_packaged_resources/rule.bzl
@@ -0,0 +1,91 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Starlark Resource Packaging for Android Rules."""
+
+load(":attrs.bzl", "ATTRS")
+load(":impl.bzl", "impl")
+load(
+    "@rules_android//rules:attrs.bzl",
+    _attrs = "attrs",
+)
+
+_DEFAULT_ALLOWED_ATTRS = ["name", "visibility", "tags", "testonly", "transitive_configs", "$enable_manifest_merging"]
+
+_DEFAULT_PROVIDES = [AndroidApplicationResourceInfo, OutputGroupInfo]
+
+# TODO(b/167721629): Rename android_packaged_resources to android_binary_internal.
+def make_rule(
+        attrs = ATTRS,
+        implementation = impl,
+        provides = _DEFAULT_PROVIDES):
+    """Makes the rule.
+
+    Args:
+      attrs: A dict. The attributes for the rule.
+      implementation: A function. The rule's implementation method.
+      provides: A list. The providers that the rule must provide.
+
+    Returns:
+      A rule.
+    """
+    return rule(
+        attrs = attrs,
+        implementation = implementation,
+        provides = provides,
+        toolchains = ["@rules_android//toolchains/android:toolchain_type"],
+        _skylark_testable = True,
+        fragments = [
+            "android",
+            "java",
+        ],
+    )
+
+_android_packaged_resources = make_rule()
+
+def sanitize_attrs(attrs, allowed_attrs = ATTRS.keys()):
+    """Sanitizes the attributes.
+
+    The android_packaged_resources has a subset of the android_binary attributes, but is
+    called from the android_binary macro with the same full set of attributes. This removes
+    any unnecessary attributes.
+
+    Args:
+      attrs: A dict. The attributes for the android_packaged_resources rule.
+      allowed_attrs: The list of attribute keys to keep.
+
+    Returns:
+      A dictionary containing valid attributes.
+    """
+    for attr_name in attrs.keys():
+        if attr_name not in allowed_attrs and attr_name not in _DEFAULT_ALLOWED_ATTRS:
+            attrs.pop(attr_name, None)
+
+        # Some teams set this to a boolean/None which works for the native attribute but breaks
+        # the Starlark attribute.
+        if attr_name == "shrink_resources":
+            if attrs[attr_name] == None:
+                attrs.pop(attr_name, None)
+            else:
+                attrs[attr_name] = _attrs.tristate.normalize(attrs[attr_name])
+
+    return attrs
+
+def android_packaged_resources_macro(**attrs):
+    """android_packaged_resources rule.
+
+    Args:
+      **attrs: Rule attributes
+    """
+    _android_packaged_resources(**sanitize_attrs(attrs))
diff --git a/rules/android_sdk.bzl b/rules/android_sdk.bzl
new file mode 100644
index 0000000..cf824e1
--- /dev/null
+++ b/rules/android_sdk.bzl
@@ -0,0 +1,53 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel rule for Android sdk."""
+
+load(":attrs.bzl", "ANDROID_SDK_ATTRS")
+
+def _impl(ctx):
+    proguard = ctx.attr._proguard if ctx.attr._proguard else ctx.attr.proguard
+    android_sdk_info = AndroidSdkInfo(
+        ctx.attr.build_tools_version,
+        ctx.file.framework_aidl,
+        ctx.attr.aidl_lib,
+        ctx.file.android_jar,
+        ctx.file.source_properties,
+        ctx.file.shrinked_android_jar,
+        ctx.file.main_dex_classes,
+        ctx.attr.adb.files_to_run,
+        ctx.attr.dx.files_to_run,
+        ctx.attr.main_dex_list_creator.files_to_run,
+        ctx.attr.aidl.files_to_run,
+        ctx.attr.aapt.files_to_run,
+        ctx.attr.aapt2.files_to_run,
+        ctx.attr.apkbuilder.files_to_run if ctx.attr.apkbuilder else None,
+        ctx.attr.apksigner.files_to_run,
+        proguard.files_to_run,
+        ctx.attr.zipalign.files_to_run,
+        # Passing the 'system' here is only necessary to support native android_binary.
+        # TODO(b/149114743): remove this after the migration to android_application.
+        ctx.attr._system[java_common.BootClassPathInfo] if ctx.attr._system and java_common.BootClassPathInfo in ctx.attr._system else None,
+    )
+    return [
+        android_sdk_info,
+        platform_common.ToolchainInfo(android_sdk_info = android_sdk_info),
+    ]
+
+android_sdk = rule(
+    attrs = ANDROID_SDK_ATTRS,
+    implementation = _impl,
+    fragments = ["java"],
+    provides = [AndroidSdkInfo],
+)
diff --git a/rules/android_sdk_repository.bzl b/rules/android_sdk_repository.bzl
new file mode 100644
index 0000000..f82f6e6
--- /dev/null
+++ b/rules/android_sdk_repository.bzl
@@ -0,0 +1,25 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel rule for Android sdk repository."""
+
+def android_sdk_repository(**attrs):
+    """Bazel android_sdk_repository rule.
+
+    https://docs.bazel.build/versions/master/be/android.html#android_sdk_repository
+
+    Args:
+      **attrs: Rule attributes
+    """
+    native.android_sdk_repository(**attrs)
diff --git a/rules/android_tools_defaults_jar.bzl b/rules/android_tools_defaults_jar.bzl
new file mode 100644
index 0000000..b226882
--- /dev/null
+++ b/rules/android_tools_defaults_jar.bzl
@@ -0,0 +1,32 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel rule for Android tools defaults jar."""
+
+load(":attrs.bzl", "ANDROID_TOOLS_DEFAULTS_JAR_ATTRS")
+load(":utils.bzl", "get_android_sdk")
+
+def _impl(ctx):
+    return [
+        DefaultInfo(
+            files = depset([get_android_sdk(ctx).android_jar]),
+        ),
+    ]
+
+android_tools_defaults_jar = rule(
+    attrs = ANDROID_TOOLS_DEFAULTS_JAR_ATTRS,
+    implementation = _impl,
+    fragments = ["android"],
+    toolchains = ["@rules_android//toolchains/android_sdk:toolchain_type"],
+)
diff --git a/rules/attrs.bzl b/rules/attrs.bzl
new file mode 100644
index 0000000..eca1947
--- /dev/null
+++ b/rules/attrs.bzl
@@ -0,0 +1,286 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Common attributes for Android rules."""
+
+load(":utils.bzl", "log")
+
+def _add(attrs, *others):
+    new = {}
+    new.update(attrs)
+    for o in others:
+        for name in o.keys():
+            if name in new:
+                log.error("Attr '%s' is defined twice." % name)
+            new[name] = o[name]
+    return new
+
+def _replace(attrs, **kwargs):
+    # Verify that new values are replacing existing ones, not adding.
+    for name in kwargs.keys():
+        if name not in attrs:
+            log.error("Attr '%s' is not defined, replacement failed." % name)
+    new = dict()
+    new.update(attrs)
+    new.update(kwargs)
+    return new
+
+def _make_tristate_attr(default, doc = "", mandatory = False):
+    return attr.int(
+        default = default,
+        doc = doc,
+        mandatory = mandatory,
+        values = [-1, 0, 1],
+    )
+
+def _normalize_tristate(attr_value):
+    """Normalizes the tristate value going into a rule.
+
+    This is required because "tristate" is not officially supported as an
+    attribute type. An equivalent attribute type is an in with a constrained
+    set of values, namely [-1, 0, 1]. Unfortunately, tristate accepts
+    multiple types, integers, booleans and strings ("auto"). As a result, this
+    method normalizes the inputs to an integer.
+
+    This method needs to be applied to attributes that were formally tristate
+    to normalize the inputs.
+    """
+    if type(attr_value) == "int":
+        return attr_value
+
+    if type(attr_value) == "string":
+        if attr_value.lower() == "auto":
+            return -1
+
+    if type(attr_value) == "bool":
+        return int(attr_value)
+
+    return attr_value  # Return unknown type, let the rule fail.
+
+_tristate = struct(
+    create = _make_tristate_attr,
+    normalize = _normalize_tristate,
+    yes = 1,
+    no = 0,
+    auto = -1,
+)
+
+_JAVA_RUNTIME = dict(
+    _host_javabase = attr.label(
+        cfg = "host",
+        default = Label("@rules_android//rules:current_java_runtime"),
+    ),
+)
+
+
+# Android SDK attribute.
+_ANDROID_SDK = dict(
+    _android_sdk = attr.label(
+        allow_rules = ["android_sdk"],
+        default = configuration_field(
+            fragment = "android",
+            name = "android_sdk_label",
+        ),
+        providers = [AndroidSdkInfo],
+    ),
+)
+
+# Compilation attributes for Android rules.
+_COMPILATION = _add(
+    dict(
+        assets = attr.label_list(
+            allow_files = True,
+            cfg = "target",
+        ),
+        assets_dir = attr.string(),
+        custom_package = attr.string(),
+        manifest = attr.label(
+            allow_single_file = [".xml"],
+        ),
+        resource_files = attr.label_list(
+            allow_files = True,
+        ),
+        data = attr.label_list(
+            allow_files = True,
+        ),
+        plugins = attr.label_list(
+            allow_rules = ["java_plugin"],
+            cfg = "host",
+        ),
+        javacopts = attr.string_list(),
+        # TODO: Expose getPlugins() in JavaConfiguration.java
+        #       com/google/devtools/build/lib/rules/java/JavaConfiguration.java
+        #       com/google/devtools/build/lib/rules/java/JavaOptions.java
+        #
+        # _java_plugins = attr.label(
+        #     allow_rules = ["java_plugin"],
+        #     default = configuration_field(
+        #         fragment = "java",
+        #         name = "plugin",
+        #     ),
+        # ),
+    ),
+    _JAVA_RUNTIME,
+)
+
+# Attributes for rules that use the AndroidDataContext android_data.make_context
+_DATA_CONTEXT = _add(
+    dict(
+        # Additional attrs needed for AndroidDataContext
+        _add_g3itr_xslt = attr.label(
+            cfg = "host",
+            default = Label("//tools/android/xslt:add_g3itr.xslt"),
+            allow_single_file = True,
+        ),
+        _android_manifest_merge_tool = attr.label(
+            cfg = "host",
+            default = Label("//tools/android:merge_manifests"),
+            executable = True,
+        ),
+        # TODO(b/145617058) Switching back to head RPBB until the Android rules release process is improved
+        _android_resources_busybox = attr.label(
+            cfg = "host",
+            default = Label("@rules_android//rules:ResourceProcessorBusyBox"),
+            executable = True,
+        ),
+        _xsltproc_tool = attr.label(
+            cfg = "host",
+            default = Label("//tools/android/xslt:xslt"),
+            allow_files = True,
+        ),
+    ),
+    _ANDROID_SDK,
+)
+
+
+
+
+
+
+
+ANDROID_SDK_ATTRS = dict(
+    aapt = attr.label(
+        allow_single_file = True,
+        cfg = "host",
+        executable = True,
+        mandatory = True,
+    ),
+    aapt2 = attr.label(
+        allow_single_file = True,
+        cfg = "host",
+        executable = True,
+    ),
+    aidl = attr.label(
+        allow_files = True,
+        cfg = "host",
+        executable = True,
+        mandatory = True,
+    ),
+    aidl_lib = attr.label(
+        allow_files = [".jar"],
+    ),
+    android_jar = attr.label(
+        allow_single_file = [".jar"],
+        cfg = "host",
+        mandatory = True,
+    ),
+    annotations_jar = attr.label(
+        allow_single_file = [".jar"],
+        cfg = "host",
+    ),
+    apkbuilder = attr.label(
+        allow_files = True,
+        cfg = "host",
+        executable = True,
+    ),
+    apksigner = attr.label(
+        allow_files = True,
+        cfg = "host",
+        executable = True,
+        mandatory = True,
+    ),
+    adb = attr.label(
+        allow_single_file = True,
+        cfg = "host",
+        executable = True,
+        mandatory = True,
+    ),
+    build_tools_version = attr.string(),
+    dx = attr.label(
+        allow_files = True,
+        cfg = "host",
+        executable = True,
+        mandatory = True,
+    ),
+    framework_aidl = attr.label(
+        allow_single_file = True,
+        cfg = "host",
+        mandatory = True,
+    ),
+    main_dex_classes = attr.label(
+        allow_single_file = True,
+        cfg = "host",
+        mandatory = True,
+    ),
+    main_dex_list_creator = attr.label(
+        allow_files = True,
+        cfg = "host",
+        executable = True,
+        mandatory = True,
+    ),
+    proguard = attr.label(
+        allow_files = True,
+        cfg = "host",
+        executable = True,
+        mandatory = True,
+    ),
+    shrinked_android_jar = attr.label(
+        allow_single_file = True,
+        cfg = "host",
+        mandatory = True,
+    ),
+    source_properties = attr.label(
+        allow_single_file = True,
+        cfg = "host",
+    ),
+    zipalign = attr.label(
+        allow_single_file = True,
+        cfg = "host",
+        executable = True,
+        mandatory = True,
+    ),
+    _proguard = attr.label(
+        cfg = "host",
+        default = configuration_field(
+            fragment = "java",
+            name = "proguard_top",
+        ),
+    ),
+    _system = attr.label(
+        default = Label("//tools/android:bootclasspath_android_only"),
+    ),
+)
+
+ANDROID_TOOLS_DEFAULTS_JAR_ATTRS = _add(_ANDROID_SDK)
+
+
+attrs = struct(
+    ANDROID_SDK = _ANDROID_SDK,
+    COMPILATION = _COMPILATION,
+    DATA_CONTEXT = _DATA_CONTEXT,
+    JAVA_RUNTIME = _JAVA_RUNTIME,
+    tristate = _tristate,
+    add = _add,
+    replace = _replace,
+)
diff --git a/rules/busybox.bzl b/rules/busybox.bzl
new file mode 100644
index 0000000..f0d78ac
--- /dev/null
+++ b/rules/busybox.bzl
@@ -0,0 +1,1033 @@
+# Copyright 2019 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel ResourcesBusyBox Commands."""
+
+load(":java.bzl", _java = "java")
+
+_ANDROID_RESOURCES_STRICT_DEPS = "android_resources_strict_deps"
+
+def _sanitize_assets_dir(assets_dir):
+    sanitized_assets_dir = "/".join(
+        [
+            part
+            for part in assets_dir.split("/")
+            if part != "" and part != "."
+        ],
+    )
+
+    return "/" + sanitized_assets_dir if assets_dir.startswith("/") else sanitized_assets_dir
+
+def _get_unique_assets_dirs(assets, assets_dir):
+    """Find the unique assets directories, partitioned by assets_dir.
+
+    Args:
+      assets: A list of Files. List of asset files to process.
+      assets_dir: String. String giving the path to the files in assets.
+
+    Returns:
+      A list of short_paths representing unique asset dirs.
+    """
+    if not assets:
+        return []
+
+    dirs = dict()
+
+    assets_dir = _sanitize_assets_dir(assets_dir)
+    if assets_dir:
+        partition_by = "/%s/" % assets_dir.strip("/")
+        for f in assets:
+            if f.is_directory and f.path.endswith(partition_by[:-1]):
+                # If f is a directory, check if its path ends with the assets_dir.
+                dirs[f.path] = True
+            elif f.is_directory and "_aar/unzipped" in f.path:
+                # Assets from an aar_import rule are extracted in a
+                # "assets" subdirectory of the given path
+                dirs["%s/assets" % f.path] = True
+            else:
+                # Partition to remove subdirectories beneath assets_dir
+                # Also removes the trailing /
+                dirs["".join(f.path.rpartition(partition_by)[:2])[:-1]] = True
+    else:
+        # Use the dirname of the generating target if no assets_dir.
+        for f in assets:
+            if f.is_source:
+                dirs[f.owner.package] = True
+            else:
+                # Prepend the root path for generated files.
+                dirs[f.root.path + "/" + f.owner.package] = True
+    return dirs.keys()
+
+def _get_unique_res_dirs(resource_files):
+    """Find the unique res dirs.
+
+    Args:
+      resource_files: A list of Files. A list of resource_files.
+
+    Returns:
+      A list of short_paths representing unique res dirs from the given resource files.
+    """
+    dirs = dict()
+    for f in resource_files:
+        if f.is_directory:
+            dirs[f.path] = True
+        else:
+            dirs[f.dirname.rpartition("/" + f.dirname.split("/")[-1])[0]] = True
+    return dirs.keys()
+
+def _make_serialized_resources_flag(
+        assets = [],
+        assets_dir = None,
+        resource_files = [],
+        label = "",
+        symbols = None):
+    return ";".join(
+        [
+            "#".join(_get_unique_res_dirs(resource_files)),
+            "#".join(_get_unique_assets_dirs(assets, assets_dir)),
+            label,
+            symbols.path if symbols else "",
+        ],
+    ).rstrip(":")
+
+def _make_resources_flag(
+        assets = [],
+        assets_dir = None,
+        resource_files = [],
+        manifest = None,
+        r_txt = None,
+        symbols = None):
+    return ":".join(
+        [
+            "#".join(_get_unique_res_dirs(resource_files)),
+            "#".join(_get_unique_assets_dirs(assets, assets_dir)),
+            manifest.path if manifest else "",
+            r_txt.path if r_txt else "",
+            symbols.path if symbols else "",
+        ],
+    )
+
+def _path(f):
+    return f.path
+
+def _make_package_resources_flags(resources_node):
+    if not (resources_node.manifest and resources_node.r_txt and resources_node.compiled_resources):
+        return None
+    flag = _make_resources_flag(
+        resource_files = resources_node.resource_files.to_list(),
+        assets = resources_node.assets.to_list(),
+        assets_dir = resources_node.assets_dir,
+        manifest = resources_node.manifest,
+        r_txt = resources_node.r_txt,
+        symbols = resources_node.compiled_resources,
+    )
+    return flag
+
+def _make_package_assets_flags(resources_node):
+    assets = resources_node.assets.to_list()
+    if not assets:
+        return None
+    return _make_serialized_resources_flag(
+        assets = assets,
+        assets_dir = resources_node.assets_dir,
+        label = str(resources_node.label),
+        symbols = resources_node.compiled_assets,
+    )
+
+def _extract_filters(
+        raw_list):
+    """Extract densities and resource_configuration filters from raw string lists.
+
+    In BUILD files, string lists can be represented as a list of strings, a single comma-separated
+    string, or a combination of both. This method outputs a single list of individual string values,
+    which can then be passed directly to resource processing actions. Empty strings are removed and
+    the final list is sorted.
+
+    Args:
+      raw_list: List of strings. The raw densities or resource configuration filters.
+
+    Returns:
+      List of strings extracted from the raw list.
+    """
+    out_filters = []
+    for item in raw_list:
+        if "," in item:
+            item_list = item.split(",")
+            for entry in item_list:
+                stripped_entry = entry.strip()
+                if stripped_entry:
+                    out_filters.append(stripped_entry)
+        elif item:
+            out_filters.append(item)
+    return sorted(out_filters)
+
+def _package(
+        ctx,
+        out_r_src_jar = None,
+        out_r_txt = None,
+        out_symbols = None,
+        out_manifest = None,
+        out_proguard_cfg = None,
+        out_main_dex_proguard_cfg = None,
+        out_resource_files_zip = None,
+        out_file = None,
+        package_type = None,
+        java_package = None,
+        manifest = None,
+        assets = [],
+        assets_dir = None,
+        resource_files = [],
+        resource_configs = None,
+        densities = [],
+        application_id = None,
+        direct_resources_nodes = [],
+        transitive_resources_nodes = [],
+        transitive_manifests = [],
+        transitive_assets = [],
+        transitive_compiled_assets = [],
+        transitive_resource_files = [],
+        transitive_compiled_resources = [],
+        transitive_r_txts = [],
+        additional_apks_to_link_against = [],
+        nocompress_extensions = [],
+        proto_format = False,
+        version_name = None,
+        version_code = None,
+        android_jar = None,
+        aapt = None,
+        busybox = None,
+        host_javabase = None,
+        should_throw_on_conflict = True,  # TODO: read this from allowlist at caller
+        debug = True):  # TODO: we will set this to false in prod builds
+    """Packages the compiled Android Resources with AAPT.
+
+    Args:
+      ctx: The context.
+      out_r_src_jar: A File. The R.java outputted by linking resources in a srcjar.
+      out_r_txt: A File. The resource IDs outputted by linking resources in text.
+      out_symbols: A File. The output zip containing compiled resources.
+      out_manifest: A File. The output processed manifest.
+      out_proguard_cfg: A File. The proguard config to be generated.
+      out_main_dex_proguard_cfg: A File. The main dex proguard config to be generated.
+      out_resource_files_zip: A File. The resource files zipped by linking resources.
+      out_file: A File. The Resource APK outputted by linking resources.
+      package_type: A string. The configuration type to use when packaging.
+      java_package: A string. The Java package for the generated R.java.
+      manifest: A File. The AndroidManifest.xml.
+      assets: sequence of Files. A list of Android assets files to be processed.
+      assets_dir: String. The name of the assets directory.
+      resource_files: A list of Files. The resource files.
+      resource_configs: A list of strings. The list of resource configuration
+        filters.
+      densities: A list of strings. The list of screen densities to filter for when
+        building the apk.
+      application_id: An optional string. The applicationId set in manifest values.
+      direct_resources_nodes: Depset of ResourcesNodeInfo providers. The set of
+        ResourcesNodeInfo from direct dependencies.
+      transitive_resources_nodes: Depset of ResourcesNodeInfo providers. The set
+        of ResourcesNodeInfo from transitive dependencies (not including directs).
+      transitive_manifests: List of Depsets. Depsets contain all transitive manifests.
+      transitive_assets: List of Depsets. Depsets contain all transitive assets.
+      transitive_compiled_assets: List of Depsets. Depsets contain all transitive
+        compiled_assets.
+      transitive_resource_files: List of Depsets. Depsets contain all transitive
+        resource files.
+      transitive_compiled_resources: List of Depsets. Depsets contain all transitive
+        compiled_resources.
+      transitive_r_txts: List of Depsets. Depsets contain all transitive R txt files.
+      additional_apks_to_link_against: A list of Files. Additional APKs to link
+        against. Optional.
+      nocompress_extensions: A list of strings. File extension to leave uncompressed
+        in the apk.
+      proto_format: Boolean, whether to generate the resource table in proto format.
+      version_name: A string. The version name to stamp the generated manifest with. Optional.
+      version_code: A string. The version code to stamp the generated manifest with. Optional.
+      android_jar: A File. The Android Jar.
+      aapt: A FilesToRunProvider. The AAPT executable.
+      busybox: A FilesToRunProvider. The ResourceProcessorBusyBox executable.
+      host_javabase: Target. The host javabase.
+      should_throw_on_conflict: A boolean. Determines whether an error should be thrown
+        when a resource conflict occurs.
+      debug: A boolean. Determines whether to enable debugging.
+    """
+    if not manifest:
+        fail("No manifest given, the manifest is mandatory.")
+
+    direct_data_flag = []
+    direct_compiled_resources = []
+
+    output_files = []
+    input_files = []
+    transitive_input_files = []
+
+    args = ctx.actions.args()
+    args.use_param_file("@%s")
+    args.add("--tool", "AAPT2_PACKAGE")
+    args.add("--")
+    args.add("--aapt2", aapt.executable)
+    args.add_joined(
+        "--data",
+        transitive_resources_nodes,
+        map_each = _make_package_resources_flags,
+        join_with = ",",
+    )
+    args.add_joined(
+        "--directData",
+        direct_resources_nodes,
+        map_each = _make_package_resources_flags,
+        join_with = ",",
+    )
+    args.add_joined(
+        "--directAssets",
+        direct_resources_nodes,
+        map_each = _make_package_assets_flags,
+        join_with = "&",
+        omit_if_empty = True,
+    )
+    args.add_joined(
+        "--assets",
+        transitive_resources_nodes,
+        map_each = _make_package_assets_flags,
+        join_with = "&",
+        omit_if_empty = True,
+    )
+    transitive_input_files.extend(transitive_resource_files)
+    transitive_input_files.extend(transitive_assets)
+    transitive_input_files.extend(transitive_compiled_assets)
+    transitive_input_files.extend(transitive_compiled_resources)
+    transitive_input_files.extend(transitive_manifests)
+    transitive_input_files.extend(transitive_r_txts)
+    args.add(
+        "--primaryData",
+        _make_resources_flag(
+            manifest = manifest,
+            assets = assets,
+            assets_dir = assets_dir,
+            resource_files = resource_files,
+        ),
+    )
+    input_files.append(manifest)
+    input_files.extend(resource_files)
+    input_files.extend(assets)
+    args.add("--androidJar", android_jar)
+    input_files.append(android_jar)
+    args.add("--rOutput", out_r_txt)
+    output_files.append(out_r_txt)
+    if out_symbols:
+        args.add("--symbolsOut", out_symbols)
+        output_files.append(out_symbols)
+    args.add("--srcJarOutput", out_r_src_jar)
+    output_files.append(out_r_src_jar)
+    if out_proguard_cfg:
+        args.add("--proguardOutput", out_proguard_cfg)
+        output_files.append(out_proguard_cfg)
+    if out_main_dex_proguard_cfg:
+        args.add("--mainDexProguardOutput", out_main_dex_proguard_cfg)
+        output_files.append(out_main_dex_proguard_cfg)
+    args.add("--manifestOutput", out_manifest)
+    output_files.append(out_manifest)
+    if out_resource_files_zip:
+        args.add("--resourcesOutput", out_resource_files_zip)
+        output_files.append(out_resource_files_zip)
+    if out_file:
+        args.add("--packagePath", out_file)
+        output_files.append(out_file)
+    args.add("--useAaptCruncher=no")  # Unnecessary, used for AAPT1 only but added here to minimize diffs.
+    if package_type:
+        args.add("--packageType", package_type)
+    if debug:
+        args.add("--debug")
+    if should_throw_on_conflict:
+        args.add("--throwOnResourceConflict")
+    if resource_configs:
+        args.add_joined("--resourceConfigs", _extract_filters(resource_configs), join_with = ",")
+    if densities:
+        args.add_joined("--densities", _extract_filters(densities), join_with = ",")
+    if application_id:
+        args.add("--applicationId", application_id)
+    if additional_apks_to_link_against:
+        args.add_joined(
+            "--additionalApksToLinkAgainst",
+            additional_apks_to_link_against,
+            join_with = ",",
+            map_each = _path,
+        )
+        input_files.extend(additional_apks_to_link_against)
+    if nocompress_extensions:
+        args.add_joined("--uncompressedExtensions", nocompress_extensions, join_with = ",")
+    if proto_format:
+        args.add("--resourceTableAsProto")
+    if version_name:
+        args.add("--versionName", version_name)
+    if version_code:
+        args.add("--versionCode", version_code)
+    args.add("--packageForR", java_package)
+
+    _java.run(
+        ctx = ctx,
+        host_javabase = host_javabase,
+        executable = busybox,
+        tools = [aapt],
+        arguments = [args],
+        inputs = depset(input_files, transitive = transitive_input_files),
+        outputs = output_files,
+        mnemonic = "PackageAndroidResources",
+        progress_message = "Packaging Android Resources in %s" % ctx.label,
+    )
+
+def _parse(
+        ctx,
+        out_symbols = None,
+        assets = [],
+        assets_dir = None,
+        busybox = None,
+        host_javabase = None):
+    """Parses Android assets.
+
+    Args:
+      ctx: The context.
+      out_symbols: A File. The output bin containing parsed assets.
+      assets: sequence of Files. A list of Android assets files to be processed.
+      assets_dir: String. The name of the assets directory.
+      busybox: A FilesToRunProvider. The ResourceProcessorBusyBox executable.
+      host_javabase: Target. The host javabase.
+    """
+    args = ctx.actions.args()
+    args.use_param_file("@%s")
+    args.add("--tool", "PARSE")
+    args.add("--")
+    args.add(
+        "--primaryData",
+        _make_resources_flag(
+            assets = assets,
+            assets_dir = assets_dir,
+        ),
+    )
+    args.add("--output", out_symbols)
+
+    _java.run(
+        ctx = ctx,
+        host_javabase = host_javabase,
+        executable = busybox,
+        arguments = [args],
+        inputs = assets,
+        outputs = [out_symbols],
+        mnemonic = "ParseAndroidResources",
+        progress_message = "Parsing Android Resources in %s" % out_symbols.short_path,
+    )
+
+def _make_merge_assets_flags(resources_node):
+    assets = resources_node.assets.to_list()
+    if not (assets or resources_node.assets_dir):
+        return None
+    return _make_serialized_resources_flag(
+        assets = assets,
+        assets_dir = resources_node.assets_dir,
+        label = str(resources_node.label),
+        symbols = resources_node.assets_symbols,
+    )
+
+def _merge_assets(
+        ctx,
+        out_assets_zip = None,
+        assets = [],
+        assets_dir = None,
+        symbols = None,
+        transitive_assets = [],
+        transitive_assets_symbols = [],
+        direct_resources_nodes = [],
+        transitive_resources_nodes = [],
+        busybox = None,
+        host_javabase = None):
+    """Merges Android assets.
+
+    Args:
+      ctx: The context.
+      out_assets_zip: A File.
+      assets: sequence of Files. A list of Android assets files to be processed.
+      assets_dir: String. The name of the assets directory.
+      symbols: A File. The parsed assets.
+      transitive_assets: Sequence of Depsets. The list of transitive
+        assets from deps.
+      transitive_assets_symbols: Sequence of Depsets. The list of
+        transitive assets_symbols files from deps.
+      direct_resources_nodes: Sequence of ResourcesNodeInfo providers. The list
+        of ResourcesNodeInfo providers that are direct depencies.
+      transitive_resources_nodes: Sequence of ResourcesNodeInfo providers. The
+        list of ResourcesNodeInfo providers that are transitive depencies.
+      busybox: A FilesToRunProvider. The ResourceProcessorBusyBox executable.
+      host_javabase: Target. The host javabase.
+    """
+    args = ctx.actions.args()
+    args.use_param_file("@%s")
+    args.add("--tool", "MERGE_ASSETS")
+    args.add("--")
+    args.add("--assetsOutput", out_assets_zip)
+    args.add(
+        "--primaryData",
+        _make_serialized_resources_flag(
+            assets = assets,
+            assets_dir = assets_dir,
+            label = str(ctx.label),
+            symbols = symbols,
+        ),
+    )
+    args.add_joined(
+        "--directData",
+        direct_resources_nodes,
+        map_each = _make_merge_assets_flags,
+        join_with = "&",
+    )
+    args.add_joined(
+        "--data",
+        transitive_resources_nodes,
+        map_each = _make_merge_assets_flags,
+        join_with = "&",
+    )
+
+    _java.run(
+        ctx = ctx,
+        host_javabase = host_javabase,
+        executable = busybox,
+        arguments = [args],
+        inputs = depset(
+            assets + [symbols],
+            transitive = transitive_assets + transitive_assets_symbols,
+        ),
+        outputs = [out_assets_zip],
+        mnemonic = "MergeAndroidAssets",
+        progress_message =
+            "Merging Android Assets in %s" % out_assets_zip.short_path,
+    )
+
+def _validate_and_link(
+        ctx,
+        out_r_src_jar = None,
+        out_r_txt = None,
+        out_file = None,
+        compiled_resources = None,
+        transitive_compiled_resources = depset(),
+        java_package = None,
+        manifest = None,
+        android_jar = None,
+        busybox = None,
+        host_javabase = None,
+        aapt = None):
+    """Links compiled Android Resources with AAPT.
+
+    Args:
+      ctx: The context.
+      out_r_src_jar: A File. The R.java outputted by linking resources in a srcjar.
+      out_r_txt: A File. The resource IDs outputted by linking resources in text.
+      out_file: A File. The Resource APK outputted by linking resources.
+      compiled_resources: A File. The symbols.zip of compiled resources for
+        this target.
+      transitive_compiled_resources: Depset of Files. The symbols.zip of the
+        compiled resources from the transitive dependencies of this target.
+      java_package: A string. The Java package for the generated R.java.
+      manifest: A File. The AndroidManifest.xml.
+      android_jar: A File. The Android Jar.
+      busybox: A FilesToRunProvider. The ResourceProcessorBusyBox executable.
+      host_javabase: Target. The host javabase.
+      aapt: A FilesToRunProvider. The AAPT executable.
+    """
+    output_files = []
+    input_files = [android_jar]
+    transitive_input_files = []
+
+    # Retrieves the list of files at runtime when a directory is passed.
+    args = ctx.actions.args()
+    args.use_param_file("@%s")
+    args.add("--tool", "LINK_STATIC_LIBRARY")
+    args.add("--")
+    args.add("--aapt2", aapt.executable)
+    args.add("--libraries", android_jar)
+    if compiled_resources:
+        args.add("--compiled", compiled_resources)
+        input_files.append(compiled_resources)
+    args.add_joined(
+        "--compiledDep",
+        transitive_compiled_resources,
+        join_with = ":",
+    )
+    transitive_input_files.append(transitive_compiled_resources)
+    args.add("--manifest", manifest)
+    input_files.append(manifest)
+    if java_package:
+        args.add("--packageForR", java_package)
+    args.add("--sourceJarOut", out_r_src_jar)
+    output_files.append(out_r_src_jar)
+    args.add("--rTxtOut", out_r_txt)
+    output_files.append(out_r_txt)
+    args.add("--staticLibraryOut", out_file)
+    output_files.append(out_file)
+
+    _java.run(
+        ctx = ctx,
+        host_javabase = host_javabase,
+        executable = busybox,
+        tools = [aapt],
+        arguments = [args],
+        inputs = depset(input_files, transitive = transitive_input_files),
+        outputs = output_files,
+        mnemonic = "LinkAndroidResources",
+        progress_message =
+            "Linking Android Resources in " + out_file.short_path,
+    )
+
+def _compile(
+        ctx,
+        out_file = None,
+        assets = [],
+        assets_dir = None,
+        resource_files = [],
+        busybox = None,
+        aapt = None,
+        host_javabase = None):
+    """Compile and store resources in a single archive.
+
+    Args:
+      ctx: The context.
+      out_file: File. The output zip containing compiled resources.
+      resource_files: A list of Files. The list of resource files or directories
+      assets: A list of Files. The list of assets files or directories
+        to process.
+      assets_dir: String. The name of the assets directory.
+      busybox: A FilesToRunProvider. The ResourceProcessorBusyBox executable.
+      aapt: AAPT. Tool for compiling resources.
+      host_javabase: Target. The host javabase.
+    """
+    if not out_file:
+        fail("No output directory specified.")
+
+    # Retrieves the list of files at runtime when a directory is passed.
+    args = ctx.actions.args()
+    args.use_param_file("@%s")
+    args.add("--tool", "COMPILE_LIBRARY_RESOURCES")
+    args.add("--")
+    args.add("--aapt2", aapt.executable)
+    args.add(
+        "--resources",
+        _make_resources_flag(
+            resource_files = resource_files,
+            assets = assets,
+            assets_dir = assets_dir,
+        ),
+    )
+    args.add("--output", out_file)
+
+    _java.run(
+        ctx = ctx,
+        host_javabase = host_javabase,
+        executable = busybox,
+        tools = [aapt],
+        arguments = [args],
+        inputs = resource_files + assets,
+        outputs = [out_file],
+        mnemonic = "CompileAndroidResources",
+        progress_message = "Compiling Android Resources in %s" % out_file.short_path,
+    )
+
+def _make_merge_compiled_flags(resources_node_info):
+    if not resources_node_info.compiled_resources:
+        return None
+    return _make_serialized_resources_flag(
+        label = str(resources_node_info.label),
+        symbols = resources_node_info.compiled_resources,
+    )
+
+def _merge_compiled(
+        ctx,
+        out_class_jar = None,
+        out_manifest = None,
+        out_aapt2_r_txt = None,
+        java_package = None,
+        manifest = None,
+        compiled_resources = None,
+        direct_resources_nodes = [],
+        transitive_resources_nodes = [],
+        direct_compiled_resources = depset(),
+        transitive_compiled_resources = depset(),
+        android_jar = None,
+        busybox = None,
+        host_javabase = None):
+    """Merges the compile resources.
+
+    Args:
+      ctx: The context.
+      out_class_jar: A File. The compiled R.java outputted by linking resources.
+      out_manifest: A File. The list of resource files or directories
+      out_aapt2_r_txt: A File. The resource IDs outputted by linking resources in text.
+      java_package: A string. The Java package for the generated R.java.
+      manifest: A File. The AndroidManifest.xml.
+      compiled_resources: A File. The symbols.zip of compiled resources for this target.
+      direct_resources_nodes: Sequence of ResourcesNodeInfo providers. The list
+        of ResourcesNodeInfo providers that are direct depencies.
+      transitive_resources_nodes: Sequence of ResourcesNodeInfo providers. The
+        list of ResourcesNodeInfo providers that are transitive depencies.
+      direct_compiled_resources: Depset of Files. A depset of symbols.zip of
+        compiled resources from direct dependencies.
+      transitive_compiled_resources: Depset of Files. A depset of symbols.zip of
+        compiled resources from transitive dependencies.
+      android_jar: A File. The Android Jar.
+      busybox: A FilesToRunProvider. The ResourceProcessorBusyBox executable.
+      host_javabase: Target. The host javabase.
+    """
+    output_files = []
+    input_files = [android_jar]
+    transitive_input_files = []
+
+    args = ctx.actions.args()
+    args.use_param_file("@%s")
+    args.add("--tool", "MERGE_COMPILED")
+    args.add("--")
+    args.add("--classJarOutput", out_class_jar)
+    output_files.append(out_class_jar)
+    args.add("--targetLabel", ctx.label)
+    args.add("--manifestOutput", out_manifest)
+    output_files.append(out_manifest)
+    args.add("--rTxtOut", out_aapt2_r_txt)
+    output_files.append(out_aapt2_r_txt)
+    args.add("--androidJar", android_jar)
+    args.add("--primaryManifest", manifest)
+    input_files.append(manifest)
+    if java_package:
+        args.add("--packageForR", java_package)
+    args.add(
+        "--primaryData",
+        _make_serialized_resources_flag(
+            label = str(ctx.label),
+            symbols = compiled_resources,
+        ),
+    )
+    input_files.append(compiled_resources)
+    args.add_joined(
+        "--directData",
+        direct_resources_nodes,
+        map_each = _make_merge_compiled_flags,
+        join_with = "&",
+    )
+    transitive_input_files.append(direct_compiled_resources)
+    if _ANDROID_RESOURCES_STRICT_DEPS in ctx.disabled_features:
+        args.add_joined(
+            "--data",
+            transitive_resources_nodes,
+            map_each = _make_merge_compiled_flags,
+            join_with = "&",
+        )
+        transitive_input_files.append(transitive_compiled_resources)
+
+    _java.run(
+        ctx = ctx,
+        host_javabase = host_javabase,
+        executable = busybox,
+        arguments = [args],
+        inputs = depset(input_files, transitive = transitive_input_files),
+        outputs = output_files,
+        mnemonic = "StarlarkMergeCompiledAndroidResources",
+        progress_message =
+            "Merging compiled Android Resources in " + out_class_jar.short_path,
+    )
+
+def _escape_mv(s):
+    """Escapes `:` and `,` in manifest values so they can be used as a busybox flag."""
+    return s.replace(":", "\\:").replace(",", "\\,")
+
+def _owner_label(file):
+    return "//" + file.owner.package + ":" + file.owner.name
+
+# We need to remove the "/_migrated/" path segment from file paths in order for sorting to
+# match the order of the native manifest merging action.
+def _manifest_short_path(manifest):
+    return manifest.short_path.replace("/_migrated/", "/")
+
+def _mergee_manifests_flag(manifests):
+    ordered_manifests = sorted(manifests.to_list(), key = _manifest_short_path)
+    entries = []
+    for manifest in ordered_manifests:
+        label = _owner_label(manifest).replace(":", "\\:")
+        entries.append((manifest.path + ":" + label).replace(",", "\\,"))
+    flag_entry = ",".join(entries)
+    if not flag_entry:
+        return None
+    return flag_entry
+
+def _merge_manifests(
+        ctx,
+        out_file = None,
+        out_log_file = None,
+        merge_type = "APPLICATION",
+        manifest = None,
+        mergee_manifests = depset(),
+        manifest_values = None,
+        java_package = None,
+        busybox = None,
+        host_javabase = None):
+    """Merge multiple AndroidManifest.xml files into a single one.
+
+    Args:
+      ctx: The context.
+      out_file: A File. The output merged manifest.
+      out_log_file: A File. The output log from the merge tool.
+      merge_type: A string, either APPLICATION or LIBRARY. Type of merging.
+      manifest: A File. The primary AndroidManifest.xml.
+      mergee_manifests: A depset of Files. All transitive manifests to be merged.
+      manifest_values: A dictionary. Manifest values to substitute.
+      java_package: A string. Custom java package to insert in manifest package attribute.
+      busybox: A FilesToRunProvider. The ResourceProcessorBusyBox executable.
+      host_javabase: Target. The host javabase.
+    """
+    if merge_type not in ["APPLICATION", "LIBRARY"]:
+        fail("Unexpected manifest merge type: " + merge_type)
+
+    outputs = [out_file]
+    directs = [manifest]
+    transitives = [mergee_manifests]
+
+    # Args for busybox
+    args = ctx.actions.args()
+    args.use_param_file("@%s", use_always = True)
+    args.add("--tool", "MERGE_MANIFEST")
+    args.add("--")
+    args.add("--manifest", manifest)
+    args.add_all(
+        "--mergeeManifests",
+        [mergee_manifests],
+        map_each = _mergee_manifests_flag,
+    )
+    if manifest_values:
+        args.add(
+            "--manifestValues",
+            ",".join(["%s:%s" % (_escape_mv(k), _escape_mv(v)) for k, v in manifest_values.items()]),
+        )
+    args.add("--mergeType", merge_type)
+    args.add("--customPackage", java_package)
+    args.add("--manifestOutput", out_file)
+    if out_log_file:
+        args.add("--log", out_log_file)
+        outputs.append(out_log_file)
+
+    _java.run(
+        ctx = ctx,
+        host_javabase = host_javabase,
+        executable = busybox,
+        arguments = [args],
+        inputs = depset(directs, transitive = transitives),
+        outputs = outputs,
+        mnemonic = "MergeManifests",
+        progress_message = "Merging Android Manifests in %s" % out_file.short_path,
+    )
+
+def _process_databinding(
+        ctx,
+        out_databinding_info = None,
+        out_databinding_processed_resources = None,
+        databinding_resources_dirname = None,
+        resource_files = None,
+        java_package = None,
+        busybox = None,
+        host_javabase = None):
+    """Processes databinding for android_binary.
+
+    Processes databinding declarations over resources, populates the databinding layout
+    info file, and generates new resources with databinding expressions stripped out.
+
+    Args:
+      ctx: The context.
+      out_databinding_info: File. The output databinding layout info zip file.
+      out_databinding_processed_resources: List of Files. The generated databinding
+        processed resource files.
+      databinding_resources_dirname: String. The execution path to the directory where
+      the out_databinding_processed_resources are generated.
+      resource_files: List of Files. The resource files to be processed.
+      java_package: String. Java package for which java sources will be
+        generated. By default the package is inferred from the directory where
+        the BUILD file containing the rule is.
+      busybox: FilesToRunProvider. The ResourceBusyBox executable or
+        FilesToRunprovider
+      host_javabase: A Target. The host javabase.
+    """
+    res_dirs = _get_unique_res_dirs(resource_files)
+
+    args = ctx.actions.args()
+    args.add("--tool", "PROCESS_DATABINDING")
+    args.add("--")
+    args.add("--output_resource_directory", databinding_resources_dirname)
+    args.add_all(res_dirs, before_each = "--resource_root")
+    args.add("--dataBindingInfoOut", out_databinding_info)
+    args.add("--appId", java_package)
+
+    _java.run(
+        ctx = ctx,
+        host_javabase = host_javabase,
+        executable = busybox,
+        arguments = [args],
+        inputs = resource_files,
+        outputs = [out_databinding_info] + out_databinding_processed_resources,
+        mnemonic = "StarlarkProcessDatabinding",
+        progress_message = "Processing data binding",
+    )
+
+def _make_generate_binay_r_flags(resources_node):
+    if not (resources_node.r_txt or resources_node.manifest):
+        return None
+    return ",".join(
+        [
+            resources_node.r_txt.path if resources_node.r_txt else "",
+            resources_node.manifest.path if resources_node.manifest else "",
+        ],
+    )
+
+def _generate_binary_r(
+        ctx,
+        out_class_jar = None,
+        r_txt = None,
+        manifest = None,
+        package_for_r = None,
+        final_fields = None,
+        resources_nodes = depset(),
+        transitive_r_txts = [],
+        transitive_manifests = [],
+        busybox = None,
+        host_javabase = None):
+    """Generate compiled resources class jar.
+
+    Args:
+      ctx: The context.
+      out_class_jar: File. The output class jar file.
+      r_txt: File. The resource IDs outputted by linking resources in text.
+      manifest: File. The primary AndroidManifest.xml.
+      package_for_r: String. The Java package for the generated R class files.
+      final_fields: Bool. Whether fields get declared as final.
+      busybox: FilesToRunProvider. The ResourceBusyBox executable or
+        FilesToRunprovider
+      host_javabase: A Target. The host javabase.
+    """
+    args = ctx.actions.args()
+    args.add("--tool", "GENERATE_BINARY_R")
+    args.add("--")
+    args.add("--primaryRTxt", r_txt)
+    args.add("--primaryManifest", manifest)
+    args.add("--packageForR", package_for_r)
+    args.add_all(
+        resources_nodes,
+        map_each = _make_generate_binay_r_flags,
+        before_each = "--library",
+    )
+    if final_fields:
+        args.add("--finalFields")
+    else:
+        args.add("--nofinalFields")
+
+    # TODO(b/154003916): support transitive "--library transitive_r_txt_path,transitive_manifest_path" flags
+    args.add("--classJarOutput", out_class_jar)
+    args.add("--targetLabel", str(ctx.label))
+
+    _java.run(
+        ctx = ctx,
+        host_javabase = host_javabase,
+        executable = busybox,
+        arguments = [args],
+        inputs = depset([r_txt, manifest], transitive = transitive_r_txts + transitive_manifests),
+        outputs = [out_class_jar],
+        mnemonic = "StarlarkRClassGenerator",
+        progress_message = "Generating R classes",
+    )
+
+def _make_aar(
+        ctx,
+        out_aar = None,
+        assets = [],
+        assets_dir = None,
+        resource_files = [],
+        class_jar = None,
+        r_txt = None,
+        manifest = None,
+        proguard_specs = [],
+        should_throw_on_conflict = False,
+        busybox = None,
+        host_javabase = None):
+    """Generate an android archive file.
+
+    Args:
+      ctx: The context.
+      out_aar: File. The output AAR file.
+      assets: sequence of Files. A list of Android assets files to be processed.
+      assets_dir: String. The name of the assets directory.
+      resource_files: A list of Files. The resource files.
+      class_jar: File. The class jar file.
+      r_txt: File. The resource IDs outputted by linking resources in text.
+      manifest: File. The primary AndroidManifest.xml.
+      proguard_specs: List of File. The proguard spec files.
+      busybox: FilesToRunProvider. The ResourceBusyBox executable or
+        FilesToRunprovider
+      host_javabase: A Target. The host javabase.
+      should_throw_on_conflict: A boolean. Determines whether an error should be thrown
+        when a resource conflict occurs.
+    """
+    args = ctx.actions.args()
+    args.add("--tool", "GENERATE_AAR")
+    args.add("--")
+    args.add(
+        "--mainData",
+        _make_resources_flag(
+            manifest = manifest,
+            assets = assets,
+            assets_dir = assets_dir,
+            resource_files = resource_files,
+        ),
+    )
+    args.add("--manifest", manifest)
+    args.add("--rtxt", r_txt)
+    args.add("--classes", class_jar)
+    args.add("--aarOutput", out_aar)
+    args.add_all(proguard_specs, before_each = "--proguardSpec")
+    if should_throw_on_conflict:
+        args.add("--throwOnResourceConflict")
+
+    _java.run(
+        ctx = ctx,
+        host_javabase = host_javabase,
+        executable = busybox,
+        arguments = [args],
+        inputs = (
+            resource_files +
+            assets +
+            proguard_specs +
+            [r_txt, manifest, class_jar]
+        ),
+        outputs = [out_aar],
+        mnemonic = "StarlarkAARGenerator",
+        progress_message = "Generating AAR package for %s" % ctx.label,
+    )
+
+busybox = struct(
+    compile = _compile,
+    merge_compiled = _merge_compiled,
+    validate_and_link = _validate_and_link,
+    merge_manifests = _merge_manifests,
+    package = _package,
+    parse = _parse,
+    merge_assets = _merge_assets,
+    make_resources_flag = _make_resources_flag,
+    process_databinding = _process_databinding,
+    generate_binary_r = _generate_binary_r,
+    make_aar = _make_aar,
+
+    # Exposed for testing
+    mergee_manifests_flag = _mergee_manifests_flag,
+    get_unique_res_dirs = _get_unique_res_dirs,
+    sanitize_assets_dir = _sanitize_assets_dir,
+    extract_filters = _extract_filters,
+)
diff --git a/rules/common.bzl b/rules/common.bzl
new file mode 100644
index 0000000..6e84559
--- /dev/null
+++ b/rules/common.bzl
@@ -0,0 +1,111 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel common library for the Android rules."""
+
+load(":java.bzl", _java = "java")
+load(":utils.bzl", "get_android_sdk", "get_android_toolchain", _log = "log")
+
+# TODO(ostonge): Remove once kotlin/jvm_library.internal.bzl
+# is updated and released to use the java.resolve_package function
+def _java_package(label, custom_package):
+    return _java.resolve_package_from_label(label, custom_package)
+
+# Validates that the packages listed under "deps" all have the given constraint. If a package
+# does not have this attribute, an error is generated.
+def _validate_constraints(targets, constraint):
+    for target in targets:
+        if JavaInfo in target:
+            if constraint not in java_common.get_constraints(target[JavaInfo]):
+                _log.error("%s: does not have constraint '%s'" % (target.label, constraint))
+
+TARGET_DNE = "Target '%s' does not exist or is a file and is not allowed."
+
+def _check_rule(targets):
+    _validate_constraints(targets, "android")
+
+def _get_java_toolchain(ctx):
+    if not hasattr(ctx.attr, "_java_toolchain"):
+        _log.error("Missing _java_toolchain attr")
+    return ctx.attr._java_toolchain
+
+def _get_host_javabase(ctx):
+    if not hasattr(ctx.attr, "_host_javabase"):
+        _log.error("Missing _host_javabase attr")
+    return ctx.attr._host_javabase
+
+def _sign_apk(ctx, unsigned_apk, signed_apk, keystore = None, signing_keys = [], signing_lineage = None):
+    """Signs an apk. Usage of keystore is deprecated. Prefer using signing_keys."""
+    inputs = [unsigned_apk]
+    signer_args = ctx.actions.args()
+    signer_args.add("sign")
+
+    if signing_keys:
+        inputs.extend(signing_keys)
+        for i, key in enumerate(signing_keys):
+            if i > 0:
+                signer_args.add("--next-signer")
+            signer_args.add("--ks")
+            signer_args.add(key.path)
+            signer_args.add("--ks-pass")
+            signer_args.add("pass:android")
+        if signing_lineage:
+            inputs.append(signing_lineage)
+            signer_args.add("--lineage", signing_lineage.path)
+    elif keystore:
+        inputs.append(keystore)
+        signer_args.add("--ks", keystore.path)
+        signer_args.add("--ks-pass", "pass:android")
+
+    signer_args.add("--v1-signing-enabled", ctx.fragments.android.apk_signing_method_v1)
+    signer_args.add("--v1-signer-name", "CERT")
+    signer_args.add("--v2-signing-enabled", ctx.fragments.android.apk_signing_method_v2)
+    signer_args.add("--out", signed_apk.path)
+    signer_args.add(unsigned_apk.path)
+    ctx.actions.run(
+        executable = get_android_sdk(ctx).apk_signer,
+        inputs = inputs,
+        outputs = [signed_apk],
+        arguments = [signer_args],
+        mnemonic = "ApkSignerTool",
+        progress_message = "Signing APK for %s" % unsigned_apk.path,
+    )
+    return signed_apk
+
+def _filter_zip(ctx, in_zip, out_zip, filters = []):
+    """Creates a copy of a zip file with files that match filters."""
+    args = ctx.actions.args()
+    args.add("-q")
+    args.add(in_zip.path)
+    args.add_all(filters)
+    args.add("--copy")
+    args.add("--out")
+    args.add(out_zip.path)
+    ctx.actions.run(
+        executable = get_android_toolchain(ctx).zip_tool.files_to_run,
+        arguments = [args],
+        inputs = [in_zip],
+        outputs = [out_zip],
+        mnemonic = "FilterZip",
+        progress_message = "Filtering %s" % in_zip.short_path,
+    )
+
+common = struct(
+    check_rule = _check_rule,
+    get_host_javabase = _get_host_javabase,
+    get_java_toolchain = _get_java_toolchain,
+    filter_zip = _filter_zip,
+    java_package = _java_package,
+    sign_apk = _sign_apk,
+)
diff --git a/rules/data_binding.bzl b/rules/data_binding.bzl
new file mode 100644
index 0000000..39923ec
--- /dev/null
+++ b/rules/data_binding.bzl
@@ -0,0 +1,286 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel Android Data Binding."""
+
+load(":utils.bzl", _utils = "utils")
+
+# Data Binding context attributes.
+_JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_INPUTS = \
+    "java_annotation_processor_additional_inputs"
+_JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_OUTPUTS = \
+    "java_annotation_processor_additional_outputs"
+_JAVA_PLUGINS = "java_plugins"
+_JAVA_SRCS = "java_srcs"
+_JAVAC_OPTS = "javac_opts"
+_PROVIDERS = "providers"
+
+DataBindingContextInfo = provider(
+    doc = "Contains data from processing Android Data Binding.",
+    fields = {
+        _JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_INPUTS: (
+            "Additional inputs required by the Java annotation processor."
+        ),
+        _JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_OUTPUTS: (
+            "Additional outputs produced by the Java annotation processor."
+        ),
+        _JAVA_PLUGINS: "Data Binding Java annotation processor",
+        _JAVA_SRCS: "Java sources required by the Java annotation processor.",
+        _JAVAC_OPTS: (
+            "Additional Javac opts required by the Java annotation processor."
+        ),
+        _PROVIDERS: "The list of all providers to propagate.",
+    },
+)
+
+# Path used when resources have not been defined.
+_NO_RESOURCES_PATH = "/tmp/no_resources"
+
+def _copy_annotation_file(ctx, output_dir, annotation_template):
+    annotation_out = ctx.actions.declare_file(
+        output_dir + "/android/databinding/layouts/DataBindingInfo.java",
+    )
+    _utils.copy_file(ctx, annotation_template, annotation_out)
+    return annotation_out
+
+def _gen_sources(ctx, output_dir, java_package, deps, data_binding_exec):
+    layout_info = ctx.actions.declare_file(output_dir + "layout-info.zip")
+    class_info = ctx.actions.declare_file(output_dir + "class-info.zip")
+    srcjar = ctx.actions.declare_file(output_dir + "baseClassSrc.srcjar")
+
+    args = ctx.actions.args()
+    args.add("-layoutInfoFiles", layout_info)
+    args.add("-package", java_package)
+    args.add("-classInfoOut", class_info)
+    args.add("-sourceOut", srcjar)
+    args.add("-zipSourceOutput", "true")
+    args.add("-useAndroidX", "false")
+
+    class_infos = []
+    for info in deps:
+        class_infos.extend(info.class_infos)
+    args.add_all(class_infos, before_each = "-dependencyClassInfoList")
+
+    ctx.actions.run(
+        executable = data_binding_exec,
+        arguments = ["GEN_BASE_CLASSES", args],
+        inputs = class_infos + [layout_info],
+        outputs = [class_info, srcjar],
+        mnemonic = "GenerateDataBindingBaseClasses",
+        progress_message = (
+            "GenerateDataBindingBaseClasses %s" % class_info.short_path
+        ),
+    )
+    return srcjar, class_info, layout_info
+
+def _setup_dependent_lib_artifacts(ctx, output_dir, deps):
+    # DataBinding requires files in very specific locations.
+    # The following expand_template (copy actions) are moving the files
+    # to the correct locations.
+    dep_lib_artifacts = []
+    for info in deps:
+        # Yes, DataBinding requires depsets iterations.
+        for artifact in (info.transitive_br_files.to_list() +
+                         info.setter_stores +
+                         info.class_infos):
+            # short_path might contain a parent directory reference if the
+            # databinding artifact is from an external repository (e.g. an aar
+            # from Maven). If that's the case, just remove the parent directory
+            # reference, otherwise the "dependent-lib-artifacts" directory will
+            # get removed by the "..".
+            path = artifact.short_path
+            if path.startswith("../"):
+                path = path[3:]
+            dep_lib_artifact = ctx.actions.declare_file(
+                output_dir + "dependent-lib-artifacts/" + path,
+            )
+
+            # Copy file to a location required by the DataBinding annotation
+            # processor.
+            # TODO(djwhang): Look into SymlinkAction.
+            if artifact.is_directory:
+                _utils.copy_dir(ctx, artifact, dep_lib_artifact)
+            else:
+                _utils.copy_file(ctx, artifact, dep_lib_artifact)
+            dep_lib_artifacts.append(dep_lib_artifact)
+    return dep_lib_artifacts
+
+def _get_javac_opts(
+        ctx,
+        java_package,
+        dependency_artifacts_dir,
+        aar_out_dir,
+        class_info_path,
+        layout_info_path,
+        deps):
+    java_packages = []
+    for info in deps:
+        for label_and_java_package in info.label_and_java_packages:
+            java_packages.append(label_and_java_package.java_package)
+
+    javac_opts = []
+    javac_opts.append("-Aandroid.databinding.dependencyArtifactsDir=" +
+                      dependency_artifacts_dir)
+    javac_opts.append("-Aandroid.databinding.aarOutDir=" + aar_out_dir)
+    javac_opts.append("-Aandroid.databinding.sdkDir=/not/used")
+    javac_opts.append("-Aandroid.databinding.artifactType=LIBRARY")
+    javac_opts.append("-Aandroid.databinding.exportClassListOutFile=" +
+                      "/tmp/exported_classes")
+    javac_opts.append("-Aandroid.databinding.modulePackage=" + java_package)
+    javac_opts.append("-Aandroid.databinding.directDependencyPkgs=[%s]" %
+                      ",".join(java_packages))
+
+    # The minimum Android SDK compatible with this rule.
+    # TODO(djwhang): This probably should be based on the actual min-sdk from
+    # the manifest, or an appropriate rule attribute.
+    javac_opts.append("-Aandroid.databinding.minApi=14")
+    javac_opts.append("-Aandroid.databinding.enableV2=1")
+
+    javac_opts.append("-Aandroid.databinding.classLogDir=" + class_info_path)
+    javac_opts.append("-Aandroid.databinding.layoutInfoDir=" + layout_info_path)
+    return javac_opts
+
+def _process(
+        ctx,
+        resources_ctx = None,
+        defines_resources = False,
+        enable_data_binding = False,
+        java_package = None,
+        deps = [],
+        exports = [],
+        data_binding_exec = None,
+        data_binding_annotation_processor = None,
+        data_binding_annotation_template = None):
+    """Processes Android Data Binding.
+
+    Args:
+      ctx: The context.
+      resources_ctx: The Android Resources context.
+      defines_resources: boolean. Determines whether resources were defined.
+      enable_data_binding: boolean. Determines whether Data Binding should be
+        enabled.
+      java_package: String. The Java package.
+      deps: sequence of DataBindingV2Info providers. A list of deps. Optional.
+      exports: sequence of DataBindingV2Info providers. A list of exports.
+        Optional.
+      data_binding_exec: The DataBinding executable.
+      data_binding_annotation_processor: JavaInfo. The JavaInfo for the
+        annotation processor.
+      data_binding_annotation_template: A file. Used to generate data binding
+        classes.
+
+    Returns:
+      A DataBindingContextInfo provider.
+    """
+
+    # TODO(b/154513292): Clean up bad usages of context objects.
+    if resources_ctx:
+        defines_resources = resources_ctx.defines_resources
+
+    # The Android Data Binding context object.
+    db_info = {
+        _JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_INPUTS: [],
+        _JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_OUTPUTS: [],
+        _JAVA_PLUGINS: [],
+        _JAVA_SRCS: [],
+        _JAVAC_OPTS: [],
+        _PROVIDERS: [],
+    }
+
+    if not enable_data_binding:
+        db_info[_PROVIDERS] = [
+            DataBindingV2Info(
+                databinding_v2_providers_in_deps = deps,
+                databinding_v2_providers_in_exports = exports,
+            ),
+        ]
+        return struct(**db_info)
+
+    output_dir = "_migrated/databinding/%s/" % ctx.label.name
+
+    db_info[_JAVA_SRCS].append(_copy_annotation_file(
+        ctx,
+        output_dir,
+        data_binding_annotation_template,
+    ))
+    db_info[_JAVA_PLUGINS].append(data_binding_annotation_processor)
+
+    br_out = None
+    setter_store_out = None
+    class_info = None
+    layout_info = None
+    if defines_resources:
+        # Outputs of the Data Binding annotation processor.
+        br_out = ctx.actions.declare_file(
+            output_dir + "bin-files/%s-br.bin" % java_package,
+        )
+        db_info[_JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_OUTPUTS].append(br_out)
+        setter_store_out = ctx.actions.declare_file(
+            output_dir + "bin-files/%s-setter_store.json" % java_package,
+        )
+        db_info[_JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_OUTPUTS].append(
+            setter_store_out,
+        )
+
+        srcjar, class_info, layout_info = _gen_sources(
+            ctx,
+            output_dir,
+            java_package,
+            deps,
+            data_binding_exec,
+        )
+        db_info[_JAVA_SRCS].append(srcjar)
+        db_info[_JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_INPUTS].append(class_info)
+        db_info[_JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_INPUTS].append(
+            layout_info,
+        )
+
+    dep_lib_artifacts = _setup_dependent_lib_artifacts(ctx, output_dir, deps)
+    db_info[_JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_INPUTS].extend(
+        dep_lib_artifacts,
+    )
+
+    db_info[_JAVAC_OPTS] = _get_javac_opts(
+        ctx,
+        java_package,
+        (
+            br_out.path.rpartition(br_out.short_path)[0] +
+            ctx.label.package +
+            "/" +
+            output_dir +
+            "dependent-lib-artifacts"
+        ),
+        br_out.dirname,
+        class_info.path if class_info else _NO_RESOURCES_PATH,
+        layout_info.path if layout_info else _NO_RESOURCES_PATH,
+        deps,
+    )
+
+    db_info[_PROVIDERS] = [
+        DataBindingV2Info(
+            setter_store_file = setter_store_out,
+            class_info_file = class_info,
+            br_file = br_out,
+            label = str(ctx.label),
+            java_package = java_package,
+            databinding_v2_providers_in_deps = deps,
+            databinding_v2_providers_in_exports = exports,
+        ),
+    ]
+
+    return DataBindingContextInfo(**db_info)
+
+data_binding = struct(
+    process = _process,
+)
diff --git a/rules/data_binding_annotation_template.txt b/rules/data_binding_annotation_template.txt
new file mode 100644
index 0000000..295397e
--- /dev/null
+++ b/rules/data_binding_annotation_template.txt
@@ -0,0 +1,15 @@
+package android.databinding.layouts;
+
+import android.databinding.BindingBuildInfo;
+
+/**
+ * Template for the file that feeds data binding's annotation processor. The
+ * processor reads the values set here to generate .java files that link XML
+ * data binding declarations (from layoutInfoDir) to app code.
+ */
+@BindingBuildInfo(
+    buildId="not_used_here" // Adds incrementality, which Bazel already supports
+)
+public class DataBindingInfo {
+  /* This only exists for annotation processing. */
+}
diff --git a/rules/flags/BUILD b/rules/flags/BUILD
new file mode 100644
index 0000000..4895b09
--- /dev/null
+++ b/rules/flags/BUILD
@@ -0,0 +1,22 @@
+# Flags for Android rules and mobile-install
+
+load("@rules_android//rules/flags:flags.bzl", "flags")
+load("@rules_android//rules/flags:flag_defs.bzl", "define_flags")
+load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
+
+
+licenses(["notice"])
+
+filegroup(
+    name = "all_files",
+    srcs = glob(["**"]),
+)
+
+bzl_library(
+    name = "bzl",
+    srcs = glob(["*.bzl"]),
+)
+
+define_flags()
+
+flags.FLAGS()
diff --git a/rules/flags/flag_defs.bzl b/rules/flags/flag_defs.bzl
new file mode 100644
index 0000000..cecb40a
--- /dev/null
+++ b/rules/flags/flag_defs.bzl
@@ -0,0 +1,92 @@
+# Copyright 2019 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Flag definitions."""
+
+load("@rules_android//rules/flags:flags.bzl", "flags")
+
+def define_flags():
+    flags.DEFINE_bool(
+        name = "android_enable_res_v3",
+        default = False,
+        description = "Enable Resource Processing Pipeline v3.",
+    )
+
+    flags.DEFINE_bool(
+        name = "use_direct_deploy",
+        default = False,
+        description = "Enable direct deployment.",
+    )
+
+    flags.DEFINE_int(
+        name = "num_dex_shards",
+        default = 16,
+        description = "Number of dex shards to use for mobile-install.",
+    )
+
+    flags.DEFINE_bool(
+        name = "use_custom_dex_shards",
+        default = False,
+        description = "Whether to use custom dex shard value for mobile-install.",
+    )
+
+    flags.DEFINE_bool_group(
+        name = "mi_v3",
+        default = True,
+        description = "Enable mobile-install v3.",
+        flags = [
+            # TODO(b/160897244): resv3 temporarily disabled while Starlark
+            #     resource processing is implemented and rolled out
+            # ":android_enable_res_v3",
+            ":use_custom_dex_shards",
+            ":use_direct_deploy",
+        ],
+    )
+
+    flags.DEFINE_bool_group(
+        name = "mi_dogfood",
+        default = False,
+        description = "Opt-in to mobile-install dogfood track.",
+        flags = [
+        ],
+    )
+
+    flags.DEFINE_bool(
+        name = "enable_splits",
+        default = False,
+        description = "Build and install split apks if the device supports them.",
+    )
+
+    flags.DEFINE_bool(
+        name = "use_adb_root",
+        default = True,
+        description = "Restart adb with root permissions.",
+    )
+
+    flags.DEFINE_bool(
+        name = "mi_desugar_java8_libs",
+        default = False,
+        description = "Set True with --config=android_java8_libs",
+    )
+
+    flags.DEFINE_bool(
+        name = "debug",
+        default = False,
+        description = "",
+    )
+
+    flags.EXPOSE_native_bool(
+        name = "stamp",
+        description = "Accesses the native --stamp CLI flag",
+    )
diff --git a/rules/flags/flags.bzl b/rules/flags/flags.bzl
new file mode 100644
index 0000000..e6e25a6
--- /dev/null
+++ b/rules/flags/flags.bzl
@@ -0,0 +1,255 @@
+# Copyright 2019 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel Flags."""
+
+load("@rules_android//rules:utils.bzl", "utils")
+
+_BoolFlagInfo = provider(
+    doc = "Provides information about a boolean flag",
+    fields = dict(
+        name = "flag name",
+        value = "flag value",
+        explicit = "whether value was set explicitly",
+    ),
+)
+_BoolFlagGroupInfo = provider(
+    doc = "Provides information about a boolean flag group",
+    fields = dict(
+        name = "group name",
+        value = "group value",
+        flags = "flag names that belong to this group",
+    ),
+)
+_IntFlagInfo = provider(
+    doc = "Provides information about an integer flag",
+    fields = dict(
+        name = "flag name",
+        value = "flag value",
+    ),
+)
+_NativeBoolFlagInfo = provider(
+    doc = "Provides information about a native boolean flag",
+    fields = dict(
+        name = "flag name, the name of the native flag being accessed.",
+        value = "flag value, derived from config_setting targets that access the value",
+    ),
+)
+FlagsInfo = provider(
+    doc = "Provides all flags",
+)
+
+def _native_bool_impl(ctx):
+    return _NativeBoolFlagInfo(
+        name = ctx.label.name,
+        value = ctx.attr.value,
+    )
+
+native_bool_flag = rule(
+    implementation = _native_bool_impl,
+    attrs = dict(
+        value = attr.bool(mandatory = True),
+    ),
+    provides = [_NativeBoolFlagInfo],
+)
+
+def native_bool_flag_macro(name, description):
+    """Provides access to a native boolean flag from Starlark.
+
+    Args:
+      name: The name of the native flag to access.
+      description: The description of the flag.
+    """
+    native.config_setting(
+        name = name + "_on",
+        values = {name: "True"},
+    )
+    native.config_setting(
+        name = name + "_off",
+        values = {name: "False"},
+    )
+    native_bool_flag(
+        name = name,
+        value = select({
+            (":" + name + "_on"): True,
+            (":" + name + "_off"): False,
+        }),
+    )
+
+def _get_bool(v):
+    v = v.lower()
+    if v == "true":
+        return True
+    if v == "false":
+        return False
+    fail("Unknown bool: " + v)
+
+def _bool_impl(ctx):
+    if ctx.label.name in ctx.var:
+        value = _get_bool(ctx.var[ctx.label.name])
+        return _BoolFlagInfo(
+            name = ctx.label.name,
+            value = value,
+            explicit = True,
+        )
+    return _BoolFlagInfo(
+        name = ctx.label.name,
+        value = ctx.attr.default,
+        explicit = False,
+    )
+
+bool_flag = rule(
+    implementation = _bool_impl,
+    attrs = dict(
+        default = attr.bool(
+            mandatory = True,
+        ),
+        description = attr.string(
+            mandatory = True,
+        ),
+    ),
+    provides = [_BoolFlagInfo],
+)
+
+def _bool_group_impl(ctx):
+    if ctx.label.name in ctx.var:
+        value = _get_bool(ctx.var[ctx.label.name])
+        return _BoolFlagGroupInfo(
+            name = ctx.label.name,
+            value = value,
+            flags = [f[_BoolFlagInfo].name for f in ctx.attr.flags],
+        )
+    return _BoolFlagGroupInfo(
+        name = ctx.label.name,
+        value = ctx.attr.default,
+        flags = [f[_BoolFlagInfo].name for f in ctx.attr.flags],
+    )
+
+bool_flag_group = rule(
+    implementation = _bool_group_impl,
+    attrs = dict(
+        default = attr.bool(
+            mandatory = True,
+        ),
+        description = attr.string(
+            mandatory = True,
+        ),
+        flags = attr.label_list(
+            mandatory = True,
+            providers = [_BoolFlagInfo],
+        ),
+    ),
+    provides = [_BoolFlagGroupInfo],
+)
+
+def _int_impl(ctx):
+    if ctx.label.name in ctx.var:
+        value = int(ctx.var[ctx.label.name])
+    else:
+        value = ctx.attr.default
+    return _IntFlagInfo(
+        name = ctx.label.name,
+        value = value,
+    )
+
+int_flag = rule(
+    implementation = _int_impl,
+    attrs = dict(
+        default = attr.int(
+            mandatory = True,
+        ),
+        description = attr.string(
+            mandatory = True,
+        ),
+    ),
+    provides = [_IntFlagInfo],
+)
+
+def _flags_impl_internal(bool_flags, bool_flag_groups, int_flags, native_bool_flags):
+    flags = dict()
+
+    # For each group, set all flags to the group value
+    for fg in bool_flag_groups:
+        for f in fg.flags:
+            if f in flags:
+                fail("Flag '%s' referenced in multiple flag groups" % f)
+            flags[f] = fg.value
+
+    # Set booleans
+    for b in bool_flags:
+        # Always set explicitly specified flags
+        if b.explicit:
+            flags[b.name] = b.value
+            # If not explicit, only set when not set by a group
+
+        elif b.name not in flags:
+            flags[b.name] = b.value
+
+    # Set ints
+    for i in int_flags:
+        flags[i.name] = i.value
+
+    # Set native bool flags
+    for n in native_bool_flags:
+        if n.name in flags:
+            fail("Flag '%s' defined as both native and non-native flag type" % n.name)
+        flags[n.name] = n.value
+
+    return FlagsInfo(**flags)
+
+def _flags_impl(ctx):
+    return _flags_impl_internal(
+        utils.collect_providers(_BoolFlagInfo, ctx.attr.targets),
+        utils.collect_providers(_BoolFlagGroupInfo, ctx.attr.targets),
+        utils.collect_providers(_IntFlagInfo, ctx.attr.targets),
+        utils.collect_providers(_NativeBoolFlagInfo, ctx.attr.targets),
+    )
+
+flags_rule = rule(
+    implementation = _flags_impl,
+    attrs = dict(
+        targets = attr.label_list(),
+    ),
+)
+
+def _flags_macro():
+    flags_rule(
+        name = "flags",
+        targets = native.existing_rules().keys(),
+        visibility = ["//visibility:public"],
+    )
+
+def _get_flags(ctx):
+    return ctx.attr._flags[FlagsInfo]
+
+flags = struct(
+    DEFINE_bool = bool_flag,
+    DEFINE_bool_group = bool_flag_group,
+    DEFINE_int = int_flag,
+    EXPOSE_native_bool = native_bool_flag_macro,
+    FLAGS = _flags_macro,
+    FlagsInfo = FlagsInfo,
+    get = _get_flags,
+)
+
+exported_for_test = struct(
+    BoolFlagGroupInfo = _BoolFlagGroupInfo,
+    BoolFlagInfo = _BoolFlagInfo,
+    IntFlagInfo = _IntFlagInfo,
+    NativeBoolFlagInfo = _NativeBoolFlagInfo,
+    bool_impl = _bool_impl,
+    flags_impl_internal = _flags_impl_internal,
+    int_impl = _int_impl,
+    native_bool_flag_macro = native_bool_flag_macro,
+)
diff --git a/rules/idl.bzl b/rules/idl.bzl
new file mode 100644
index 0000000..8dc52d3
--- /dev/null
+++ b/rules/idl.bzl
@@ -0,0 +1,264 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel Android IDL library for the Android rules."""
+
+load(":java.bzl", _java = "java")
+load(":path.bzl", _path = "path")
+load(":utils.bzl", _log = "log")
+
+_AIDL_TOOLCHAIN_MISSING_ERROR = (
+    "IDL sources provided without the Android IDL toolchain."
+)
+
+_AIDL_JAVA_ROOT_UNDETERMINABLE_ERROR = (
+    "Cannot determine java/javatests root for import %s."
+)
+
+IDLContextInfo = provider(
+    doc = "Contains data from processing Android IDL.",
+    fields = dict(
+        idl_srcs = "List of IDL sources",
+        idl_import_root = "IDL import root",
+        idl_java_srcs = "List of IDL Java sources",
+        idl_deps =
+            "List of IDL targets required for Java compilation, Proguard, etc.",
+        providers = "The list of all providers to propagate.",
+    ),
+)
+
+def _gen_java_from_idl(
+        ctx,
+        out_idl_java_src = None,
+        idl_src = None,
+        transitive_idl_import_roots = [],
+        transitive_idl_imports = [],
+        transitive_idl_preprocessed = [],
+        aidl = None,
+        aidl_lib = None,
+        aidl_framework = None):
+    args = ctx.actions.args()
+    args.add("-b")
+    args.add_all(transitive_idl_import_roots, format_each = "-I%s")
+    args.add(aidl_framework, format = "-p%s")
+    args.add_all(transitive_idl_preprocessed, format_each = "-p%s")
+    args.add(idl_src)
+    args.add(out_idl_java_src)
+
+    ctx.actions.run(
+        executable = aidl,
+        arguments = [args],
+        inputs = depset(
+            [aidl_framework],
+            transitive = [
+                aidl_lib.files,
+                transitive_idl_imports,
+                transitive_idl_preprocessed,
+            ],
+        ),
+        outputs = [out_idl_java_src],
+        mnemonic = "AndroidIDLGenerate",
+        progress_message = "Android IDL generation %s" % idl_src.path,
+    )
+
+def _get_idl_import_root_path(
+        package,
+        idl_import_root,
+        idl_file_root_path):
+    package_path = _path.relative(
+        idl_file_root_path,
+        package,
+    )
+    return _path.relative(
+        package_path,
+        idl_import_root,
+    )
+
+def _collect_unique_idl_import_root_paths(
+        package,
+        idl_import_root,
+        idl_imports):
+    idl_import_roots = dict()
+    for idl_import in idl_imports:
+        idl_import_roots[_get_idl_import_root_path(
+            package,
+            idl_import_root,
+            idl_import.root.path,
+        )] = True
+    return sorted(idl_import_roots.keys())
+
+def _collect_unique_java_roots(idl_imports):
+    idl_import_roots = dict()
+    for idl_import in idl_imports:
+        java_root = _java.root(idl_import.path)
+        if not java_root:
+            _log.error(_AIDL_JAVA_ROOT_UNDETERMINABLE_ERROR % idl_import.path)
+        idl_import_roots[java_root] = True
+    return sorted(idl_import_roots.keys())
+
+def _determine_idl_import_roots(
+        package,
+        idl_import_root = None,
+        idl_imports = []):
+    if idl_import_root == None:
+        return _collect_unique_java_roots(idl_imports)
+    return _collect_unique_idl_import_root_paths(
+        package,
+        idl_import_root,
+        idl_imports,
+    )
+
+def _process(
+        ctx,
+        idl_srcs = [],
+        idl_parcelables = [],
+        idl_import_root = None,
+        idl_preprocessed = [],
+        deps = [],
+        exports = [],
+        aidl = None,
+        aidl_lib = None,
+        aidl_framework = None):
+    """Processes Android IDL.
+
+    Args:
+      ctx: The context.
+      idl_srcs: sequence of Files. A list of the aidl source files to be
+        processed into Java source files and then compiled. Optional.
+      idl_parcelables: sequence of Files. A list of Android IDL definitions to
+        supply as imports. These files will be made available as imports for any
+        android_library target that depends on this library, directly or via its
+        transitive closure, but will not be translated to Java or compiled.
+
+        Only .aidl files that correspond directly to .java sources in this library
+        should be included (e.g. custom implementations of Parcelable), otherwise
+        idl_srcs should be used.
+
+        These files must be placed appropriately for the aidl compiler to find
+        them. See the description of idl_import_root for information about what
+        this means. Optional.
+      idl_import_root: string. Package-relative path to the root of the java
+        package tree containing idl sources included in this library. This path
+        will be used as the import root when processing idl sources that depend on
+        this library.
+
+        When idl_import_root is specified, both idl_parcelables and idl_srcs must
+        be at the path specified by the java package of the object they represent
+        under idl_import_root. When idl_import_root is not specified, both
+        idl_parcelables and idl_srcs must be at the path specified by their
+        package under a Java root. Optional.
+      idl_preprocessed: sequence of Files. A list of preprocessed Android IDL
+        definitions to supply as imports. These files will be made available as
+        imports for any android_library target that depends on this library,
+        directly or via its transitive closure, but will not be translated to
+        Java or compiled.
+
+        Only preprocessed .aidl files that correspond directly to .java sources
+        in this library should be included (e.g. custom implementations of
+        Parcelable), otherwise use idl_srcs for Android IDL definitions that
+        need to be translated to Java interfaces and use idl_parcelable for
+        non-preprcessed AIDL files. Optional.
+      deps: sequence of Targets. A list of dependencies. Optional.
+      exports: sequence of Targets. A list of exports. Optional.
+      aidl: Target. A target pointing to the aidl executable to be used for
+        Java code generation from *.idl source files. Optional, unless idl_srcs
+        are supplied.
+      aidl_lib: Target. A target pointing to the aidl_lib library required
+        during Java compilation when Java code is generated from idl sources.
+        Optional, unless idl_srcs are supplied.
+      aidl_framework: Target. A target pointing to the aidl framework. Optional,
+        unless idl_srcs are supplied.
+
+    Returns:
+      A IDLContextInfo provider.
+    """
+    if idl_srcs and not (aidl and aidl_lib and aidl_framework):
+        _log.error(_AIDL_TOOLCHAIN_MISSING_ERROR)
+
+    transitive_idl_import_roots = []
+    transitive_idl_imports = []
+    transitive_idl_preprocessed = []
+    for dep in deps + exports:
+        transitive_idl_import_roots.append(dep.transitive_idl_import_roots)
+        transitive_idl_imports.append(dep.transitive_idl_imports)
+        transitive_idl_preprocessed.append(dep.transitive_idl_preprocessed)
+
+    idl_java_srcs = []
+    for idl_src in idl_srcs:
+        idl_java_src = ctx.actions.declare_file(
+            ctx.label.name + "_aidl/" + idl_src.path.replace(".aidl", ".java"),
+        )
+        idl_java_srcs.append(idl_java_src)
+        _gen_java_from_idl(
+            ctx,
+            out_idl_java_src = idl_java_src,
+            idl_src = idl_src,
+            transitive_idl_import_roots = depset(
+                _determine_idl_import_roots(
+                    ctx.label.package,
+                    idl_import_root,
+                    idl_parcelables + idl_srcs,
+                ),
+                transitive = transitive_idl_import_roots,
+                order = "preorder",
+            ),
+            transitive_idl_imports = depset(
+                idl_parcelables + idl_srcs,
+                transitive = transitive_idl_imports,
+                order = "preorder",
+            ),
+            transitive_idl_preprocessed = depset(
+                transitive = transitive_idl_preprocessed,
+            ),
+            aidl = aidl,
+            aidl_lib = aidl_lib,
+            aidl_framework = aidl_framework,
+        )
+
+    return IDLContextInfo(
+        idl_srcs = idl_srcs,
+        idl_import_root = idl_import_root,
+        idl_java_srcs = idl_java_srcs,
+        idl_deps = [aidl_lib] if idl_java_srcs else [],
+        providers = [
+            # TODO(b/146216105): Make this a Starlark provider.
+            AndroidIdlInfo(
+                depset(
+                    _determine_idl_import_roots(
+                        ctx.label.package,
+                        idl_import_root,
+                        idl_parcelables + idl_srcs + idl_preprocessed,
+                    ),
+                    transitive = transitive_idl_import_roots,
+                    order = "preorder",
+                ),
+                depset(
+                    idl_parcelables + idl_srcs + idl_preprocessed,
+                    transitive = transitive_idl_imports,
+                    order = "preorder",
+                ),
+                depset(),  # TODO(b/146216105): Delete this field once in Starlark.
+                depset(idl_preprocessed, transitive = transitive_idl_preprocessed),
+            ),
+        ],
+    )
+
+idl = struct(
+    process = _process,
+)
+
+# Visible for testing.
+testing = struct(
+    get_idl_import_root_path = _get_idl_import_root_path,
+)
diff --git a/rules/intellij.bzl b/rules/intellij.bzl
new file mode 100644
index 0000000..c870b1b
--- /dev/null
+++ b/rules/intellij.bzl
@@ -0,0 +1,165 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Common methods for use by the IntelliJ Aspect."""
+
+load(":java.bzl", _java = "java")
+load(":utils.bzl", _utils = "utils")
+
+def _extract_idl_jars(
+        ctx,
+        idl_java_srcs = [],
+        jar = None,
+        manifest_proto = None,
+        out_srcjar = None,
+        out_jar = None,
+        idlclass = None,
+        host_javabase = None):
+    """Extracts the idl class and src jars."""
+    args = ctx.actions.args()
+    args.add("--class_jar", jar)
+    args.add("--manifest_proto", manifest_proto)
+    args.add("--output_class_jar", out_jar)
+    args.add("--output_source_jar", out_srcjar)
+    args.add("--temp_dir", out_jar.dirname)
+    args.add_all(idl_java_srcs)
+
+    _java.run(
+        ctx = ctx,
+        host_javabase = host_javabase,
+        executable = idlclass,
+        arguments = [args],
+        inputs = idl_java_srcs + [jar, manifest_proto],
+        outputs = [out_srcjar, out_jar],
+        mnemonic = "AndroidIdlJars",
+        progress_message = "Building idl jars %s" % out_jar.path,
+    )
+
+def _make_android_ide_info(
+        ctx,
+        idl_ctx = None,
+        resources_ctx = None,
+        defines_resources = False,
+        java_package = None,
+        manifest = None,
+        merged_manifest = None,
+        resources_apk = None,
+        idl_import_root = None,
+        idl_srcs = [],
+        idl_java_srcs = [],
+        java_info = None,
+        r_jar = None,
+        signed_apk = None,
+        aar = None,
+        apks_under_test = [],
+        native_libs = dict(),
+        idlclass = None,
+        host_javabase = None):
+    # TODO(b/154513292): Clean up bad usages of context objects.
+    if idl_ctx:
+        idl_import_root = idl_ctx.idl_import_root
+        idl_srcs = idl_ctx.idl_srcs
+        idl_java_srcs = idl_ctx.idl_java_srcs
+    if resources_ctx:
+        defines_resources = resources_ctx.defines_resources
+        merged_manifest = resources_ctx.merged_manifest
+        resources_apk = resources_ctx.resources_apk
+
+    if not defines_resources:
+        java_package = None
+        merged_manifest = None
+
+    # Extracts idl related classes from the jar and creates a src jar
+    # for the idl generated java.
+    idl_jar = None
+    idl_srcjar = None
+
+    # TODO(djwhang): JavaInfo.outputs.jar.manifest_proto is not created by
+    # Kotlin compile. Determine if this is the same manifest_proto produced
+    # by turbine, this could be pulled during annotation processing.
+    jar = _utils.only(java_info.outputs.jars)
+    if idl_java_srcs and jar.manifest_proto:
+        idl_jar = ctx.actions.declare_file("lib%s-idl.jar" % ctx.label.name)
+        idl_srcjar = \
+            ctx.actions.declare_file("lib%s-idl.srcjar" % ctx.label.name)
+
+        jar = _utils.only(java_info.outputs.jars)
+        _extract_idl_jars(
+            ctx,
+            idl_java_srcs = idl_java_srcs,
+            jar = jar.class_jar,
+            manifest_proto = jar.manifest_proto,
+            out_jar = idl_jar,
+            out_srcjar = idl_srcjar,
+            idlclass = idlclass,
+            host_javabase = host_javabase,
+        )
+
+    return AndroidIdeInfo(
+        java_package,
+        manifest,
+        merged_manifest,
+        idl_import_root,
+        idl_srcs,
+        idl_java_srcs,
+        idl_srcjar,
+        idl_jar,
+        defines_resources,
+        r_jar,
+        resources_apk,
+        signed_apk,
+        aar,
+        apks_under_test,
+        native_libs,
+    )
+
+def _make_legacy_android_provider(android_ide_info):
+    # Create the ClassJar "object" for the target.android.idl.output field.
+    if android_ide_info.idl_class_jar:
+        idl_class_jar = struct(
+            class_jar = android_ide_info.idl_class_jar,
+            ijar = None,
+            source_jar = android_ide_info.idl_source_jar,
+        )
+    else:
+        idl_class_jar = None
+
+    return struct(
+        aar = android_ide_info.aar,
+        apk = android_ide_info.signed_apk,
+        apks_under_test = android_ide_info.apks_under_test,
+        defines_resources = android_ide_info.defines_android_resources,
+        idl = struct(
+            import_root = android_ide_info.idl_import_root,
+            sources = android_ide_info.idl_srcs,
+            generated_java_files = android_ide_info.idl_generated_java_files,
+            output = idl_class_jar,
+        ),
+        java_package = android_ide_info.java_package,
+        manifest = android_ide_info.manifest,
+        merged_manifest = android_ide_info.generated_manifest,
+        native_libs = android_ide_info.native_libs,
+        resource_apk = android_ide_info.resource_apk,
+        resource_jar = android_ide_info.resource_jar,
+    )
+
+intellij = struct(
+    make_android_ide_info = _make_android_ide_info,
+    make_legacy_android_provider = _make_legacy_android_provider,
+)
+
+# Only visible for testing.
+testing = struct(
+    extract_idl_jars = _extract_idl_jars,
+)
diff --git a/rules/java.bzl b/rules/java.bzl
new file mode 100644
index 0000000..7b23b35
--- /dev/null
+++ b/rules/java.bzl
@@ -0,0 +1,447 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel Java APIs for the Android rules."""
+
+load(":path.bzl", _path = "path")
+load(":utils.bzl", "log")
+
+_ANDROID_CONSTRAINT_MISSING_ERROR = (
+    "A list of constraints provided without the 'android' constraint."
+)
+
+def _segment_idx(path_segments):
+    """Finds the index of the segment in the path that preceeds the source root.
+
+    Args:
+      path_segments: A list of strings, where each string is the segment of a
+        filesystem path.
+
+    Returns:
+      An index to the path segment that represents the Java segment or -1 if
+      none found.
+    """
+    if _path.is_absolute(path_segments[0]):
+        log.error("path must not be absolute: %s" % _path.join(path_segments))
+
+    root_idx = -1
+    for idx, segment in enumerate(path_segments):
+        if segment in ["java", "javatests", "src", "testsrc"]:
+            root_idx = idx
+            break
+    if root_idx < 0:
+        return root_idx
+
+    is_src = path_segments[root_idx] == "src"
+    check_maven_idx = root_idx if is_src else -1
+    if root_idx == 0 or is_src:
+        # Check for a nested root directory.
+        for idx in range(root_idx + 1, len(path_segments) - 2):
+            segment = path_segments[idx]
+            if segment == "src" or (is_src and segment in ["java", "javatests"]):
+                next_segment = path_segments[idx + 1]
+                if next_segment in ["com", "org", "net"]:
+                    root_idx = idx
+                elif segment == "src":
+                    check_maven_idx = idx
+                break
+
+    if check_maven_idx >= 0 and check_maven_idx + 2 < len(path_segments):
+        next_segment = path_segments[check_maven_idx + 1]
+        if next_segment in ["main", "test"]:
+            next_segment = path_segments[check_maven_idx + 2]
+            if next_segment in ["java", "resources"]:
+                root_idx = check_maven_idx + 2
+    return root_idx
+
+def _resolve_package(path):
+    """Determines the Java package name from the given path.
+
+    Examples:
+        "{workspace}/java/foo/bar/wiz" -> "foo.bar.wiz"
+        "{workspace}/javatests/foo/bar/wiz" -> "foo.bar.wiz"
+
+    Args:
+      path: A string, representing a file path.
+
+    Returns:
+      A string representing a Java package name or None if could not be
+      determined.
+    """
+    path_segments = _path.split(path.partition(":")[0])
+    java_idx = _segment_idx(path_segments)
+    if java_idx < 0:
+        return None
+    else:
+        return ".".join(path_segments[java_idx + 1:])
+
+def _resolve_package_from_label(
+        label,
+        custom_package = None,
+        fallback = True):
+    """Resolves the Java package from a Label.
+
+    When no legal Java package can be resolved from the label, None will be
+    returned unless fallback is specified.
+
+    When a fallback is requested, a not safe for Java compilation package will
+    be returned. The fallback value will be derrived by taking the label.package
+    and replacing all path separators with ".".
+    """
+    if custom_package:
+        return custom_package
+
+    # For backwards compatibility, also include directories
+    # from the label's name
+    # Ex: "//foo/bar:java/com/google/baz" is a legal one and
+    # results in "com.google"
+    label_path = _path.join(
+        [label.package] +
+        _path.split(label.name)[:-1],
+    )
+    java_package = _resolve_package(label_path)
+
+    if java_package != None:  # "" is a valid result.
+        return java_package
+
+    if fallback:
+        return label.package.replace("/", ".")
+
+    return None
+
+def _root(path):
+    """Determines the Java root from the given path.
+
+    Examples:
+        "{workspace}/java/foo/bar/wiz" -> "{workspace}/java"
+        "{workspace}/javatests/foo/bar/wiz" -> "{workspace}/javatests"
+        "java/foo/bar/wiz" -> "java"
+        "javatests/foo/bar/wiz" -> "javatests"
+
+    Args:
+      path: A string, representing a file path.
+
+    Returns:
+      A string representing the Java root path or None if could not be
+      determined.
+    """
+    path_segments = _path.split(path.partition(":")[0])
+    java_idx = _segment_idx(path_segments)
+    if java_idx < 0:
+        return None
+    else:
+        return _path.join(path_segments[0:java_idx + 1])
+
+def _check_for_invalid_java_package(java_package):
+    return "-" in java_package or len(java_package.split(".")) < 2
+
+def _invalid_java_package(custom_package, java_package):
+    """Checks if the given java package is invalid.
+
+    Only checks if either custom_package or java_package contains the
+    illegal character "-" or if they are composed of only one word.
+    Only checks java_package if custom_package is an empty string or None.
+
+    Args:
+      custom_package: string. Java package given as an attribute to a rule to override
+      the java_package.
+      java_package: string. Java package inferred from the directory where the BUILD
+      containing the rule is.
+
+    Returns:
+      A boolean. True if custom_package or java_package contains "-" or is only one word.
+      Only checks java_package if custom_package is an empty string or None.
+    """
+    return (
+        (custom_package and _check_for_invalid_java_package(custom_package)) or
+        (not custom_package and _check_for_invalid_java_package(java_package))
+    )
+
+# The Android specific Java compile.
+def _compile_android(
+        ctx,
+        output_jar,
+        output_srcjar = None,
+        srcs = [],
+        resources = [],
+        javac_opts = [],
+        r_java = None,
+        deps = [],
+        exports = [],
+        plugins = [],
+        exported_plugins = [],
+        annotation_processor_additional_outputs = [],
+        annotation_processor_additional_inputs = [],
+        enable_deps_without_srcs = False,
+        neverlink = False,
+        constraints = ["android"],
+        strict_deps = "Error",
+        java_toolchain = None):
+    """Compiles the Java and IDL sources for Android.
+
+    Args:
+      ctx: The context.
+      output_jar: File. The artifact to place the compilation unit.
+      output_srcjar: File. The artifact to place the sources of the compilation
+        unit. Optional.
+      srcs: sequence of Files. A list of files and jars to be compiled.
+      resources: sequence of Files. Will be added to the output jar - see
+        java_library.resources. Optional.
+      javac_opts: sequence of strings. A list of the desired javac options.
+        Optional.
+      r_java: JavaInfo. The R.jar dependency. Optional.
+      deps: sequence of JavaInfo providers. A list of dependencies. Optional.
+      exports: sequence of JavaInfo providers. A list of exports. Optional.
+      plugins: sequence of JavaInfo providers. A list of plugins. Optional.
+      exported_plugins: sequence of JavaInfo providers. A list of exported
+        plugins. Optional.
+      annotation_processor_additional_outputs: sequence of Files. A list of
+        files produced by an annotation processor.
+      annotation_processor_additional_inputs: sequence of Files. A list of
+        files consumed by an annotation processor.
+      enable_deps_without_srcs: Enables the behavior from b/14473160.
+      neverlink: Bool. Makes the compiled unit a compile-time only dependency.
+      constraints: sequence of Strings. A list of constraints, to constrain the
+        target. Optional. By default [].
+      strict_deps: string. A string that specifies how to handle strict deps.
+        Possible values: 'OFF', 'ERROR','WARN' and 'DEFAULT'. For more details
+        see https://docs.bazel.build/versions/master/user-manual.html#flag--strict_java_deps.
+        By default 'ERROR'.
+      java_toolchain: The java_toolchain Target.
+      host_javabase: The host_javabase Target.
+
+    Returns:
+      A JavaInfo provider representing the Java compilation.
+    """
+    if "android" not in constraints:
+        log.error(_ANDROID_CONSTRAINT_MISSING_ERROR)
+
+    if not srcs:
+        if deps and enable_deps_without_srcs:
+            # TODO(b/122039567): Produces a JavaInfo that exports the deps, but
+            # not the plugins. To reproduce the "deps without srcs" bug,
+            # b/14473160, behavior in Starlark.
+            exports = exports + [
+                android_common.enable_implicit_sourceless_deps_exports_compatibility(dep)
+                for dep in deps
+            ]
+        if not exports:
+            # Add a "no-op JavaInfo" to propagate the exported_plugins when
+            # deps or exports have not been specified by the target and
+            # additionally forces java_common.compile method to create the
+            # empty output jar and srcjar when srcs have not been specified.
+            noop_java_info = java_common.merge([])
+            exports = exports + [noop_java_info]
+
+    r_java_info = [r_java] if r_java else []
+
+    java_info = _compile(
+        ctx,
+        output_jar,
+        output_srcjar = output_srcjar,
+        srcs = srcs,
+        resources = resources,
+        javac_opts = javac_opts,
+        deps = r_java_info + deps,
+        # In native, the JavaInfo exposes two Jars as compile-time deps, the
+        # compiled sources and the Android R.java jars. To simulate this
+        # behavior, the JavaInfo of the R.jar is also exported.
+        exports = r_java_info + exports,
+        plugins = plugins,
+        exported_plugins = exported_plugins,
+        annotation_processor_additional_outputs = (
+            annotation_processor_additional_outputs
+        ),
+        annotation_processor_additional_inputs = (
+            annotation_processor_additional_inputs
+        ),
+        neverlink = neverlink,
+        constraints = constraints,
+        strict_deps = strict_deps,
+        java_toolchain = java_toolchain,
+    )
+    return java_info
+
+def _compile(
+        ctx,
+        output_jar,
+        output_srcjar = None,
+        srcs = [],
+        resources = [],
+        javac_opts = [],
+        deps = [],
+        exports = [],
+        plugins = [],
+        exported_plugins = [],
+        annotation_processor_additional_outputs = [],
+        annotation_processor_additional_inputs = [],
+        neverlink = False,
+        constraints = [],
+        strict_deps = "Error",
+        java_toolchain = None):
+    """Compiles the Java and IDL sources for Android.
+
+    Args:
+      ctx: The context.
+      output_jar: File. The artifact to place the compilation unit.
+      output_srcjar: File. The artifact to place the sources of the compilation
+        unit. Optional.
+      srcs: sequence of Files. A list of files and jars to be compiled.
+      resources: sequence of Files. Will be added to the output jar - see
+        java_library.resources. Optional.
+      javac_opts: sequence of strings. A list of the desired javac options.
+        Optional.
+      deps: sequence of JavaInfo providers. A list of dependencies. Optional.
+      exports: sequence of JavaInfo providers. A list of exports. Optional.
+      plugins: sequence of JavaInfo providers. A list of plugins. Optional.
+      exported_plugins: sequence of JavaInfo providers. A list of exported
+        plugins. Optional.
+      annotation_processor_additional_outputs: sequence of Files. A list of
+        files produced by an annotation processor.
+      annotation_processor_additional_inputs: sequence of Files. A list of
+        files consumed by an annotation processor.
+      resources: sequence of Files. Will be added to the output jar - see
+        java_library.resources. Optional.
+      neverlink: Bool. Makes the compiled unit a compile-time only dependency.
+      constraints: sequence of Strings. A list of constraints, to constrain the
+        target. Optional. By default [].
+      strict_deps: string. A string that specifies how to handle strict deps.
+        Possible values: 'OFF', 'ERROR','WARN' and 'DEFAULT'. For more details
+        see https://docs.bazel.build/versions/master/user-manual.html#flag--strict_java_deps.
+        By default 'ERROR'.
+      java_toolchain: The java_toolchain Target.
+      host_javabase: The host_javabase Target.
+
+    Returns:
+      A JavaInfo provider representing the Java compilation.
+    """
+
+    # Split javac opts.
+    opts = []
+    for opt in javac_opts:
+        opts.extend(opt.split(" "))
+
+    # Separate the sources *.java from *.srcjar.
+    source_files = []
+    source_jars = []
+    for src in srcs:
+        if src.path.endswith(".srcjar"):
+            source_jars.append(src)
+        else:
+            source_files.append(src)
+
+    return java_common.compile(
+        ctx,
+        output = output_jar,
+        output_source_jar = output_srcjar,
+        source_files = source_files,
+        source_jars = source_jars,
+        resources = resources,
+        javac_opts = opts,
+        deps = deps,
+        exports = exports,
+        plugins = plugins,
+        exported_plugins = exported_plugins,
+        annotation_processor_additional_outputs = (
+            annotation_processor_additional_outputs
+        ),
+        annotation_processor_additional_inputs = (
+            annotation_processor_additional_inputs
+        ),
+        neverlink = neverlink,
+        strict_deps = strict_deps,
+        java_toolchain = java_toolchain[java_common.JavaToolchainInfo],
+    )
+
+def _singlejar(
+        ctx,
+        inputs,
+        output,
+        mnemonic = "SingleJar",
+        progress_message = "Merge into a single jar.",
+        exclude_build_data = False,
+        java_toolchain = None):
+    args = ctx.actions.args()
+    args.add("--output")
+    args.add(output)
+    args.add("--compression")
+    args.add("--normalize")
+    if exclude_build_data:
+        args.add("--exclude_build_data")
+    args.add("--warn_duplicate_resources")
+    if inputs:
+        args.add("--sources")
+        args.add_all(inputs)
+
+    ctx.actions.run(
+        executable = java_toolchain.java_toolchain.single_jar,
+        arguments = [args],
+        inputs = inputs,
+        outputs = [output],
+        mnemonic = mnemonic,
+        progress_message = progress_message,
+    )
+
+def _run(
+        ctx,
+        host_javabase,
+        **args):
+    """Run a java binary
+
+    Args:
+      ctx: The context.
+      host_javabase: Target. The host_javabase.
+      **args: Additional arguments to pass to ctx.actions.run(). Some will get modified.
+    """
+
+    if type(ctx) != "ctx":
+        fail("Expected type ctx for argument ctx, got %s" % type(ctx))
+
+    if type(host_javabase) != "Target":
+        fail("Expected type Target for argument host_javabase, got %s" % type(host_javabase))
+
+    # executable should be a File or a FilesToRunProvider
+    jar = args.get("executable")
+    if type(jar) == "FilesToRunProvider":
+        jar = jar.executable
+    elif type(jar) != "File":
+        fail("Expected type File or FilesToRunProvider for argument executable, got %s" % type(jar))
+
+    java_runtime = host_javabase[java_common.JavaRuntimeInfo]
+    args["executable"] = java_runtime.java_executable_exec_path
+
+    # inputs can be a list or a depset of File
+    inputs = args.get("inputs", default = [])
+    if type(inputs) == type([]):
+        args["inputs"] = depset(direct = inputs + [jar], transitive = [java_runtime.files])
+    else:  # inputs is a depset
+        args["inputs"] = depset(direct = [jar], transitive = [inputs, java_runtime.files])
+
+    jar_args = ctx.actions.args()
+    jar_args.add("-jar", jar)
+
+    args["arguments"] = [jar_args] + args.get("arguments", default = [])
+
+    ctx.actions.run(**args)
+
+java = struct(
+    compile = _compile,
+    compile_android = _compile_android,
+    resolve_package = _resolve_package,
+    resolve_package_from_label = _resolve_package_from_label,
+    root = _root,
+    invalid_java_package = _invalid_java_package,
+    run = _run,
+    singlejar = _singlejar,
+)
diff --git a/rules/migration_tag_DONOTUSE.bzl b/rules/migration_tag_DONOTUSE.bzl
new file mode 100644
index 0000000..539aca9
--- /dev/null
+++ b/rules/migration_tag_DONOTUSE.bzl
@@ -0,0 +1,25 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel component for the Android Skylark Migration."""
+
+_MIGRATION_TAG = "__ANDROID_RULES_MIGRATION__"
+_TAG_ATTR = "tags"
+
+def add_migration_tag(attrs):
+    if _TAG_ATTR in attrs and attrs[_TAG_ATTR] != None:
+        attrs[_TAG_ATTR] = attrs[_TAG_ATTR] + [_MIGRATION_TAG]
+    else:
+        attrs[_TAG_ATTR] = [_MIGRATION_TAG]
+    return attrs
diff --git a/rules/path.bzl b/rules/path.bzl
new file mode 100644
index 0000000..28d18f1
--- /dev/null
+++ b/rules/path.bzl
@@ -0,0 +1,102 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel Path APIs for the Android rules."""
+
+# TODO(djwhang): Get the path separator in a platform agnostic manner.
+_PATH_SEP = "/"
+_TEST_SRCDIR = "${TEST_SRCDIR}"
+
+def _is_absolute(path):
+    # TODO(djwhang): This is not cross platform safe. Windows absolute paths
+    # do not start with "//", rather "C:\".
+    return path.startswith(_PATH_SEP)
+
+def _split(path):
+    return path.split(_PATH_SEP)
+
+def _join(path_segments):
+    return _PATH_SEP.join(path_segments)
+
+def _normalize_path(path, posix = False):
+    return _PATH_SEP.join(
+        _normalize_path_fragments(
+            path.split(_PATH_SEP),
+            posix = posix,
+        ),
+    )
+
+def _normalize_path_fragments(path_fragments, posix = False):
+    normalized_path_fragments = []
+    for idx, fragment in enumerate(path_fragments):
+        if not fragment and idx > 0:
+            continue
+        if fragment == ".":
+            continue
+        if fragment == ".." and not posix:
+            if normalized_path_fragments:
+                last = normalized_path_fragments.pop()
+                if last == ".." or last == "":
+                    normalized_path_fragments.append(last)
+                else:
+                    continue
+        normalized_path_fragments.append(fragment)
+    if len(normalized_path_fragments) == 1 and not normalized_path_fragments[0]:
+        normalized_path_fragments.append("")
+    return normalized_path_fragments
+
+def _relative_path(path1, path2):
+    if not path1 or _is_absolute(path2):
+        return path2
+
+    path1_fragments = _normalize_path_fragments(_split(path1))
+    path2_fragments = _normalize_path_fragments(_split(path2))
+    path1_idx = len(path1_fragments)  # index move backwards
+    path2_idx = -1
+    for idx, fragment in enumerate(path2_fragments):
+        if fragment == "..":
+            path1_idx -= 1
+        else:
+            path2_idx = idx
+            break
+
+    relative_path_fragments = []
+    if path1_idx >= 0:
+        relative_path_fragments.extend(path1_fragments[:path1_idx])
+    if path2_idx >= 0:
+        relative_path_fragments.extend(path2_fragments[path2_idx:])
+    return _join(_normalize_path_fragments(relative_path_fragments))
+
+def _make_test_srcdir_path(ctx, *path_fragments):
+    """Creates a filepath relative to TEST_SRCDIR.
+
+    Args:
+        ctx: Starlark context.
+        *path_fragments: Directories/file to join into a single path.
+    Returns:
+        A filepath that's spearated by the host's filepath separator.
+    """
+    fragments = [_TEST_SRCDIR, ctx.workspace_name]
+    for path_fragment in path_fragments:
+        fragments += _normalize_path_fragments(_split(path_fragment))
+    return _join(fragments)
+
+path = struct(
+    is_absolute = _is_absolute,
+    join = _join,
+    normalize = _normalize_path,
+    relative = _relative_path,
+    split = _split,
+    make_test_srcdir_path = _make_test_srcdir_path,
+)
diff --git a/rules/platforms/BUILD b/rules/platforms/BUILD
new file mode 100644
index 0000000..778c849
--- /dev/null
+++ b/rules/platforms/BUILD
@@ -0,0 +1,33 @@
+package(default_visibility = ["//visibility:public"])
+
+platform(
+	name = "armeabi_v7a",
+	constraint_values = [
+		"@platforms//cpu:armv7",
+		"@platforms//os:android",
+	],
+)
+
+platform(
+	name = "arm64-v8a",
+	constraint_values = [
+		"@platforms//cpu:arm64",
+		"@platforms//os:android",
+	],
+)
+
+platform(
+	name = "x86",
+	constraint_values = [
+		"@platforms//cpu:x86_32",
+		"@platforms//os:android",
+	],
+)
+
+platform(
+	name = "x86_64",
+	constraint_values = [
+		"@platforms//cpu:x86_64",
+		"@platforms//os:android",
+	],
+)
diff --git a/rules/processing_pipeline.bzl b/rules/processing_pipeline.bzl
new file mode 100644
index 0000000..6ba2ae7
--- /dev/null
+++ b/rules/processing_pipeline.bzl
@@ -0,0 +1,161 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Common implementation for processing pipelines."""
+
+PROVIDERS = "providers"
+VALIDATION_OUTPUTS = "validation_outputs"
+
+# TODO(djwhang): When a provider type can be retrieved from a Starlark provider
+# ProviderInfo is necessary. Once this is possible, processor methods can have a
+# uniform method signature foo(ctx, target_ctx) where we can pull the provider
+# off the target_ctx using the provider type.
+#
+# Yes, this effectively leads to producing a build rule like system within a
+# build rule, rather than resorting to rule based composition.
+ProviderInfo = provider(
+    "Stores metadata about the actual Starlark provider returned.",
+    fields = dict(
+        name = "The type of the provider",
+        value = "The actual provider",
+        runfiles = "Runfiles to pass to the DefaultInfo provider",
+    ),
+)
+
+_ProcessingPipelineInfo = provider(
+    "Stores functions that forms a rule's implementation.",
+    fields = dict(
+        processors = "Ordered dictionary of processing functions.",
+        finalize = "Function to form the final providers to propagate.",
+    ),
+)
+
+def _make_processing_pipeline(processors = dict(), finalize = None):
+    """Creates the combined processing pipeline.
+
+    Args:
+      processors: Ordered dictionary of processing functions.
+      finalize: Function to form the final providers to propagate.
+
+    Returns:
+      A _ProcessingPipelineInfo provider.
+    """
+    return _ProcessingPipelineInfo(
+        processors = processors,
+        finalize = finalize,
+    )
+
+def _run(ctx, java_package, processing_pipeline):
+    """Runs the processing pipeline and populates the target context.
+
+    Args:
+      ctx: The context.
+      java_package: The java package resolved from the target's path
+        or the custom_package attr.
+      processing_pipeline: The _ProcessingPipelineInfo provider for this target.
+
+    Returns:
+      The output of the _ProcessingPipelineInfo.finalize function.
+    """
+    target_ctx = dict(
+        java_package = java_package,
+        providers = [],
+        validation_outputs = [],
+        runfiles = ctx.runfiles(),
+    )
+
+    for execute in processing_pipeline.processors.values():
+        info = execute(ctx, **target_ctx)
+        if info:
+            if info.name in target_ctx:
+                fail("%s provider already registered in target context" % info.name)
+            target_ctx[info.name] = info.value
+            target_ctx[PROVIDERS].extend(getattr(info.value, PROVIDERS, []))
+            target_ctx[VALIDATION_OUTPUTS].extend(getattr(info.value, VALIDATION_OUTPUTS, []))
+            if hasattr(info, "runfiles") and info.runfiles:
+                target_ctx["runfiles"] = target_ctx["runfiles"].merge(info.runfiles)
+
+    return processing_pipeline.finalize(ctx, **target_ctx)
+
+def _prepend(processors, **new_processors):
+    """Prepends processors in a given processing pipeline.
+
+    Args:
+      processors: The dictionary representing the processing pipeline.
+      **new_processors: The processors to add where the key represents the
+        name of the processor and value is the function pointer to the new
+        processor.
+
+    Returns:
+      A dictionary which represents the new processing pipeline.
+    """
+    updated_processors = dict()
+    for name, processor in new_processors.items():
+        updated_processors[name] = processor
+
+    for key in processors.keys():
+        updated_processors[key] = processors[key]
+
+    return updated_processors
+
+def _append(processors, **new_processors):
+    """Appends processors in a given processing pipeline.
+
+    Args:
+      processors: The dictionary representing the processing pipeline.
+      **new_processors: The processors to append where the key represents the
+        name of the processor and value is the function pointer to the new
+        processor.
+
+    Returns:
+      A dictionary which represents the new processing pipeline.
+    """
+    updated_processors = dict(processors)
+    for name, processor in new_processors.items():
+        updated_processors[name] = processor
+
+    return updated_processors
+
+def _replace(processors, **new_processors):
+    """Replace processors in a given processing pipeline.
+
+    Args:
+      processors: The dictionary representing the processing pipeline.
+      **new_processors: The processors to override where the key represents the
+        name of the processor and value is the function pointer to the new
+        processor.
+
+    Returns:
+      A dictionary which represents the new processing pipeline.
+    """
+    updated_processors = dict(processors)
+    for name, processor in new_processors.items():
+        if name not in processors:
+            fail("Error, %s not found, unable to override." % name)
+
+        # NOTE: Overwriting an existing value does not break iteration order.
+        # However, if a new processor is being added that needs to be injected
+        # between other processors, the processing pipeline dictionary will need
+        # to be recreated.
+        updated_processors[name] = processor
+
+    return updated_processors
+
+processing_pipeline = struct(
+    make_processing_pipeline = _make_processing_pipeline,
+    run = _run,
+    prepend = _prepend,
+    append = _append,
+    replace = _replace,
+)
diff --git a/rules/proguard.bzl b/rules/proguard.bzl
new file mode 100644
index 0000000..837d622
--- /dev/null
+++ b/rules/proguard.bzl
@@ -0,0 +1,110 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel Android Proguard library for the Android rules."""
+
+_ProguardContextInfo = provider(
+    doc = "Contains data from processing Proguard specs.",
+    fields = dict(
+        proguard_configs = "The direct proguard configs",
+        transitive_proguard_configs =
+            "The proguard configs within the transitive closure of the target",
+        providers = "The list of all providers to propagate.",
+    ),
+)
+
+def _validate_proguard_spec(
+        ctx,
+        out_validated_proguard_spec,
+        proguard_spec,
+        proguard_allowlister):
+    args = ctx.actions.args()
+    args.add("--path", proguard_spec)
+    args.add("--output", out_validated_proguard_spec)
+
+    ctx.actions.run(
+        executable = proguard_allowlister,
+        arguments = [args],
+        inputs = [proguard_spec],
+        outputs = [out_validated_proguard_spec],
+        mnemonic = "ValidateProguard",
+        progress_message = (
+            "Validating proguard configuration %s" % proguard_spec.short_path
+        ),
+    )
+
+def _process(
+        ctx,
+        proguard_configs = [],
+        proguard_spec_providers = [],
+        proguard_allowlister = None):
+    """Processes Proguard Specs
+
+    Args:
+      ctx: The context.
+      proguard_configs: sequence of Files. A list of proguard config files to be
+        processed. Optional.
+      proguard_spec_providers: sequence of ProguardSpecProvider providers. A
+        list of providers from the dependencies, exports, plugins,
+        exported_plugins, etc. Optional.
+      proguard_allowlister: The proguard_allowlister exeutable provider.
+
+    Returns:
+      A _ProguardContextInfo provider.
+    """
+
+    # TODO(djwhang): Look to see if this can be just a validation action and the
+    # proguard_spec provided by the rule can be propagated.
+    validated_proguard_configs = []
+    for proguard_spec in proguard_configs:
+        validated_proguard_spec = ctx.actions.declare_file(
+            "validated_proguard/%s/%s_valid" %
+            (ctx.label.name, proguard_spec.path),
+        )
+        _validate_proguard_spec(
+            ctx,
+            validated_proguard_spec,
+            proguard_spec,
+            proguard_allowlister,
+        )
+        validated_proguard_configs.append(validated_proguard_spec)
+
+    transitive_validated_proguard_configs = []
+    for info in proguard_spec_providers:
+        transitive_validated_proguard_configs.append(info.specs)
+
+    transitive_proguard_configs = depset(
+        validated_proguard_configs,
+        transitive = transitive_validated_proguard_configs,
+        order = "preorder",
+    )
+    return _ProguardContextInfo(
+        proguard_configs = proguard_configs,
+        transitive_proguard_configs = transitive_proguard_configs,
+        providers = [
+            ProguardSpecProvider(transitive_proguard_configs),
+            # TODO(b/152659272): Remove this once the android_archive rule is
+            # able to process a transitive closure of deps to produce an aar.
+            AndroidProguardInfo(proguard_configs),
+        ],
+    )
+
+proguard = struct(
+    process = _process,
+)
+
+testing = struct(
+    validate_proguard_spec = _validate_proguard_spec,
+    ProguardContextInfo = _ProguardContextInfo,
+)
diff --git a/rules/providers.bzl b/rules/providers.bzl
new file mode 100644
index 0000000..fd92708
--- /dev/null
+++ b/rules/providers.bzl
@@ -0,0 +1,118 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel providers for Android rules."""
+
+
+
+AndroidAppsInfo = provider(
+    doc = "Provides information about app to install.",
+    fields = dict(
+        apps = "List of app provider artifacts.",
+    ),
+)
+
+
+
+
+
+
+
+
+AndroidJavaInfo = provider(
+    doc = "Provides outputs for the Android Java Compilation",
+    fields = dict(
+        aidl = "AndroidIdlInfo",
+        aide = "AndroidIdeInfo",
+        java = "JavaInfo",
+    ),
+)
+
+AndroidFilteredJdepsInfo = provider(
+    doc = "Provides a filtered jdeps proto.",
+    fields = dict(
+        jdeps = "Filtered jdeps",
+    ),
+)
+
+
+StarlarkApkInfo = provider(
+    doc = "Provides APK outputs of a rule.",
+    fields = dict(
+        keystore = "Keystore used to sign the APK. Deprecated, prefer signing_keys.",
+        signing_keys = "List of keys used to sign the APK",
+        signing_lineage = "Optional sigining lineage file",
+        signed_apk = "Signed APK",
+        unsigned_apk = "Unsigned APK",
+    ),
+)
+
+ResourcesNodeInfo = provider(
+    doc = "Provides information for building ResourceProcessorBusyBox flags",
+    fields = dict(
+        label = "A label, the target's label",
+
+        # Assets related fields
+        assets = "A depset of files, assets files of the target",
+        assets_dir = "A string, the name of the assets directory",
+        assets_symbols = "A file, the merged assets",
+        compiled_assets = "A file, the compiled assets",
+
+        # Resource related fields
+        resource_files = "A depset of files, resource files of the target",
+        compiled_resources = "A file, the compiled resources",
+        r_txt = "A file, the R.txt file",
+        manifest = "A file, the AndroidManifest.xml",
+        # TODO(ostonge): Add the manifest if it's exported, otherwise leave empty
+        exports_manifest = "Boolean, whether the manifest is exported",
+    ),
+)
+
+StarlarkAndroidResourcesInfo = provider(
+    doc = "Provides information about direct and transitive resources",
+    fields = dict(
+        direct_resources_nodes = "Depset of ResourcesNodeInfo providers, can contain multiple providers due to exports",
+        transitive_resources_nodes = "Depset of transitive ResourcesNodeInfo providers, not including directs",
+        transitive_assets = "Depset of transitive assets files",
+        transitive_assets_symbols = "Depset of transitive merged assets",
+        transitive_compiled_assets = "Depset of transitive compiled assets",
+        direct_compiled_resources = "Depset of direct compiled_resources, can contain multiple files due to exports",
+        transitive_compiled_resources = "Depset of transitive compiled resources",
+        transitive_manifests = "Depset of transitive manifests",
+        transitive_r_txts = "Depset of transitive R.txt files",
+        transitive_resource_files = "Depset of transitive resource files",
+    ),
+)
+
+AndroidLintRulesInfo = provider(
+    doc = "Provides extra lint rules to use with AndroidLint.",
+    fields = dict(
+        lint_jar = "A file, a lint jar found in an aar.",
+    ),
+)
+
+
+
+FailureInfo = provider(
+    fields = dict(
+        error = "Error message",
+    ),
+)
+
+AndroidBundleInfo = provider(
+    doc = "Provides .aab outputs from a rule.",
+    fields = dict(
+        unsigned_aab = "File, the unsigned .aab",
+    ),
+)
diff --git a/rules/res_v3_dummy_AndroidManifest.xml b/rules/res_v3_dummy_AndroidManifest.xml
new file mode 100644
index 0000000..8072ee0
--- /dev/null
+++ b/rules/res_v3_dummy_AndroidManifest.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest />
diff --git a/rules/res_v3_dummy_R.txt b/rules/res_v3_dummy_R.txt
new file mode 100644
index 0000000..2b3d8b7
--- /dev/null
+++ b/rules/res_v3_dummy_R.txt
@@ -0,0 +1 @@
+int string fake 0x00000000
diff --git a/rules/resources.bzl b/rules/resources.bzl
new file mode 100644
index 0000000..386196d
--- /dev/null
+++ b/rules/resources.bzl
@@ -0,0 +1,1638 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Bazel Android Resources."""
+
+load(":attrs.bzl", _attrs = "attrs")
+load(":busybox.bzl", _busybox = "busybox")
+load(":common.bzl", _common = "common")
+load(":java.bzl", _java = "java")
+load(":path.bzl", _path = "path")
+load(
+    ":providers.bzl",
+    "ResourcesNodeInfo",
+    "StarlarkAndroidResourcesInfo",
+)
+load(
+    ":utils.bzl",
+    "utils",
+    _compilation_mode = "compilation_mode",
+    _log = "log",
+)
+
+_RESOURCE_FOLDER_TYPES = [
+    "anim",
+    "animator",
+    "color",
+    "drawable",
+    "font",
+    "interpolator",
+    "layout",
+    "menu",
+    "mipmap",
+    "navigation",
+    "values",
+    "xml",
+    "raw",
+    "transition",
+]
+
+_RESOURCE_QUALIFIER_SEP = "-"
+
+_MANIFEST_MISSING_ERROR = (
+    "In target %s, manifest attribute is required when resource_files or " +
+    "assets are defined."
+)
+
+_ASSET_DEFINITION_ERROR = (
+    "In target %s, the assets and assets_dir attributes should be either " +
+    "both empty or non-empty."
+)
+
+_JAVA_PACKAGE_MISSING_ERROR = (
+    "In target %s, a java package is required when stamping " +
+    "the manifest."
+)
+
+_INCORRECT_RESOURCE_LAYOUT_ERROR = (
+    "'%s' is not in the expected resource directory structure of " +
+    "<resource directory>/{%s}/<file>" % (",").join(_RESOURCE_FOLDER_TYPES)
+)
+
+# Keys for manifest_values
+_VERSION_NAME = "versionName"
+_VERSION_CODE = "versionCode"
+
+# Resources context attributes.
+_ASSETS_PROVIDER = "assets_provider"
+_DEFINES_RESOURCES = "defines_resources"
+_DIRECT_ANDROID_RESOURCES = "direct_android_resources"
+_MERGED_MANIFEST = "merged_manifest"
+_PROVIDERS = "providers"
+_R_JAVA = "r_java"
+_RESOURCES_APK = "resources_apk"
+_VALIDATION_RESULTS = "validation_results"
+_VALIDATION_OUTPUTS = "validation_outputs"
+_RESOURCES_PROVIDER = "resources_provider"
+_STARLARK_PROCESSED_MANIFEST = "starlark_processed_manifest"
+_STARLARK_R_TXT = "starlark_r_txt"
+_STARLARK_PROCESSED_RESOURCES = "starlark_processed_resources"
+
+_ResourcesProcessContextInfo = provider(
+    "Resources context object",
+    fields = {
+        _DEFINES_RESOURCES: "If local resources were defined.",
+        _DIRECT_ANDROID_RESOURCES: "Direct android resources.",
+        _MERGED_MANIFEST: "Merged manifest.",
+        _PROVIDERS: "The list of all providers to propagate.",
+        _R_JAVA: "JavaInfo for R.jar.",
+        _RESOURCES_APK: "ResourcesApk.",
+        _VALIDATION_RESULTS: "List of validation results.",
+        _VALIDATION_OUTPUTS: "List of outputs given to OutputGroupInfo _validation group",
+
+        # TODO(djwhang): The android_library aar generation requires direct
+        # access to providers. Remove once aar is its own rule.
+        _ASSETS_PROVIDER: "AndroidAssetsInfo provider.",
+        _RESOURCES_PROVIDER: "AndroidResourcesInfo provider.",
+        _STARLARK_PROCESSED_MANIFEST: "The processed manifest from the starlark resource processing pipeline.",
+        _STARLARK_R_TXT: "The R.txt from the starlark resource processing pipeline.",
+        _STARLARK_PROCESSED_RESOURCES: "The processed resources from the starlark processing pipeline.",
+    },
+)
+
+# Packaged resources context attributes.
+_PACKAGED_FINAL_MANIFEST = "processed_manifest"
+_PACKAGED_RESOURCE_APK = "resources_apk"
+_PACKAGED_CLASS_JAR = "class_jar"
+_PACKAGED_VALIDATION_RESULT = "validation_result"
+
+_ResourcesPackageContextInfo = provider(
+    "Packaged resources context object",
+    fields = {
+        _PACKAGED_FINAL_MANIFEST: "Final processed manifest.",
+        _PACKAGED_RESOURCE_APK: "ResourceApk.",
+        _PACKAGED_CLASS_JAR: "R class jar.",
+        _PACKAGED_VALIDATION_RESULT: "Validation result.",
+        _R_JAVA: "JavaInfo for R.jar",
+        _PROVIDERS: "The list of all providers to propagate.",
+    },
+)
+
+def _generate_dummy_manifest(
+        ctx,
+        out_manifest = None,
+        java_package = None,
+        min_sdk_version = None):
+    content = """<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="%s">""" % java_package
+
+    if min_sdk_version:
+        content = content + """
+    <uses-sdk android:minSdkVersion="%s" />""" % min_sdk_version
+
+    content = content + """
+    <application>
+    </application>
+</manifest>"""
+
+    ctx.actions.write(
+        output = out_manifest,
+        content = content,
+    )
+
+def _add_g3itr(
+        ctx,
+        manifest = None,
+        out_manifest = None,
+        xsltproc = None,
+        instrument_xslt = None):
+    """Adds Google3InstrumentationTestRunner instrumentation element to the manifest.
+
+    Element is only added if the manifest contains an instrumentation element with
+    name "android.test.InstrumentationTestRunner". The added element's name attr is
+    "com.google.android.apps.common.testing.testrunner.Google3InstrumentationTestRunner".
+
+    Args:
+      ctx: The context.
+      manifest: File. The AndroidManifest.xml file.
+      out_manifest: File. The transformed AndroidManifest.xml.
+      xsltproc: FilesToRunProvider. The xsltproc executable or
+        FilesToRunProvider.
+      instrument_xslt: File. The add_g3itr.xslt file describing the xslt
+        transformation to apply.
+    """
+    args = ctx.actions.args()
+    args.add("--nonet")
+    args.add("--novalid")
+    args.add("-o", out_manifest)
+    args.add(instrument_xslt)
+    args.add(manifest)
+
+    ctx.actions.run(
+        executable = xsltproc,
+        arguments = [args],
+        inputs = [manifest, instrument_xslt],
+        outputs = [out_manifest],
+        mnemonic = "AddG3ITRStarlark",
+        progress_message = "Adding G3ITR to test manifest for %s" % ctx.label,
+    )
+
+def _get_legacy_mergee_manifests(resources_infos):
+    all_dependencies = depset(
+        transitive = [
+            ri.direct_android_resources
+            for ri in resources_infos
+        ] + [
+            ri.transitive_android_resources
+            for ri in resources_infos
+        ],
+    )
+
+    mergee_manifests = []
+    for dep in all_dependencies.to_list():
+        if dep.to_provider.manifest.exports_manifest:
+            mergee_manifests.append(dep.to_provider.manifest.manifest)
+
+    return depset(mergee_manifests)
+
+def _legacy_mergee_manifest(manifest):
+    sort_key = manifest.short_path + "#"
+    return sort_key + "--mergee=" + manifest.path
+
+def _legacy_merge_manifests(
+        ctx,
+        out_merged_manifest = None,
+        manifest = None,
+        mergee_manifests = None,
+        legacy_merger = None):
+    """Merges manifests with the legacy manifest merger."
+
+    This should not be called with empty mergee_manifests.
+
+    Args:
+      ctx: The context.
+      out_merged_manifest: File. The merged AndroidManifest.xml.
+      manifest: File. The AndroidManifest.xml.
+      mergee_manifests: A sequence of Files. All transitive manifests to be merged.
+      legacy_merger: A FilesToRunProvider. The legacy manifest merger executable.
+    """
+    args = ctx.actions.args()
+    args.use_param_file("%s", use_always = True)
+    args.set_param_file_format("multiline")
+    args.add("--merger=%s" % manifest.path)
+    args.add("--exclude_permission=all")
+    args.add("--output=%s" % out_merged_manifest.path)
+
+    manifest_params = ctx.actions.declare_file(ctx.label.name + "/legacy_merger.params")
+    manifest_args = ctx.actions.args()
+    manifest_args.use_param_file("%s", use_always = True)
+    manifest_args.set_param_file_format("multiline")
+    manifest_args.add_joined(mergee_manifests, map_each = _legacy_mergee_manifest, join_with = "\n")
+    ctx.actions.run_shell(
+        command = """
+# Sorts the mergee manifests by path and combines with other busybox args.
+set -e
+SORTED=`sort $1 | sed 's/^.*#//'`
+cat $2 > $3
+echo "$SORTED" >> $3
+""",
+        arguments = [manifest_args, args, manifest_params.path],
+        outputs = [manifest_params],
+    )
+    args = ctx.actions.args()
+    args.add(manifest_params, format = "--flagfile=%s")
+
+    ctx.actions.run(
+        executable = legacy_merger,
+        arguments = [args],
+        inputs = depset([manifest, manifest_params], transitive = [mergee_manifests]),
+        outputs = [out_merged_manifest],
+        mnemonic = "StarlarkLegacyAndroidManifestMerger",
+        progress_message = "Merging Android Manifests",
+    )
+
+def _make_databinding_outputs(
+        ctx,
+        resource_files):
+    """Helper method to create arguments for the process_databinding busybox tool.
+
+    Declares databinding-processed resource files that are generated by the
+    PROCESS_DATABINDING busybox tool, which must be declared underneath an output
+    resources directory and namespaced by their paths. The busybox takes the
+    output directory exec path and generates the underlying resource files.
+
+    Args:
+      ctx: The context.
+      resource_files: List of Files. The android resource files to be processed by
+        _process_databinding.
+
+    Returns:
+      A tuple containing the list of declared databinding processed resource files and the
+        output resource directory path expected by the busybox. The path is a full path.
+    """
+
+    # TODO(b/160907203): Clean up databinding_rel_path. We capitalize "Databinding" here to avoid
+    # conflicting with native artifact file names. This is changed back to "databinding" during
+    # process_starlark so that compiled resources exactly match those of the native resource
+    # processing pipeline. Even a single character mismatch in the file names causes selected
+    # resources to differ in the final APK.
+    databinding_rel_path = _path.join(["Databinding-processed-resources", ctx.label.name])
+    databinding_processed_resources = [
+        ctx.actions.declare_file(_path.join([databinding_rel_path, f.path]))
+        for f in resource_files
+    ]
+    databinding_resources_dirname = _path.join([
+        ctx.bin_dir.path,
+        ctx.label.package,
+        databinding_rel_path,
+    ])
+    return databinding_processed_resources, databinding_resources_dirname
+
+def _fix_databinding_compiled_resources(
+        ctx,
+        out_compiled_resources = None,
+        compiled_resources = None,
+        zip_tool = None):
+    """Fix compiled resources to match those produced by the native pipeline.
+
+    Changes "Databinding" to "databinding" in each compiled resource .flat file name and header.
+
+    Args:
+      ctx: The context.
+      out_compiled_resources: File. The modified compiled_resources output.
+      compiled_resources: File. The compiled_resources zip.
+    """
+    ctx.actions.run_shell(
+        outputs = [out_compiled_resources],
+        inputs = [compiled_resources],
+        tools = [zip_tool],
+        arguments = [compiled_resources.path, out_compiled_resources.path, zip_tool.executable.path],
+        command = """#!/bin/bash
+set -e
+
+IN_DIR=$(mktemp -d)
+OUT_DIR=$(mktemp -d)
+CUR_PWD=$(pwd)
+
+if zipinfo -t "$1"; then
+    ORDERED_LIST=`(unzip -l "$1" | sed -e '1,3d' | head -n -2 | tr -s " " | cut -d " " -f5)`
+
+    unzip -q "$1" -d "$IN_DIR"
+
+    # Iterate through the ordered list, change "Databinding" to "databinding" in the file header
+    # and file name and zip the files with the right comment
+    for FILE in $ORDERED_LIST; do
+        cd "$IN_DIR"
+        if [ -f "$FILE" ]; then
+            sed -i 's/Databinding\\-processed\\-resources/databinding\\-processed\\-resources/g' "$FILE"
+            NEW_NAME=`echo "$FILE" | sed 's/Databinding\\-processed\\-resources/databinding\\-processed\\-resources/g' | sed 's#'"$IN_DIR"'/##g'`
+            mkdir -p `dirname "$OUT_DIR/$NEW_NAME"` && touch "$OUT_DIR/$NEW_NAME"
+            cp -p "$FILE" "$OUT_DIR/$NEW_NAME"
+
+            PATH_SEGMENTS=(`echo ${FILE} | tr '/' ' '`)
+            BASE_PATH_SEGMENT="${PATH_SEGMENTS[0]}"
+                COMMENT=
+            if [ "${BASE_PATH_SEGMENT}" == "generated" ]; then
+                COMMENT="generated"
+            elif [ "${BASE_PATH_SEGMENT}" == "default" ]; then
+                COMMENT="default"
+            fi
+
+            cd "$OUT_DIR"
+            "$CUR_PWD/$3" -jt -X -0 -q -r -c "$CUR_PWD/$2" $NEW_NAME <<EOM
+${COMMENT}
+EOM
+        fi
+    done
+
+    cd "$CUR_PWD"
+    touch -r "$1" "$2"
+else
+    cp -p "$1" "$2"
+fi
+        """,
+    )
+
+def _is_resource_shrinking_enabled(
+        shrink_resources,
+        use_android_resource_shrinking):
+    if shrink_resources == _attrs.tristate.auto:
+        return use_android_resource_shrinking
+    return shrink_resources == _attrs.tristate.yes
+
+def _should_shrink_resource_cycles(
+        use_android_resource_cycle_shrinking,
+        resource_shrinking_enabled):
+    if use_android_resource_cycle_shrinking and not resource_shrinking_enabled:
+        fail("resource cycle shrinking can only be enabled when resource shrinking is enabled")
+    return use_android_resource_cycle_shrinking
+
+def _filter_multi_cpu_configuration_targets(
+        targets):
+    """Filter out duplicate split-configured targets.
+
+    This method simulates logic in the native rule where if a label_list attribute has
+    split-configuration but is requested in target mode, only targets from the first architecture
+    are returned. Without this filtering there are duplicate targets if multiple CPU configurations
+    are specified on the command line. This is the case with deps in the packaging step of
+    android_binary.
+
+    Args:
+      targets: A list of Target objects.
+
+    Returns:
+      A list of Target objects with duplicates removed.
+    """
+    seen_labels = {}
+    filtered_targets = []
+    for t in targets:
+        if t.label in seen_labels:
+            continue
+        seen_labels[t.label] = True
+        filtered_targets.append(t)
+    return filtered_targets
+
+def _package(
+        ctx,
+        assets = [],
+        assets_dir = None,
+        deps = [],
+        manifest = None,
+        manifest_values = None,
+        instruments = None,
+        resource_configs = None,
+        densities = [],
+        resource_files = [],
+        nocompress_extensions = [],
+        java_package = None,
+        compilation_mode = _compilation_mode.FASTBUILD,
+        shrink_resources = None,
+        use_android_resource_shrinking = None,
+        use_android_resource_cycle_shrinking = None,
+        use_legacy_manifest_merger = False,
+        should_throw_on_conflict = True,
+        enable_data_binding = False,
+        enable_manifest_merging = True,
+        aapt = None,
+        android_jar = None,
+        legacy_merger = None,
+        xsltproc = None,
+        instrument_xslt = None,
+        busybox = None,
+        host_javabase = None):
+    """Package resources for top-level rules.
+
+    Args:
+      ctx: The context.
+      assets: sequence of Files. A list of assets to be packaged. All files be
+        under the assets_dir directory in the corresponding package.
+      assets_dir: String. A string giving the path to the files in assets. The
+        pair assets and assets_dir describe packaged assets and either both
+        parameters should be provided or none of them.
+      deps: sequence of Targets. The list of other libraries targets to link
+        against.
+      manifest: File. The input top-level AndroidManifest.xml.
+      manifest_values: String dictionary. Manifest values to substitute.
+      instruments: Optional target. The value of the "instruments" attr if set.
+      resource_configs: sequence of Strings. A list of resource_configuration_filters
+        to apply.
+      densities: sequence of Strings. A list of densities to filter for when building
+        the apk.
+      resource_files: sequence of Files. A list of Android resource files
+        to be processed.
+      nocompress_extensions: sequence of Strings. File extension to leave uncompressed
+        in the apk.
+      java_package: String. Java package for which java sources will be
+        generated. By default the package is inferred from the directory where
+        the BUILD file containing the rule is.
+      compilation_mode: String. A string that represents compilation mode. The
+        list of expected values are as follows: dbg, fastbuild, opt.
+      shrink_resources: Tristate. Whether resource shrinking is enabled by the rule.
+      use_android_resource_shrinking: Bool. Flag that controls the default value for
+        shrink_resources if the tristate value is auto (-1).
+      use_android_resource_cycle_shrinking: Bool. Flag that enables more shrinking of
+        code and resources by instructing AAPT2 to emit conditional Proguard keep rules.
+      use_legacy_manifest_merger: A boolean. Whether to use the legacy manifest merger
+      instead of the android manifest merger.
+      should_throw_on_conflict: A boolean. Determines whether an error should be thrown
+        when a resource conflict occurs.
+      enable_data_binding: boolean. If true, processesing the data binding
+        expressions in layout resources included through the resource_files
+        parameter is enabled. Without this setting, data binding expressions
+        produce build failures.
+      enable_manifest_merging: boolean. If true, manifest merging will be performed.
+      aapt: FilesToRunProvider. The aapt executable or FilesToRunProvider.
+      android_jar: File. The Android jar.
+      legacy_merger: FilesToRunProvider. The legacy manifest merger executable.
+      xsltproc: FilesToRunProvider. The xsltproc executable or
+        FilesToRunProvider.
+      instrument_xslt: File. The add_g3itr.xslt file describing the xslt
+        transformation to apply.
+      busybox: FilesToRunProvider. The ResourceBusyBox executable or
+        FilesToRunprovider
+      host_javabase: A Target. The host javabase.
+
+    Returns:
+      A ResourcesPackageContextInfo containing packaged resource artifacts and
+        providers.
+    """
+    _validate_resources(resource_files)
+
+    # Filtering is necessary if a build is requested with multiple CPU configurations.
+    deps = _filter_multi_cpu_configuration_targets(deps)
+
+    packaged_resources_ctx = {
+        _PROVIDERS: [],
+    }
+
+    g3itr_manifest = manifest
+
+    if xsltproc or instrument_xslt:
+        g3itr_manifest = ctx.actions.declare_file(
+            "_migrated/" + ctx.label.name + "add_g3itr/AndroidManifest.xml",
+        )
+        _add_g3itr(
+            ctx,
+            out_manifest = g3itr_manifest,
+            manifest = manifest,
+            xsltproc = xsltproc,
+            instrument_xslt = instrument_xslt,
+        )
+
+    direct_resources_nodes = []
+    transitive_resources_nodes = []
+    transitive_assets = []
+    transitive_assets_symbols = []
+    transitive_compiled_assets = []
+    transitive_resource_files = []
+    transitive_compiled_resources = []
+    transitive_manifests = []
+    transitive_r_txts = []
+    for dep in utils.collect_providers(StarlarkAndroidResourcesInfo, deps):
+        direct_resources_nodes.append(dep.direct_resources_nodes)
+        transitive_resources_nodes.append(dep.transitive_resources_nodes)
+        transitive_assets.append(dep.transitive_assets)
+        transitive_assets_symbols.append(dep.transitive_assets_symbols)
+        transitive_compiled_assets.append(dep.transitive_compiled_assets)
+        transitive_resource_files.append(dep.transitive_resource_files)
+        transitive_compiled_resources.append(dep.transitive_compiled_resources)
+        transitive_manifests.append(dep.transitive_manifests)
+        transitive_r_txts.append(dep.transitive_r_txts)
+
+    mergee_manifests = depset([
+        node_info.manifest
+        for node_info in depset(transitive = transitive_resources_nodes + direct_resources_nodes).to_list()
+        if node_info.exports_manifest
+    ])
+
+    # TODO(b/156763506): Add analysis tests to verify logic around when manifest merging is configured.
+    # TODO(b/154153771): Run the android merger if mergee_manifests or manifest values are present.
+    merged_manifest = g3itr_manifest
+    if enable_manifest_merging and (manifest_values or mergee_manifests):
+        if use_legacy_manifest_merger:
+            # Legacy manifest merger only runs if mergee manifests are present
+            if mergee_manifests:
+                merged_manifest = ctx.actions.declare_file(
+                    "_migrated/_merged/" + ctx.label.name + "/AndroidManifest.xml",
+                )
+                _legacy_merge_manifests(
+                    ctx,
+                    out_merged_manifest = merged_manifest,
+                    manifest = g3itr_manifest,
+                    mergee_manifests = mergee_manifests,
+                    legacy_merger = legacy_merger,
+                )
+        else:
+            merged_manifest = ctx.actions.declare_file(
+                "_migrated/_merged/" + ctx.label.name + "/AndroidManifest.xml",
+            )
+            _busybox.merge_manifests(
+                ctx,
+                out_file = merged_manifest,
+                out_log_file = ctx.actions.declare_file(
+                    "_migrated/_merged/" + ctx.label.name + "/manifest_merger_log.txt",
+                ),
+                manifest = g3itr_manifest,
+                mergee_manifests = mergee_manifests,
+                manifest_values = manifest_values,
+                merge_type = "APPLICATION",
+                java_package = java_package,
+                busybox = busybox,
+                host_javabase = host_javabase,
+            )
+
+    processed_resources = resource_files
+    databinding_info = None
+    if enable_data_binding:
+        databinding_info = ctx.actions.declare_file("_migrated/databinding/" + ctx.label.name + "/layout-info.zip")
+        processed_resources, resources_dirname = _make_databinding_outputs(
+            ctx,
+            resource_files,
+        )
+        _busybox.process_databinding(
+            ctx,
+            out_databinding_info = databinding_info,
+            out_databinding_processed_resources = processed_resources,
+            databinding_resources_dirname = resources_dirname,
+            resource_files = resource_files,
+            java_package = java_package,
+            busybox = busybox,
+            host_javabase = host_javabase,
+        )
+
+    resource_apk = ctx.actions.declare_file(ctx.label.name + "_migrated/.ap_")
+    r_java = ctx.actions.declare_file("_migrated/" + ctx.label.name + ".srcjar")
+    r_txt = ctx.actions.declare_file(ctx.label.name + "_migrated/_symbols/R.txt")
+    processed_manifest = ctx.actions.declare_file(ctx.label.name + "_migrated/_processed_manifest/AndroidManifest.xml")
+    proguard_cfg = ctx.actions.declare_file(
+        "_migrated/proguard/%s/_%s_proguard.cfg" % (ctx.label.name, ctx.label.name),
+    )
+    main_dex_proguard_cfg = ctx.actions.declare_file(
+        "_migrated/proguard/%s/main_dex_%s_proguard.cfg" %
+        (ctx.label.name, ctx.label.name),
+    )
+    resource_files_zip = ctx.actions.declare_file(
+        "_migrated/" + ctx.label.name + "_files/resource_files.zip",
+    )
+    _busybox.package(
+        ctx,
+        out_file = resource_apk,
+        out_r_src_jar = r_java,
+        out_r_txt = r_txt,
+        out_symbols = ctx.actions.declare_file("_migrated/" + ctx.label.name + "_symbols/merged.bin"),
+        out_manifest = processed_manifest,
+        out_proguard_cfg = proguard_cfg,
+        out_main_dex_proguard_cfg = main_dex_proguard_cfg,
+        out_resource_files_zip = resource_files_zip,
+        application_id = manifest_values.get("applicationId", None),
+        manifest = merged_manifest,
+        assets = assets,
+        assets_dir = assets_dir,
+        resource_files = processed_resources,
+        direct_resources_nodes =
+            depset(transitive = direct_resources_nodes, order = "preorder"),
+        transitive_resources_nodes =
+            depset(transitive = transitive_resources_nodes, order = "preorder"),
+        transitive_assets = transitive_assets,
+        transitive_compiled_assets = transitive_compiled_assets,
+        transitive_resource_files = transitive_resource_files,
+        transitive_compiled_resources = transitive_compiled_resources,
+        transitive_manifests = transitive_manifests,
+        transitive_r_txts = transitive_r_txts,
+        resource_configs = resource_configs,
+        densities = densities,
+        nocompress_extensions = nocompress_extensions,
+        java_package = java_package,
+        version_name = manifest_values[_VERSION_NAME] if _VERSION_NAME in manifest_values else None,
+        version_code = manifest_values[_VERSION_CODE] if _VERSION_CODE in manifest_values else None,
+        android_jar = android_jar,
+        aapt = aapt,
+        busybox = busybox,
+        host_javabase = host_javabase,
+        debug = compilation_mode != _compilation_mode.OPT,
+        should_throw_on_conflict = should_throw_on_conflict,
+    )
+    packaged_resources_ctx[_PACKAGED_FINAL_MANIFEST] = processed_manifest
+    packaged_resources_ctx[_PACKAGED_RESOURCE_APK] = resource_apk
+    packaged_resources_ctx[_PACKAGED_VALIDATION_RESULT] = resource_files_zip
+
+    resource_shrinking_enabled = _is_resource_shrinking_enabled(
+        shrink_resources,
+        use_android_resource_shrinking,
+    )
+    shrink_resource_cycles = _should_shrink_resource_cycles(
+        use_android_resource_cycle_shrinking,
+        resource_shrinking_enabled,
+    )
+
+    # Fix class jar name because some tests depend on {label_name}_resources.jar being the suffix of
+    # the path, with _RESOURCES_DO_NOT_USE removed from the label name.
+    _RESOURCES_SUFFIX = "_RESOURCES_DO_NOT_USE"
+    class_jar_name = ctx.label.name + "_migrated/_resources.jar"
+    if ctx.label.name.endswith(_RESOURCES_SUFFIX):
+        label_name = ctx.label.name[:-len(_RESOURCES_SUFFIX)]
+        class_jar_name = ctx.label.name + "_migrated/" + label_name + "_resources.jar"
+
+    class_jar = ctx.actions.declare_file(class_jar_name)
+    _busybox.generate_binary_r(
+        ctx,
+        out_class_jar = class_jar,
+        r_txt = r_txt,
+        manifest = processed_manifest,
+        package_for_r = java_package,
+        final_fields = not shrink_resource_cycles and not instruments,
+        resources_nodes = depset(transitive = direct_resources_nodes + transitive_resources_nodes),
+        transitive_r_txts = transitive_r_txts,
+        transitive_manifests = transitive_manifests,
+        busybox = busybox,
+        host_javabase = host_javabase,
+    )
+    packaged_resources_ctx[_PACKAGED_CLASS_JAR] = class_jar
+
+    java_info = JavaInfo(
+        output_jar = class_jar,
+        compile_jar = class_jar,
+        source_jar = r_java,
+    )
+
+    packaged_resources_ctx[_R_JAVA] = java_info
+
+    packaged_resources_ctx[_PROVIDERS].append(AndroidApplicationResourceInfo(
+        resource_apk = resource_apk,
+        resource_java_src_jar = r_java,
+        resource_java_class_jar = class_jar,
+        manifest = processed_manifest,
+        resource_proguard_config = proguard_cfg,
+        main_dex_proguard_config = main_dex_proguard_cfg,
+        r_txt = r_txt,
+        resources_zip = resource_files_zip,
+        databinding_info = databinding_info,
+    ))
+    return _ResourcesPackageContextInfo(**packaged_resources_ctx)
+
+def _liteparse(ctx, out_r_pb, resource_files, android_kit):
+    """Creates an R.pb which contains the resource ids gotten from a light parse.
+
+    Args:
+      ctx: The context.
+      out_r_pb: File. The R.pb output file.
+      resource_files: List of Files. The list of resource files.
+      android_kit: FilesToRunProvider. The Android Kit executable or
+        FilesToRunProvider.
+    """
+    args = ctx.actions.args()
+    args.use_param_file(param_file_arg = "--flagfile=%s", use_always = True)
+    args.set_param_file_format("multiline")
+    args.add_joined("--res_files", resource_files, join_with = ",")
+    args.add("--out", out_r_pb)
+
+    ctx.actions.run(
+        executable = android_kit,
+        arguments = ["liteparse", args],
+        inputs = resource_files,
+        outputs = [out_r_pb],
+        mnemonic = "ResLiteParse",
+        progress_message = "Lite parse Android Resources %s" % ctx.label,
+    )
+
+def _fastr(ctx, r_pbs, package, manifest, android_kit):
+    """Create R.srcjar from the given R.pb files in the transitive closure.
+
+    Args:
+      ctx: The context.
+      r_pbs: Transitive  set of resource pbs.
+      package: The package name of the compile-time R.java.
+      manifest: File. The AndroidManifest.xml file.
+      android_kit: FilesToRunProvider. The Android Kit executable or
+        FilesToRunProvider.
+
+    Returns:
+      The output R source jar artifact.
+    """
+    inputs = r_pbs
+    r_srcjar = ctx.actions.declare_file(ctx.label.name + "/resources/R-fastr.srcjar")
+    args = ctx.actions.args()
+    args.use_param_file(param_file_arg = "--flagfile=%s", use_always = True)
+    args.set_param_file_format("multiline")
+    args.add("-rJavaOutput", r_srcjar)
+    if package:
+        args.add("-packageForR", package)
+    else:
+        args.add("-manifest", manifest)
+        inputs = depset([manifest], transitive = [inputs])
+    args.add_joined("-resourcePbs", r_pbs, join_with = ",")
+
+    ctx.actions.run(
+        executable = android_kit,
+        arguments = ["rstub", args],
+        inputs = inputs,
+        outputs = [r_srcjar],
+        mnemonic = "CompileTimeR",
+        progress_message = "Generating compile-time R %s" % r_srcjar.short_path,
+    )
+    return r_srcjar
+
+def _compile(
+        ctx,
+        out_compiled_resources = None,
+        out_r_pb = None,
+        resource_files = [],
+        aapt = None,
+        android_kit = None,
+        busybox = None,
+        host_javabase = None):
+    """Compile Android Resources processing pipeline.
+
+    Args:
+      ctx: The context.
+      out_compiled_resources: File. The compiled resources output file.
+      out_r_pb: File. The R.pb output file.
+      resource_files: A list of Files. The resource files can be directories.
+      aapt: FilesToRunProvider. The aapt executable or FilesToRunProvider.
+      android_kit: FilesToRunProvider. The android_kit executable or
+        FilesToRunProvider.
+      busybox: FilesToRunProvider. The ResourceBusyBox executable or
+        FilesToRunprovider
+      host_javabase: A Target. The host javabase.
+    """
+    _liteparse(ctx, out_r_pb, resource_files, android_kit)
+    _busybox.compile(
+        ctx,
+        out_file = out_compiled_resources,
+        resource_files = resource_files,
+        aapt = aapt,
+        busybox = busybox,
+        host_javabase = host_javabase,
+    )
+
+def _make_aar(
+        ctx,
+        assets = [],
+        assets_dir = None,
+        resource_files = [],
+        class_jar = None,
+        r_txt = None,
+        manifest = None,
+        proguard_specs = [],
+        busybox = None,
+        host_javabase = None):
+    """Generate an android archive file.
+
+    Args:
+      ctx: The context.
+      assets: sequence of Files. A list of Android assets files to be processed.
+      assets_dir: String. The name of the assets directory.
+      resource_files: A list of Files. The resource files.
+      class_jar: File. The class jar file.
+      r_txt: File. The resource IDs outputted by linking resources in text.
+      manifest: File. The primary AndroidManifest.xml.
+      proguard_specs: List of File. The proguard spec files.
+      busybox: FilesToRunProvider. The ResourceBusyBox executable or
+        FilesToRunprovider
+      host_javabase: A Target. The host javabase.
+
+    Returns:
+      The output aar artifact.
+    """
+    aar = ctx.actions.declare_file(ctx.label.name + ".aar")
+    _busybox.make_aar(
+        ctx,
+        out_aar = aar,
+        assets = assets,
+        assets_dir = assets_dir,
+        resource_files = resource_files,
+        class_jar = class_jar,
+        r_txt = r_txt,
+        manifest = manifest,
+        proguard_specs = proguard_specs,
+        busybox = busybox,
+        host_javabase = host_javabase,
+    )
+    return aar
+
+def _validate(ctx, manifest, defined_assets, defined_assets_dir):
+    if ((defined_assets and not defined_assets_dir) or
+        (not defined_assets and defined_assets_dir)):
+        _log.error(_ASSET_DEFINITION_ERROR % ctx.label)
+
+    if not manifest:
+        _log.error(_MANIFEST_MISSING_ERROR % ctx.label)
+
+def _make_direct_assets_transitive(assets_info):
+    return AndroidAssetsInfo(
+        assets_info.label,
+        assets_info.validation_result,
+        depset([]),  # direct_parsed_assets
+        depset(
+            transitive = [
+                assets_info.direct_parsed_assets,
+                assets_info.transitive_parsed_assets,
+            ],
+            order = "preorder",
+        ),
+        assets_info.assets,
+        assets_info.symbols,
+        assets_info.compiled_symbols,
+    )
+
+def _make_direct_resources_transitive(resources_info):
+    return AndroidResourcesInfo(
+        resources_info.label,
+        resources_info.manifest,
+        resources_info.compiletime_r_txt,
+        # NB: the ordering of "direct" and "transitive" is inconsistent with that used for
+        # AndroidAssetsInfo.
+        depset(
+            transitive = [
+                # Ordering is inconsistent here too:
+                # https://github.com/bazelbuild/bazel/blob/82c7f48b4628ebbec18123afdbed701bbaa605e2/src/tools/android/java/com/google/devtools/build/android/Aapt2ResourcePackagingAction.java#L158
+                resources_info.transitive_android_resources,
+                resources_info.direct_android_resources,
+            ],
+            order = "preorder",
+        ),
+        depset([]),  # direct_android_resources
+        resources_info.transitive_resources,
+        resources_info.transitive_manifests,
+        resources_info.transitive_aapt2_r_txt,
+        resources_info.transitive_symbols_bin,
+        resources_info.transitive_compiled_symbols,
+        resources_info.transitive_static_lib,
+        resources_info.transitive_r_txt,
+        validation_artifacts = resources_info.validation_artifacts,
+    )
+
+def _export_assets(assets_info, exports):
+    all_providers = [assets_info] + utils.collect_providers(AndroidAssetsInfo, exports)
+    return AndroidAssetsInfo(
+        assets_info.label,
+        assets_info.validation_result,
+        direct_parsed_assets = utils.join_depsets(all_providers, "direct_parsed_assets", order = "preorder"),
+        transitive_parsed_assets = utils.join_depsets(all_providers, "transitive_parsed_assets", order = "preorder"),
+        transitive_assets = utils.join_depsets(all_providers, "assets", order = "preorder"),
+        transitive_symbols = utils.join_depsets(all_providers, "symbols", order = "preorder"),
+        transitive_compiled_symbols = utils.join_depsets(all_providers, "compiled_symbols", order = "preorder"),
+    )
+
+def _export_resources(resources_info, exports):
+    all_providers = [resources_info] + utils.collect_providers(AndroidResourcesInfo, exports)
+    return AndroidResourcesInfo(
+        resources_info.label,
+        resources_info.manifest,
+        resources_info.compiletime_r_txt,
+        **{attr: utils.join_depsets(all_providers, attr, order = "preorder") for attr in [
+            "transitive_android_resources",
+            "direct_android_resources",
+            "transitive_resources",
+            "transitive_manifests",
+            "transitive_aapt2_r_txt",
+            "transitive_symbols_bin",
+            "transitive_compiled_symbols",
+            "transitive_static_lib",
+            "transitive_r_txt",
+            "validation_artifacts",
+        ]}
+    )
+
+def _validate_resources(resource_files = None):
+    for resource_file in resource_files:
+        path_segments = resource_file.path.split("/")
+        if len(path_segments) < 3:
+            fail(_INCORRECT_RESOURCE_LAYOUT_ERROR % resource_file)
+
+        # Check the resource directory type if the resource file is not a Fileset.
+        if not resource_file.is_directory:
+            # The resource directory is presumed to be the second directory from the end.
+            # Resource directories can have multiple qualifiers, each one separated with a dash.
+            res_type = path_segments[-2].partition(_RESOURCE_QUALIFIER_SEP)[0]
+            if res_type not in _RESOURCE_FOLDER_TYPES:
+                fail(_INCORRECT_RESOURCE_LAYOUT_ERROR % resource_file)
+
+def _process_starlark(
+        ctx,
+        java_package = None,
+        manifest = None,
+        defined_assets = False,
+        assets = None,
+        defined_assets_dir = False,
+        assets_dir = None,
+        exports_manifest = False,
+        stamp_manifest = True,
+        deps = [],
+        exports = [],
+        resource_files = None,
+        neverlink = False,
+        enable_data_binding = False,
+        android_test_migration = False,
+        fix_resource_transitivity = False,
+        aapt = None,
+        android_jar = None,
+        android_kit = None,
+        busybox = None,
+        java_toolchain = None,
+        host_javabase = None,
+        instrument_xslt = None,
+        xsltproc = None,
+        zip_tool = None):
+    """Processes Android Resources.
+
+    Args:
+      ctx: The rules context.
+      java_package: string. Java package for which java sources will be
+        generated. By default the package is inferred from the directory where
+        the BUILD file containing the rule is.
+      manifest: File. The AndroidManifest.xml file.
+      defined_assets: Bool. Signifies that the assets attribute was set, even
+        if the value is an empty list.
+      assets: sequence of Files. A list of Android assets files to be processed.
+      defined_assets_dir: Bool. Signifies that the assets dir attribute was set,
+        even if the value is an empty string.
+      assets_dir: String. The name of the assets directory.
+      exports_manifest: boolean. Whether to export manifest entries to the
+        android_binary targets that depend on this target.
+        NOTE: "uses-permissions" attributes are never exported.
+      stamp_manifest: boolean. Whether to stamp the manifest with the java
+        package of the target. If True, java_package needs to be passed to
+        the function.
+      deps: sequence of Targets. The list of other libraries targets to link
+        against.
+      exports: sequence of Targets. The closure of all rules reached via exports
+        attributes are considered direct dependencies of any rule that directly
+        depends on the target with exports. The exports are not direct deps of
+        the rule they belong to (TODO(b/144134042): make this so).
+      resource_files: sequence of Files. A list of Android resource files to be
+        processed.
+      neverlink: boolean. Only use this library for compilation and not runtime.
+        The outputs of a rule marked as neverlink will not be used in .apk
+        creation. Useful if the library will be provided by the runtime
+        environment during execution.
+      enable_data_binding: boolean. If true, processesing the data binding
+        expressions in layout resources included through the resource_files
+        parameter is enabled. Without this setting, data binding expressions
+        produce build failures.
+      android_test_migration: boolean. If true, the target is part of the android
+      test to android instrumentation test migration and should not propagate
+      any Android Resource providers.
+      fix_resource_transitivity: Whether to ensure that transitive resources are
+        correctly marked as transitive.
+      aapt: FilesToRunProvider. The aapt executable or FilesToRunProvider.
+      android_jar: File. The android Jar.
+      android_kit: FilesToRunProvider. The android_kit executable or
+        FilesToRunProvider.
+      busybox: FilesToRunProvider. The ResourceBusyBox executable or
+        FilesToRunprovider
+      java_toolchain: The java_toolchain Target.
+      host_javabase: Target. The host javabase.
+      instrument_xslt: File. The xslt transform to apply g3itr.
+      xsltproc: FilesToRunProvider. The xsltproc executable or FilesToRunProvider.
+      zip_tool: FilesToRunProvider. The zip tool executable or FilesToRunProvider.
+
+    Returns:
+      A dict containing _ResourcesProcessContextInfo provider fields.
+    """
+    if (xsltproc and not instrument_xslt) or (not xsltproc and instrument_xslt):
+        fail(
+            "Error, both instrument_xslt and xsltproc need to be " +
+            "specified or not, got:\nxlstproc = %s\ninstrument_xslt = %s" %
+            (xsltproc, instrument_xslt),
+        )
+
+    _validate_resources(resource_files)
+
+    defines_resources = bool(
+        manifest or
+        resource_files or
+        defined_assets or
+        defined_assets_dir or
+        exports_manifest,
+    )
+
+    # TODO(djwhang): Clean up the difference between neverlink the attribute used
+    # by Java compilation and resources neverlink.
+    resources_neverlink = (
+        neverlink and (
+            defines_resources or
+            ctx.fragments.android.fixed_resource_neverlinking
+        )
+    )
+
+    resources_ctx = {
+        _RESOURCES_APK: None,
+        _PROVIDERS: [],
+        # TODO(b/156530953): Move the validation result to the validation_outputs list when we are
+        # done rolling out Starlark resources processing
+        _VALIDATION_RESULTS: [],
+        _DEFINES_RESOURCES: defines_resources,
+        _R_JAVA: None,
+        _MERGED_MANIFEST: None,
+        _STARLARK_PROCESSED_MANIFEST: None,
+        _STARLARK_R_TXT: None,
+        _STARLARK_PROCESSED_RESOURCES: [],
+    }
+
+    if resource_files and not manifest:
+        _log.error(_MANIFEST_MISSING_ERROR % ctx.label)
+
+    if stamp_manifest and not java_package:
+        _log.error(_JAVA_PACKAGE_MISSING_ERROR % ctx.label)
+
+    direct_resources_nodes = []
+    transitive_resources_nodes = []
+    transitive_assets = []
+    transitive_assets_symbols = []
+    transitive_compiled_assets = []
+    direct_compiled_resources = []
+    transitive_compiled_resources = []
+    transitive_resources_files = []
+    transitive_manifests = []
+    transitive_r_txts = []
+
+    for dep in utils.collect_providers(StarlarkAndroidResourcesInfo, deps):
+        direct_resources_nodes.append(dep.direct_resources_nodes)
+        transitive_resources_nodes.append(dep.transitive_resources_nodes)
+        transitive_assets.append(dep.transitive_assets)
+        transitive_assets_symbols.append(dep.transitive_assets_symbols)
+        transitive_compiled_assets.append(dep.transitive_compiled_assets)
+        direct_compiled_resources.append(dep.direct_compiled_resources)
+        transitive_compiled_resources.append(dep.transitive_compiled_resources)
+        transitive_resources_files.append(dep.transitive_resource_files)
+        transitive_manifests.append(dep.transitive_manifests)
+        transitive_r_txts.append(dep.transitive_r_txts)
+
+    exports_direct_resources_nodes = []
+    exports_transitive_resources_nodes = []
+    exports_transitive_assets = []
+    exports_transitive_assets_symbols = []
+    exports_transitive_compiled_assets = []
+    exports_direct_compiled_resources = []
+    exports_transitive_compiled_resources = []
+    exports_transitive_resources_files = []
+    exports_transitive_manifests = []
+    exports_transitive_r_txts = []
+    for dep in utils.collect_providers(StarlarkAndroidResourcesInfo, exports):
+        exports_direct_resources_nodes.append(dep.direct_resources_nodes)
+        exports_transitive_resources_nodes.append(dep.transitive_resources_nodes)
+        exports_transitive_assets.append(dep.transitive_assets)
+        exports_transitive_assets_symbols.append(dep.transitive_assets_symbols)
+        exports_transitive_compiled_assets.append(dep.transitive_compiled_assets)
+        exports_direct_compiled_resources.append(dep.direct_compiled_resources)
+        exports_transitive_compiled_resources.append(dep.transitive_compiled_resources)
+        exports_transitive_resources_files.append(dep.transitive_resource_files)
+        exports_transitive_manifests.append(dep.transitive_manifests)
+        exports_transitive_r_txts.append(dep.transitive_r_txts)
+
+    # TODO(b/144134042): Don't merge exports; exports are not deps.
+    direct_resources_nodes.extend(exports_direct_resources_nodes)
+    transitive_resources_nodes.extend(exports_transitive_resources_nodes)
+    transitive_assets.extend(exports_transitive_assets)
+    transitive_assets_symbols.extend(exports_transitive_assets_symbols)
+    transitive_compiled_assets.extend(exports_transitive_compiled_assets)
+    direct_compiled_resources.extend(exports_direct_compiled_resources)
+    transitive_compiled_resources.extend(exports_transitive_compiled_resources)
+    transitive_resources_files.extend(exports_transitive_resources_files)
+    transitive_manifests.extend(exports_transitive_manifests)
+    transitive_r_txts.extend(exports_transitive_r_txts)
+
+    compiled_assets = None
+    parsed_assets = None
+    compiled_resources = None
+    out_aapt2_r_txt = None
+    r_txt = None
+    processed_resources = resource_files
+    processed_manifest = None
+    if not defines_resources:
+        if aapt:
+            # Generate an empty manifest with the right package
+            generated_manifest = ctx.actions.declare_file(
+                "_migrated/_generated/" + ctx.label.name + "/AndroidManifest.xml",
+            )
+            _generate_dummy_manifest(
+                ctx,
+                generated_manifest,
+                java_package if java_package else ctx.label.package.replace("/", "."),
+            )
+            r_txt = ctx.actions.declare_file(
+                "_migrated/" + ctx.label.name + "_symbols/R.txt",
+            )
+            out_manifest = ctx.actions.declare_file(
+                "_migrated/" + ctx.label.name + "_processed_manifest/AndroidManifest.xml",
+            )
+            _busybox.package(
+                ctx,
+                out_r_src_jar = ctx.actions.declare_file(
+                    "_migrated/" + ctx.label.name + ".srcjar",
+                ),
+                out_r_txt = r_txt,
+                out_manifest = out_manifest,
+                manifest = generated_manifest,
+                assets = assets,
+                assets_dir = assets_dir,
+                resource_files = resource_files,
+                direct_resources_nodes =
+                    depset(transitive = direct_resources_nodes, order = "preorder"),
+                transitive_resources_nodes =
+                    depset(transitive = transitive_resources_nodes, order = "preorder"),
+                transitive_assets = transitive_assets,
+                transitive_compiled_assets = transitive_compiled_assets,
+                transitive_resource_files = transitive_resources_files,
+                transitive_compiled_resources = transitive_compiled_resources,
+                transitive_manifests = transitive_manifests,
+                transitive_r_txts = transitive_r_txts,
+                package_type = "LIBRARY",
+                java_package = java_package,
+                android_jar = android_jar,
+                aapt = aapt,
+                busybox = busybox,
+                host_javabase = host_javabase,
+                should_throw_on_conflict = False,
+            )
+            resources_ctx[_STARLARK_PROCESSED_MANIFEST] = out_manifest
+            resources_ctx[_STARLARK_R_TXT] = r_txt
+            resources_ctx[_STARLARK_PROCESSED_RESOURCES] = resource_files
+
+    else:
+        if stamp_manifest:
+            stamped_manifest = ctx.actions.declare_file(
+                "_migrated/_renamed/" + ctx.label.name + "/AndroidManifest.xml",
+            )
+            _busybox.merge_manifests(
+                ctx,
+                out_file = stamped_manifest,
+                manifest = manifest,
+                merge_type = "LIBRARY",
+                java_package = java_package,
+                busybox = busybox,
+                host_javabase = host_javabase,
+            )
+            manifest = stamped_manifest
+
+        if instrument_xslt:
+            g3itr_manifest = ctx.actions.declare_file(
+                "_migrated/" + ctx.label.name + "_g3itr_manifest/AndroidManifest.xml",
+            )
+            _add_g3itr(
+                ctx,
+                out_manifest = g3itr_manifest,
+                manifest = manifest,
+                xsltproc = xsltproc,
+                instrument_xslt = instrument_xslt,
+            )
+            manifest = g3itr_manifest
+
+        parsed_assets = ctx.actions.declare_file(
+            "_migrated/" + ctx.label.name + "_symbols/assets.bin",
+        )
+        _busybox.parse(
+            ctx,
+            out_symbols = parsed_assets,
+            assets = assets,
+            assets_dir = assets_dir,
+            busybox = busybox,
+            host_javabase = host_javabase,
+        )
+        merged_assets = ctx.actions.declare_file(
+            "_migrated/" + ctx.label.name + "_files/assets.zip",
+        )
+        _busybox.merge_assets(
+            ctx,
+            out_assets_zip = merged_assets,
+            assets = assets,
+            assets_dir = assets_dir,
+            symbols = parsed_assets,
+            direct_resources_nodes = depset(
+                transitive = direct_resources_nodes,
+                order = "preorder",
+            ),
+            transitive_resources_nodes = depset(
+                transitive = transitive_resources_nodes,
+                order = "preorder",
+            ),
+            transitive_assets = transitive_assets,
+            transitive_assets_symbols = transitive_assets_symbols,
+            busybox = busybox,
+            host_javabase = host_javabase,
+        )
+        resources_ctx[_VALIDATION_RESULTS].append(merged_assets)
+
+        if assets:
+            compiled_assets = ctx.actions.declare_file(
+                "_migrated/" + ctx.label.name + "_symbols/assets.zip",
+            )
+            _busybox.compile(
+                ctx,
+                out_file = compiled_assets,
+                assets = assets,
+                assets_dir = assets_dir,
+                aapt = aapt,
+                busybox = busybox,
+                host_javabase = host_javabase,
+            )
+
+        if enable_data_binding:
+            out_databinding_info = ctx.actions.declare_file(
+                "_migrated/databinding/" + ctx.label.name + "/layout-info.zip",
+            )
+            processed_resources, resources_dirname = _make_databinding_outputs(
+                ctx,
+                resource_files,
+            )
+            _busybox.process_databinding(
+                ctx,
+                out_databinding_info = out_databinding_info,
+                out_databinding_processed_resources = processed_resources,
+                databinding_resources_dirname = resources_dirname,
+                resource_files = resource_files,
+                java_package = java_package,
+                busybox = busybox,
+                host_javabase = host_javabase,
+            )
+
+        compiled_resources = ctx.actions.declare_file(
+            "_migrated/" + ctx.label.name + "_symbols/symbols.zip",
+        )
+        _busybox.compile(
+            ctx,
+            out_file = compiled_resources,
+            resource_files = processed_resources,
+            aapt = aapt,
+            busybox = busybox,
+            host_javabase = host_javabase,
+        )
+
+        # TODO(b/160907203): Remove this fix once the native resource processing pipeline is turned off.
+        if enable_data_binding:
+            fixed_compiled_resources = ctx.actions.declare_file(
+                "_migrated/fixed/" + ctx.label.name + "_symbols/symbols.zip",
+            )
+            _fix_databinding_compiled_resources(
+                ctx,
+                out_compiled_resources = fixed_compiled_resources,
+                compiled_resources = compiled_resources,
+                zip_tool = zip_tool,
+            )
+            compiled_resources = fixed_compiled_resources
+
+        out_class_jar = ctx.actions.declare_file(
+            "_migrated/" + ctx.label.name + "_resources.jar",
+        )
+        processed_manifest = ctx.actions.declare_file(
+            "_migrated/" + ctx.label.name + "_processed_manifest/AndroidManifest.xml",
+        )
+        out_aapt2_r_txt = ctx.actions.declare_file(
+            "_migrated/" + ctx.label.name + "_symbols/R.aapt2.txt",
+        )
+        _busybox.merge_compiled(
+            ctx,
+            out_class_jar = out_class_jar,
+            out_manifest = processed_manifest,
+            out_aapt2_r_txt = out_aapt2_r_txt,
+            java_package = java_package,
+            manifest = manifest,
+            compiled_resources = compiled_resources,
+            direct_resources_nodes =
+                depset(transitive = direct_resources_nodes, order = "preorder"),
+            transitive_resources_nodes = depset(
+                transitive = transitive_resources_nodes,
+                order = "preorder",
+            ),
+            direct_compiled_resources = depset(
+                transitive = direct_compiled_resources,
+                order = "preorder",
+            ),
+            transitive_compiled_resources = depset(
+                transitive = transitive_compiled_resources,
+                order = "preorder",
+            ),
+            android_jar = android_jar,
+            busybox = busybox,
+            host_javabase = host_javabase,
+        )
+        resources_ctx[_MERGED_MANIFEST] = processed_manifest
+
+        apk = ctx.actions.declare_file(
+            "_migrated/" + ctx.label.name + "_files/library.ap_",
+        )
+        r_java = ctx.actions.declare_file(
+            "_migrated/" + ctx.label.name + ".srcjar",
+        )
+        r_txt = ctx.actions.declare_file(
+            "_migrated/" + ctx.label.name + "_symbols/R.txt",
+        )
+        _busybox.validate_and_link(
+            ctx,
+            out_r_src_jar = r_java,
+            out_r_txt = r_txt,
+            out_file = apk,
+            compiled_resources = compiled_resources,
+            transitive_compiled_resources = depset(
+                transitive = transitive_compiled_resources,
+                order = "preorder",
+            ),
+            java_package = java_package,
+            manifest = processed_manifest,
+            android_jar = android_jar,
+            aapt = aapt,
+            busybox = busybox,
+            host_javabase = host_javabase,
+        )
+        resources_ctx[_RESOURCES_APK] = apk
+
+        java_info = JavaInfo(
+            output_jar = out_class_jar,
+            compile_jar = out_class_jar,
+            source_jar = r_java,
+        )
+
+        resources_ctx[_R_JAVA] = java_info
+
+        # In a normal build, the outputs of _busybox.validate_and_link are unused. However we need
+        # this action to run to support resource visibility checks.
+        resources_ctx[_VALIDATION_RESULTS].append(r_txt)
+
+        # Needed for AAR generation. The Starlark resource processing pipeline uses the aapt2_r_txt file,
+        # which is why we can't use the StarlarkAndroidResourcesInfo provider when generating the aar.
+        resources_ctx[_STARLARK_PROCESSED_MANIFEST] = processed_manifest
+        resources_ctx[_STARLARK_R_TXT] = r_txt
+        resources_ctx[_STARLARK_PROCESSED_RESOURCES] = processed_resources
+
+    # TODO(b/117338320): Transitive lists defined here are incorrect; direct should come
+    # before transitive, and the order should be topological order instead of preorder.
+    # However, some applications may depend on this incorrect order.
+    if defines_resources:
+        transitive_resources_nodes = transitive_resources_nodes + direct_resources_nodes
+        direct_resources_nodes = []
+        transitive_compiled_resources = transitive_compiled_resources + direct_compiled_resources
+        direct_compiled_resources = []
+    else:
+        if fix_resource_transitivity:
+            transitive_resources_nodes = transitive_resources_nodes + direct_resources_nodes
+            direct_resources_nodes = []
+            transitive_compiled_resources = transitive_compiled_resources + direct_compiled_resources
+            direct_compiled_resources = []
+
+        # TODO(b/144163743): If the resource transitivity fix is disabled and resources-related
+        # inputs are missing, we implicitly export deps here. This legacy behavior must exist in the
+        # Starlark resource processing pipeline until we can clean up the depot.
+
+    # TODO(b/159916013): Audit neverlink behavior. Some processing can likely be skipped if the target is neverlink.
+    # TODO(b/69668042): Don't propagate exported providers/artifacts. Exports should respect neverlink.
+    if resources_neverlink:
+        resources_ctx[_PROVIDERS].append(StarlarkAndroidResourcesInfo(
+            direct_resources_nodes = depset(
+                transitive = exports_direct_resources_nodes,
+                order = "preorder",
+            ),
+            transitive_resources_nodes = depset(
+                transitive = exports_transitive_resources_nodes,
+                order = "preorder",
+            ),
+            transitive_assets = depset(
+                transitive = exports_transitive_assets,
+                order = "preorder",
+            ),
+            transitive_assets_symbols = depset(
+                transitive = exports_transitive_assets_symbols,
+                order = "preorder",
+            ),
+            transitive_compiled_assets = depset(
+                transitive = exports_transitive_compiled_assets,
+                order = "preorder",
+            ),
+            transitive_resource_files = depset(
+                transitive = exports_transitive_resources_files,
+                order = "preorder",
+            ),
+            direct_compiled_resources = depset(
+                transitive = exports_direct_compiled_resources,
+                order = "preorder",
+            ),
+            transitive_compiled_resources = depset(
+                transitive = exports_transitive_compiled_resources,
+                order = "preorder",
+            ),
+            transitive_manifests = depset(
+                [processed_manifest] if processed_manifest else [],
+                transitive = exports_transitive_manifests,
+                order = "preorder",
+            ),
+            transitive_r_txts = depset(
+                [out_aapt2_r_txt] if out_aapt2_r_txt else [],
+                transitive = exports_transitive_r_txts,
+                order = "preorder",
+            ),
+        ))
+    else:
+        # Depsets are ordered below to match the order in the legacy native rules.
+        resources_ctx[_PROVIDERS].append(StarlarkAndroidResourcesInfo(
+            direct_resources_nodes = depset(
+                [ResourcesNodeInfo(
+                    label = ctx.label,
+                    assets = depset(assets),
+                    assets_dir = assets_dir,
+                    assets_symbols = parsed_assets,
+                    compiled_assets = compiled_assets,
+                    resource_files = depset(processed_resources),
+                    compiled_resources = compiled_resources,
+                    r_txt = out_aapt2_r_txt,
+                    manifest = processed_manifest,
+                    exports_manifest = exports_manifest,
+                )] if defines_resources else [],
+                transitive = direct_resources_nodes + exports_direct_resources_nodes,
+                order = "preorder",
+            ),
+            transitive_resources_nodes = depset(
+                transitive = transitive_resources_nodes + exports_transitive_resources_nodes,
+                order = "preorder",
+            ),
+            transitive_assets = depset(
+                assets,
+                transitive = transitive_assets + exports_transitive_assets,
+                order = "preorder",
+            ),
+            transitive_assets_symbols = depset(
+                [parsed_assets] if parsed_assets else [],
+                transitive = transitive_assets_symbols + exports_transitive_assets_symbols,
+                order = "preorder",
+            ),
+            transitive_compiled_assets = depset(
+                [compiled_assets] if compiled_assets else [],
+                transitive = transitive_compiled_assets + exports_transitive_compiled_assets,
+                order = "preorder",
+            ),
+            transitive_resource_files = depset(
+                processed_resources,
+                transitive = transitive_resources_files + exports_transitive_resources_files,
+                order = "preorder",
+            ),
+            direct_compiled_resources = depset(
+                [compiled_resources] if compiled_resources else [],
+                transitive = direct_compiled_resources + exports_direct_compiled_resources,
+                order = "preorder",
+            ),
+            transitive_compiled_resources = depset(
+                [compiled_resources] if compiled_resources else [],
+                transitive = transitive_compiled_resources + exports_transitive_compiled_resources,
+                order = "preorder",
+            ),
+            transitive_manifests = depset(
+                [processed_manifest] if processed_manifest else [],
+                transitive = transitive_manifests + exports_transitive_manifests,
+                order = "preorder",
+            ),
+            transitive_r_txts = depset(
+                [out_aapt2_r_txt] if out_aapt2_r_txt else [],
+                transitive = transitive_r_txts + exports_transitive_r_txts,
+                order = "preorder",
+            ),
+        ))
+
+    # Do not collect resources and R.java for test apk
+    if android_test_migration:
+        resources_ctx[_R_JAVA] = None
+        resources_ctx[_PROVIDERS] = []
+
+    # TODO(b/69552500): In the Starlark Android Rules, the R compile time
+    # JavaInfo is added as a runtime dependency to the JavaInfo. Stop
+    # adding the R.jar as a runtime dependency.
+    resources_ctx[_PROVIDERS].append(
+        AndroidLibraryResourceClassJarProvider(
+            depset(
+                (resources_ctx[_R_JAVA].runtime_output_jars if resources_ctx[_R_JAVA] else []),
+                transitive = [
+                    p.jars
+                    for p in utils.collect_providers(
+                        AndroidLibraryResourceClassJarProvider,
+                        deps,
+                        exports,
+                    )
+                ],
+                order = "preorder",
+            ),
+        ),
+    )
+
+    return resources_ctx
+
+
+def _process(
+        ctx,
+        manifest = None,
+        resource_files = None,
+        defined_assets = False,
+        assets = None,
+        defined_assets_dir = False,
+        assets_dir = None,
+        exports_manifest = False,
+        java_package = None,
+        custom_package = None,
+        neverlink = False,
+        enable_data_binding = False,
+        deps = [],
+        exports = [],
+        android_jar = None,
+        android_kit = None,
+        aapt = None,
+        busybox = None,
+        xsltproc = None,
+        instrument_xslt = None,
+        java_toolchain = None,
+        host_javabase = None,
+        enable_res_v3 = False,
+        res_v3_dummy_manifest = None,
+        res_v3_dummy_r_txt = None,
+        fix_resource_transitivity = False,
+        fix_export_exporting = False,
+        android_test_migration = False,
+        zip_tool = None):
+    out_ctx = _process_starlark(
+        ctx,
+        java_package = java_package,
+        manifest = manifest,
+        defined_assets = defined_assets,
+        # TODO(b/159937795): When the Starlark Resources Processing pipeline is
+        # default and the native version is no longer used, remove the depset
+        # creation and directly pass through ctx.files.assets to this method.
+        assets =
+            depset(transitive = [target.files for target in assets]).to_list(),
+        defined_assets_dir = defined_assets_dir,
+        assets_dir = assets_dir,
+        exports_manifest = exports_manifest,
+        stamp_manifest = True if java_package else False,
+        deps = deps,
+        exports = exports,
+        resource_files = depset(transitive = [target.files for target in resource_files]).to_list(),
+        enable_data_binding = enable_data_binding,
+        fix_resource_transitivity = fix_resource_transitivity,
+        neverlink = neverlink,
+        android_test_migration = android_test_migration,
+        android_jar = android_jar,
+        aapt = aapt,
+        android_kit = android_kit,
+        busybox = busybox,
+        instrument_xslt = instrument_xslt,
+        xsltproc = xsltproc,
+        java_toolchain = java_toolchain,
+        host_javabase = host_javabase,
+        zip_tool = zip_tool,
+    )
+
+
+    if _VALIDATION_OUTPUTS not in out_ctx:
+        out_ctx[_VALIDATION_OUTPUTS] = []
+
+    return _ResourcesProcessContextInfo(**out_ctx)
+
+resources = struct(
+    process = _process,
+    process_starlark = _process_starlark,
+    package = _package,
+    make_aar = _make_aar,
+
+    # Exposed for mobile-install
+    compile = _compile,
+    legacy_merge_manifests = _legacy_merge_manifests,
+
+    # Exposed for android_local_test and android_library
+    generate_dummy_manifest = _generate_dummy_manifest,
+)
+
+testing = struct(
+    add_g3itr = _add_g3itr,
+    filter_multi_cpu_configuration_targets = _filter_multi_cpu_configuration_targets,
+    get_legacy_mergee_manifests = _get_legacy_mergee_manifests,
+    make_databinding_outputs = _make_databinding_outputs,
+    ResourcesPackageContextInfo = _ResourcesPackageContextInfo,
+    ResourcesProcessContextInfo = _ResourcesProcessContextInfo,
+)
diff --git a/rules/robolectric_properties_template.txt b/rules/robolectric_properties_template.txt
new file mode 100644
index 0000000..d05a28c
--- /dev/null
+++ b/rules/robolectric_properties_template.txt
@@ -0,0 +1,5 @@
+android_merged_manifest=%android_merged_manifest%
+android_merged_resources=%android_merged_resources%
+android_merged_assets=%android_merged_assets%
+android_custom_package=%android_custom_package%
+android_resource_apk=%android_resource_apk%
diff --git a/rules/rules.bzl b/rules/rules.bzl
new file mode 100644
index 0000000..e849d72
--- /dev/null
+++ b/rules/rules.bzl
@@ -0,0 +1,129 @@
+# Copyright 2019 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Skylark rules for building Android apps."""
+
+load(
+    "//rules/aar_import:rule.bzl",
+    _aar_import = "aar_import",
+)
+
+#load(
+#    ":apk_import.bzl",
+#    _apk_import = "apk_import",
+#)
+
+load(
+    ":android_binary.bzl",
+    _android_binary = "android_binary",
+)
+
+# load(
+#     ":android_device.bzl",
+#     _android_device = "android_device",
+# )
+# load(
+#     ":android_device_script_fixture.bzl",
+#     _android_device_script_fixture = "android_device_script_fixture",
+# )
+# load(
+#     ":android_host_service_fixture.bzl",
+#     _android_host_service_fixture = "android_host_service_fixture",
+# )
+# load(
+#     ":android_instrumentation_test.bzl",
+#     _android_instrumentation_test = "android_instrumentation_test",
+# )
+
+load(
+    "//rules/android_library:rule.bzl",
+    _android_library = "android_library_macro",
+)
+
+# load(
+#     ":android_local_test.bzl",
+#     _android_local_test = "android_local_test",
+# )
+
+load(
+    ":android_ndk_repository.bzl",
+    _android_ndk_repository = "android_ndk_repository",
+)
+load(
+    ":android_sdk.bzl",
+    _android_sdk = "android_sdk",
+)
+load(
+    ":android_sdk_repository.bzl",
+    _android_sdk_repository = "android_sdk_repository",
+)
+load(
+    ":android_tools_defaults_jar.bzl",
+    _android_tools_defaults_jar = "android_tools_defaults_jar",
+)
+
+# Current version. Tools may check this to determine compatibility.
+RULES_ANDROID_VERSION = "0.1.0"
+
+aar_import = _aar_import
+
+"""https://docs.bazel.build/versions/master/be/android.html#android_apk_to_bundle"""
+
+android_binary = _android_binary
+
+"""https://docs.bazel.build/versions/master/be/android.html#android_binary"""
+
+#android_device = _android_device
+
+"""https://docs.bazel.build/versions/master/be/android.html#android_device"""
+
+#android_device_script_fixture = _android_device_script_fixture
+
+"""https://docs.bazel.build/versions/master/be/android.html#android_host_service_fixture"""
+
+#android_host_service_fixture = _android_host_service_fixture
+
+"""https://docs.bazel.build/versions/master/be/android.html#android_device_script_fixture"""
+
+#android_instrumentation_test = _android_instrumentation_test
+
+"""https://docs.bazel.build/versions/master/be/android.html#android_instrumentation_test"""
+
+android_library = _android_library
+
+"""https://docs.bazel.build/versions/master/be/android.html#android_library"""
+
+#android_local_test = _android_local_test
+
+"""https://docs.bazel.build/versions/master/be/android.html#android_local_test"""
+
+android_ndk_repository = _android_ndk_repository
+
+"""https://docs.bazel.build/versions/master/be/android.html#android_ndk_repository"""
+
+android_sdk = _android_sdk
+
+"""https://docs.bazel.build/versions/master/be/android.html#android_sdk"""
+
+android_sdk_repository = _android_sdk_repository
+
+"""https://docs.bazel.build/versions/master/be/android.html#android_sdk_repository"""
+
+android_tools_defaults_jar = _android_tools_defaults_jar
+
+"""https://docs.bazel.build/versions/master/be/android.html#android_tools_defaults_jar"""
+
+#apk_import = _apk_import
+#
+#"""https://docs.bazel.build/versions/master/be/android.html#apk_import"""
diff --git a/rules/toolchains/emulator/BUILD b/rules/toolchains/emulator/BUILD
new file mode 100644
index 0000000..a02375a
--- /dev/null
+++ b/rules/toolchains/emulator/BUILD
@@ -0,0 +1,27 @@
+# Description:
+#   Defines an emulator toolchain so that the emulator used for android_device
+#   can be configured at build-time.
+
+load(":toolchain.bzl", "emulator_toolchain")
+
+package(default_visibility = ["//visibility:public"])
+
+# By convention, toolchain_type targets are named "toolchain_type"
+# and distinguished by their package path.
+toolchain_type(
+    name = "toolchain_type",
+)
+
+emulator_toolchain(
+    name = "emulator_default",
+    emulator = "@androidsdk//:emulator",
+    emulator_deps = [
+        "@androidsdk//:emulator_shared_libs",
+    ],
+)
+
+toolchain(
+    name = "emulator_default_toolchain",
+    toolchain = ":emulator_default",
+    toolchain_type = ":toolchain_type",
+)
diff --git a/rules/toolchains/emulator/toolchain.bzl b/rules/toolchains/emulator/toolchain.bzl
new file mode 100644
index 0000000..61bfb77
--- /dev/null
+++ b/rules/toolchains/emulator/toolchain.bzl
@@ -0,0 +1,59 @@
+# Copyright 2019 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Defines the emulator_toolchain rule to allow configuring emulator binaries to use."""
+
+EmulatorInfo = provider(
+    doc = "Information used to launch a specific version of the emulator.",
+    fields = {
+        "emulator": "A label for the emulator launcher executable at stable version.",
+        "emulator_deps": "Additional files required to launch the stable version of emulator.",
+        "emulator_suffix": "An optional path suffix used to find emulator binary under the emulator label path",
+    },
+)
+
+def _emulator_toolchain_impl(ctx):
+    toolchain_info = platform_common.ToolchainInfo(
+        info = EmulatorInfo(
+            emulator = ctx.attr.emulator,
+            emulator_deps = ctx.attr.emulator_deps,
+            emulator_suffix = ctx.attr.emulator_suffix,
+        ),
+    )
+    return [toolchain_info]
+
+emulator_toolchain = rule(
+    implementation = _emulator_toolchain_impl,
+    attrs = {
+        "emulator": attr.label(
+            allow_files = True,
+            cfg = "host",
+            mandatory = True,
+        ),
+        "emulator_deps": attr.label_list(
+            allow_files = True,
+            cfg = "host",
+        ),
+        "emulator_head": attr.label(
+            allow_files = True,
+            cfg = "host",
+        ),
+        "emulator_head_deps": attr.label_list(
+            allow_files = True,
+            cfg = "host",
+        ),
+        "emulator_suffix": attr.string(default = ""),
+        "emulator_head_suffix": attr.string(default = ""),
+    },
+)
diff --git a/rules/utils.bzl b/rules/utils.bzl
new file mode 100644
index 0000000..76a0fd2
--- /dev/null
+++ b/rules/utils.bzl
@@ -0,0 +1,451 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Utilities for the Android rules."""
+
+load(":providers.bzl", "FailureInfo")
+
+_CUU = "\033[A"
+_EL = "\033[K"
+_DEFAULT = "\033[0m"
+_BOLD = "\033[1m"
+_RED = "\033[31m"
+_GREEN = "\033[32m"
+_MAGENTA = "\033[35m"
+_ERASE_PREV_LINE = "\n" + _CUU + _EL
+
+_INFO = _ERASE_PREV_LINE + _GREEN + "INFO: " + _DEFAULT + "%s"
+_WARNING = _ERASE_PREV_LINE + _MAGENTA + "WARNING: " + _DEFAULT + "%s"
+_ERROR = _ERASE_PREV_LINE + _BOLD + _RED + "ERROR: " + _DEFAULT + "%s"
+
+_WORD_CHARS = {
+    "A": True,
+    "B": True,
+    "C": True,
+    "D": True,
+    "E": True,
+    "F": True,
+    "G": True,
+    "H": True,
+    "I": True,
+    "J": True,
+    "K": True,
+    "L": True,
+    "M": True,
+    "N": True,
+    "O": True,
+    "P": True,
+    "Q": True,
+    "R": True,
+    "S": True,
+    "T": True,
+    "U": True,
+    "V": True,
+    "W": True,
+    "X": True,
+    "Y": True,
+    "Z": True,
+    "a": True,
+    "b": True,
+    "c": True,
+    "d": True,
+    "e": True,
+    "f": True,
+    "g": True,
+    "h": True,
+    "i": True,
+    "j": True,
+    "k": True,
+    "l": True,
+    "m": True,
+    "n": True,
+    "o": True,
+    "p": True,
+    "q": True,
+    "r": True,
+    "s": True,
+    "t": True,
+    "u": True,
+    "v": True,
+    "w": True,
+    "x": True,
+    "y": True,
+    "z": True,
+    "0": True,
+    "1": True,
+    "2": True,
+    "3": True,
+    "4": True,
+    "5": True,
+    "6": True,
+    "7": True,
+    "8": True,
+    "9": True,
+    "_": True,
+}
+
+_HEX_CHAR = {
+    0x0: "0",
+    0x1: "1",
+    0x2: "2",
+    0x3: "3",
+    0x4: "4",
+    0x5: "5",
+    0x6: "6",
+    0x7: "7",
+    0x8: "8",
+    0x9: "9",
+    0xA: "A",
+    0xB: "B",
+    0xC: "C",
+    0xD: "D",
+    0xE: "E",
+    0xF: "F",
+}
+
+_JAVA_RESERVED = {
+    "abstract": True,
+    "assert": True,
+    "boolean": True,
+    "break": True,
+    "byte": True,
+    "case": True,
+    "catch": True,
+    "char": True,
+    "class": True,
+    "const": True,
+    "continue": True,
+    "default": True,
+    "do": True,
+    "double": True,
+    "else": True,
+    "enum": True,
+    "extends": True,
+    "final": True,
+    "finally": True,
+    "float": True,
+    "for": True,
+    "goto": True,
+    "if": True,
+    "implements": True,
+    "import": True,
+    "instanceof": True,
+    "int": True,
+    "interface": True,
+    "long": True,
+    "native": True,
+    "new": True,
+    "package": True,
+    "private": True,
+    "protected": True,
+    "public": True,
+    "return": True,
+    "short": True,
+    "static": True,
+    "strictfp": True,
+    "super": True,
+    "switch": True,
+    "synchronized": True,
+    "this": True,
+    "throw": True,
+    "throws": True,
+    "transient": True,
+    "try": True,
+    "void": True,
+    "volatile": True,
+    "while": True,
+    "true": True,
+    "false": True,
+    "null": True,
+}
+
+def _collect_providers(provider, *all_deps):
+    """Collects the requested providers from the given list of deps."""
+    providers = []
+    for deps in all_deps:
+        for dep in deps:
+            if provider in dep:
+                providers.append(dep[provider])
+    return providers
+
+def _join_depsets(providers, attr, order = "default"):
+    """Returns a merged depset using 'attr' from each provider in 'providers'."""
+    return depset(transitive = [getattr(p, attr) for p in providers], order = order)
+
+def _first(collection):
+    """Returns the first item in the collection."""
+    for i in collection:
+        return i
+    return _error("The collection is empty.")
+
+def _only(collection):
+    """Returns the only item in the collection."""
+    if len(collection) != 1:
+        _error("Expected one element, has %s." % len(collection))
+    return _first(collection)
+
+def _copy_file(ctx, src, dest):
+    if src.is_directory or dest.is_directory:
+        fail("Cannot use copy_file with directories")
+    ctx.actions.run_shell(
+        command = "cp --reflink=auto $1 $2",
+        arguments = [src.path, dest.path],
+        inputs = [src],
+        outputs = [dest],
+        mnemonic = "CopyFile",
+        progress_message = "Copy %s to %s" % (src.short_path, dest.short_path),
+    )
+
+def _copy_dir(ctx, src, dest):
+    if not src.is_directory:
+        fail("copy_dir src must be a directory")
+    ctx.actions.run_shell(
+        command = "cp -r --reflink=auto $1 $2",
+        arguments = [src.path, dest.path],
+        inputs = [src],
+        outputs = [dest],
+        mnemonic = "CopyDir",
+        progress_message = "Copy %s to %s" % (src.short_path, dest.short_path),
+    )
+
+def _info(msg):
+    """Print info."""
+    print(_INFO % msg)
+
+def _warn(msg):
+    """Print warning."""
+    print(_WARNING % msg)
+
+def _debug(msg):
+    """Print debug."""
+    print("\n%s" % msg)
+
+def _error(msg):
+    """Print error and fail."""
+    fail(_ERASE_PREV_LINE + _CUU + _ERASE_PREV_LINE + _CUU + _ERROR % msg)
+
+def _expand_var(config_vars, value):
+    """Expands make variables of the form $(SOME_VAR_NAME) for a single value.
+
+    "$$(SOME_VAR_NAME)" is escaped to a literal value of "$(SOME_VAR_NAME)" instead of being
+    expanded.
+
+    Args:
+      config_vars: String dictionary which maps config variables to their expanded values.
+      value: The string to apply substitutions to.
+
+    Returns:
+      The string value with substitutions applied.
+    """
+    parts = value.split("$(")
+    replacement = parts[0]
+    last_char = replacement[-1] if replacement else ""
+    for part in parts[1:]:
+        var_end = part.find(")")
+        if last_char == "$":
+            # If "$$(..." is found, treat it as "$(..."
+            replacement += "(" + part
+        elif var_end == -1 or part[:var_end] not in config_vars:
+            replacement += "$(" + part
+        else:
+            replacement += config_vars[part[:var_end]] + part[var_end + 1:]
+        last_char = replacement[-1] if replacement else ""
+    return replacement
+
+def _expand_make_vars(ctx, vals):
+    """Expands make variables of the form $(SOME_VAR_NAME).
+
+    Args:
+      ctx: The rules context.
+      vals: Dictionary. Values of the form $(...) will be replaced.
+
+    Returns:
+      A dictionary containing vals.keys() and the expanded values.
+    """
+    res = {}
+    for k, v in vals.items():
+        res[k] = _expand_var(ctx.var, v)
+    return res
+
+def _get_runfiles(ctx, attrs):
+    runfiles = ctx.runfiles()
+    for attr in attrs:
+        executable = attr[DefaultInfo].files_to_run.executable
+        if executable:
+            runfiles = runfiles.merge(ctx.runfiles([executable]))
+        runfiles = runfiles.merge(
+            ctx.runfiles(
+                # Wrap DefaultInfo.files in depset to strip ordering.
+                transitive_files = depset(
+                    transitive = [attr[DefaultInfo].files],
+                ),
+            ),
+        )
+        runfiles = runfiles.merge(attr[DefaultInfo].default_runfiles)
+    return runfiles
+
+def _sanitize_string(s, replacement = ""):
+    """Sanitizes a string by replacing all non-word characters.
+
+    This matches the \\w regex character class [A_Za-z0-9_].
+
+    Args:
+      s: String to sanitize.
+      replacement: Replacement for all non-word characters. Optional.
+
+    Returns:
+      The original string with all non-word characters replaced.
+    """
+    return "".join([s[i] if s[i] in _WORD_CHARS else replacement for i in range(len(s))])
+
+def _hex(n, pad = True):
+    """Convert an integer number to an uppercase hexadecimal string.
+
+    Args:
+      n: Integer number.
+      pad: Optional. Pad the result to 8 characters with leading zeroes. Default = True.
+
+    Returns:
+      Return a representation of an integer number as a hexadecimal string.
+    """
+    hex_str = ""
+    for _ in range(8):
+        r = n % 16
+        n = n // 16
+        hex_str = _HEX_CHAR[r] + hex_str
+    if pad:
+        return hex_str
+    else:
+        return hex_str.lstrip("0")
+
+def _sanitize_java_package(pkg):
+    return ".".join(["xxx" if p in _JAVA_RESERVED else p for p in pkg.split(".")])
+
+def _check_for_failures(label, *all_deps):
+    """Collects FailureInfo providers from the given list of deps and fails if there's at least one."""
+    failure_infos = _collect_providers(FailureInfo, *all_deps)
+    if failure_infos:
+        error = "in label '%s':" % label
+        for failure_info in failure_infos:
+            error += "\n\t" + failure_info.error
+        _error(error)
+
+def _run_validation(
+        ctx,
+        validation_out,
+        executable,
+        outputs = [],
+        tools = [],
+        **args):
+    """Creates an action that runs an executable as a validation.
+
+    Note: When the validation executable fails, it should return a non-zero
+    value to signify a validation failure.
+
+    Args:
+      ctx: The context.
+      validation_out: A File. The output of the executable is piped to the
+        file. This artifact should then be propagated to "validations" in the
+        OutputGroupInfo.
+      executable: See ctx.actions.run#executable.
+      outputs: See ctx.actions.run#outputs.
+      tools: See ctx.actions.run#tools.
+      **args: Remaining args are directly propagated to ctx.actions.run_shell.
+        See ctx.actions.run_shell for further documentation.
+    """
+    exec_type = type(executable)
+    exec_bin = None
+    exec_bin_path = None
+    if exec_type == "FilesToRunProvider":
+        exec_bin = executable.executable
+        exec_bin_path = exec_bin.path
+    elif exec_type == "File":
+        exec_bin = executable
+        exec_bin_path = exec_bin.path
+    elif exec_type == type(""):
+        exec_bin_path = executable
+    else:
+        fail(
+            "Error, executable should be a File, FilesToRunProvider or a " +
+            "string that represents a path to a tool, got: %s" % exec_type,
+        )
+
+    ctx.actions.run_shell(
+        command = """#!/bin/bash
+set -eu
+set -o pipefail # Returns the executables failure code, if it fails.
+
+EXECUTABLE={executable}
+VALIDATION_OUT={validation_out}
+
+"${{EXECUTABLE}}" $@ 2>&1 | tee -a "${{VALIDATION_OUT}}"
+""".format(
+            executable = exec_bin_path,
+            validation_out = validation_out.path,
+        ),
+        tools = tools + ([exec_bin] if exec_bin else []),
+        outputs = [validation_out] + outputs,
+        **args
+    )
+
+def get_android_toolchain(ctx):
+    return ctx.toolchains["@rules_android//toolchains/android:toolchain_type"]
+
+def get_android_sdk(ctx):
+    if hasattr(ctx.fragments.android, "incompatible_use_toolchain_resolution") and ctx.fragments.android.incompatible_use_toolchain_resolution:
+        return ctx.toolchains["@rules_android//toolchains/android_sdk:toolchain_type"].android_sdk_info
+    else:
+        return ctx.attr._android_sdk[AndroidSdkInfo]
+
+def _get_compilation_mode(ctx):
+    """Retrieves the compilation mode from the context.
+
+    Returns:
+      A string that represents the compilation mode.
+    """
+    return ctx.var["COMPILATION_MODE"]
+
+compilation_mode = struct(
+    DBG = "dbg",
+    FASTBUILD = "fastbuild",
+    OPT = "opt",
+    get = _get_compilation_mode,
+)
+
+utils = struct(
+    check_for_failures = _check_for_failures,
+    collect_providers = _collect_providers,
+    copy_file = _copy_file,
+    copy_dir = _copy_dir,
+    expand_make_vars = _expand_make_vars,
+    first = _first,
+    get_runfiles = _get_runfiles,
+    join_depsets = _join_depsets,
+    only = _only,
+    run_validation = _run_validation,
+    sanitize_string = _sanitize_string,
+    sanitize_java_package = _sanitize_java_package,
+    hex = _hex,
+)
+
+log = struct(
+    debug = _debug,
+    error = _error,
+    info = _info,
+    warn = _warn,
+)
+
+testing = struct(
+    expand_var = _expand_var,
+)
diff --git a/test/rules/resources/BUILD b/test/rules/resources/BUILD
new file mode 100644
index 0000000..e9ef118
--- /dev/null
+++ b/test/rules/resources/BUILD
@@ -0,0 +1,4 @@
+# Used in android_binary_internal resources diff test
+exports_files(
+    ["test_stub_script.sh"],
+)
diff --git a/toolchains/android/BUILD b/toolchains/android/BUILD
new file mode 100644
index 0000000..3741ee8
--- /dev/null
+++ b/toolchains/android/BUILD
@@ -0,0 +1,57 @@
+# Description:
+#   Defines the Android toolchain.
+
+load(":toolchain.bzl", "android_toolchain")
+load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
+
+licenses(["notice"])
+
+filegroup(
+    name = "all_files",
+    srcs = glob(["**"]),
+)
+
+# Android Toolchain Type
+toolchain_type(
+    name = "toolchain_type",
+    visibility = ["//visibility:public"],
+)
+
+# Default Android Toolchain
+android_toolchain(
+    name = "android_default",
+    visibility = ["//visibility:public"],
+)
+
+toolchain(
+    name = "android_default_toolchain",
+    toolchain = ":android_default",
+    toolchain_type = ":toolchain_type",
+)
+
+bzl_library(
+    name = "bzl",
+    srcs = glob(["*.bzl"]),
+)
+
+genrule(
+    name = "gen_unzip",
+    outs = ["unzip.sh"],
+    cmd = """cat > $@ <<EOF
+unzip \\$$@
+EOF
+""",
+    executable = True,
+)
+
+sh_binary(
+    name = "zip",
+    srcs = [":zip.sh"],
+    visibility = ["//visibility:public"],
+)
+
+sh_binary(
+    name = "unzip",
+    srcs = [":unzip.sh"],
+    visibility = ["//visibility:public"],
+)
diff --git a/toolchains/android/toolchain.bzl b/toolchains/android/toolchain.bzl
new file mode 100644
index 0000000..b356447
--- /dev/null
+++ b/toolchains/android/toolchain.bzl
@@ -0,0 +1,167 @@
+# Copyright 2019 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Android toolchain."""
+
+_ATTRS = dict(
+    aapt2 = attr.label(
+        allow_files = True,
+        default = "@androidsdk//:aapt2_binary",
+    ),
+    aar_embedded_jars_extractor = attr.label(
+        allow_files = True,
+        cfg = "host",
+        default = "@bazel_tools//tools/android:aar_embedded_jars_extractor",
+        executable = True,
+    ),
+    aar_native_libs_zip_creator = attr.label(
+        allow_files = True,
+        cfg = "host",
+        default = "@bazel_tools//tools/android:aar_native_libs_zip_creator",
+        executable = True,
+    ),
+    aar_resources_extractor = attr.label(
+        allow_files = True,
+        cfg = "host",
+        default = "@bazel_tools//tools/android:aar_resources_extractor",
+        executable = True,
+    ),
+    adb = attr.label(
+        allow_files = True,
+        cfg = "host",
+        default = "@androidsdk//:platform-tools/adb",
+        executable = True,
+    ),
+    add_g3itr_xslt = attr.label(
+        cfg = "host",
+        default = Label("//tools/android/xslt:add_g3itr.xslt"),
+        allow_files = True,
+    ),
+    android_kit = attr.label(
+        allow_files = True,
+        cfg = "host",
+        default = "@androidsdk//:fail",  # TODO: "//src/tools/ak", needs Go
+        executable = True,
+    ),
+    android_resources_busybox = attr.label(
+        allow_files = True,
+        cfg = "host",
+        default = "@bazel_tools//src/tools/android/java/com/google/devtools/build/android:ResourceProcessorBusyBox_deploy.jar",
+        executable = True,
+    ),
+    apk_to_bundle_tool = attr.label(
+        allow_files = True,
+        cfg = "host",
+        default = "@androidsdk//:fail",
+        executable = True,
+    ),
+    bundletool = attr.label(
+        allow_files = True,
+        cfg = "host",
+        default = "@androidsdk//:fail",
+        executable = True,
+    ),
+    data_binding_annotation_processor = attr.label(
+        cfg = "host",
+        default = "@//tools/android:compiler_annotation_processor",  # TODO: processor rules should be moved into rules_android
+    ),
+    data_binding_annotation_template = attr.label(
+        default = "//rules:data_binding_annotation_template.txt",
+        allow_files = True,
+    ),
+    data_binding_exec = attr.label(
+        cfg = "host",
+        default = "@bazel_tools//tools/android:databinding_exec",
+        executable = True,
+    ),
+    desugar_java8_extra_bootclasspath = attr.label(
+        allow_files = True,
+        cfg = "host",
+        default = "@bazel_tools//tools/android:desugar_java8_extra_bootclasspath",
+        executable = True,
+    ),
+    idlclass = attr.label(
+        allow_files = True,
+        cfg = "host",
+        default = "@bazel_tools//tools/android:IdlClass",  # _deploy.jar?
+        executable = True,
+    ),
+    import_deps_checker = attr.label(
+        allow_files = True,
+        cfg = "host",
+        default = "@android_tools//:ImportDepsChecker_deploy.jar",
+        executable = True,
+    ),
+    jacocorunner = attr.label(
+        default = "@androidsdk//:fail",
+    ),
+    java_stub = attr.label(
+        allow_files = True,
+        # used in android_local_test
+        default = "@androidsdk//:fail",  # TODO: java_stub_template.txt gets embedded in bazel's jar, need a copy in @bazel_tools or similar
+    ),
+    jdeps_tool = attr.label(
+        allow_files = True,
+        cfg = "host",
+        # used in android_local_test
+        default = "@androidsdk//:fail",  # TODO: "//src/tools/jdeps", needs Go
+        executable = True,
+    ),
+    proguard_allowlister = attr.label(
+        cfg = "host",
+        default = "@bazel_tools//tools/jdk:proguard_whitelister",
+        executable = True,
+    ),
+    res_v3_dummy_manifest = attr.label(
+        allow_files = True,
+        default = "//rules:res_v3_dummy_AndroidManifest.xml",
+    ),
+    res_v3_dummy_r_txt = attr.label(
+        allow_files = True,
+        default = "//rules:res_v3_dummy_R.txt",
+    ),
+    robolectric_template = attr.label(
+        allow_files = True,
+        default = "//rules:robolectric_properties_template.txt",
+    ),
+    testsupport = attr.label(
+        default = "@androidsdk//:fail",
+    ),
+    unzip_tool = attr.label(
+        cfg = "host",
+        default = "//toolchains/android:unzip",
+        executable = True,
+    ),
+    xsltproc_tool = attr.label(
+        cfg = "host",
+        default = Label("//tools/android/xslt:xslt"),
+        allow_files = True,
+        executable = True,
+    ),
+    zip_tool = attr.label(
+        cfg = "host",
+        default = "//toolchains/android:zip",
+        executable = True,
+    ),
+)
+
+def _impl(ctx):
+    return [platform_common.ToolchainInfo(
+        **{name: getattr(ctx.attr, name) for name in _ATTRS.keys()}
+    )]
+
+android_toolchain = rule(
+    implementation = _impl,
+    attrs = _ATTRS,
+)
diff --git a/toolchains/android/zip.sh b/toolchains/android/zip.sh
new file mode 100755
index 0000000..5d0f18b
--- /dev/null
+++ b/toolchains/android/zip.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -e
+
+args=()
+for arg in "$@"; do
+  if [[ ! "$arg" == "-jt" ]]; then
+    args+=( "$arg" )
+  fi
+done
+
+zip ${args[@]}
diff --git a/toolchains/android_sdk/BUILD b/toolchains/android_sdk/BUILD
new file mode 100644
index 0000000..d675cbe
--- /dev/null
+++ b/toolchains/android_sdk/BUILD
@@ -0,0 +1,30 @@
+# Description:
+#   Defines the Android SDK toolchain.
+
+licenses(["notice"])
+
+filegroup(
+    name = "all_files",
+    srcs = glob(["**"]),
+)
+
+# Android SDK Toolchain Type
+toolchain_type(
+    name = "toolchain_type",
+    visibility = ["//visibility:public"],
+)
+
+toolchain(
+    name = "android_sdk_tools",
+    exec_compatible_with = [
+        "@bazel_tools//platforms:x86_64",
+        "@bazel_tools//platforms:linux",
+    ],
+    # TODO(b/175833893): This causes the toolchain to not be selected, so
+    # disable for now.
+    #target_compatible_with = [
+    #    "@bazel_tools//platforms:android",
+    #],
+    toolchain = "@androidsdk//:sdk",
+    toolchain_type = ":toolchain_type",
+)
diff --git a/toolchains/emulator/BUILD b/toolchains/emulator/BUILD
new file mode 100644
index 0000000..a02375a
--- /dev/null
+++ b/toolchains/emulator/BUILD
@@ -0,0 +1,27 @@
+# Description:
+#   Defines an emulator toolchain so that the emulator used for android_device
+#   can be configured at build-time.
+
+load(":toolchain.bzl", "emulator_toolchain")
+
+package(default_visibility = ["//visibility:public"])
+
+# By convention, toolchain_type targets are named "toolchain_type"
+# and distinguished by their package path.
+toolchain_type(
+    name = "toolchain_type",
+)
+
+emulator_toolchain(
+    name = "emulator_default",
+    emulator = "@androidsdk//:emulator",
+    emulator_deps = [
+        "@androidsdk//:emulator_shared_libs",
+    ],
+)
+
+toolchain(
+    name = "emulator_default_toolchain",
+    toolchain = ":emulator_default",
+    toolchain_type = ":toolchain_type",
+)
diff --git a/tools/android/BUILD b/tools/android/BUILD
new file mode 100644
index 0000000..7c33f67
--- /dev/null
+++ b/tools/android/BUILD
@@ -0,0 +1,25 @@
+load(":defs.bzl", "android_jar")
+
+android_jar(
+    name = "android_jar",
+    visibility = ["//visibility:public"],
+)
+
+# TODO(b/175833857): This is a stub, should remove.
+alias(
+    name = "merge_manifests",
+    actual = ":fail",
+    visibility = ["//visibility:public"],
+)
+
+genrule(
+  name = "gen_fail",
+  outs = ["fail.sh"],
+  cmd = "echo 'exit 1' > $@",
+  executable = 1,
+)
+
+sh_binary(
+  name = "fail",
+  srcs =[":fail.sh"],
+)
diff --git a/tools/android/defs.bzl b/tools/android/defs.bzl
new file mode 100644
index 0000000..07c7a13
--- /dev/null
+++ b/tools/android/defs.bzl
@@ -0,0 +1,40 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""A rule that returns android.jar from the current android sdk."""
+
+def _android_jar_impl(ctx):
+    return DefaultInfo(
+        files = depset([ctx.attr._sdk[AndroidSdkInfo].android_jar]),
+    )
+
+android_jar = rule(
+    implementation = _android_jar_impl,
+    # TODO: Should use a toolchain instead of a configuration_field on
+    # --android_sdk as below, however that appears to be broken when used
+    # from an local_repository: b/183060658.
+    #toolchains = [
+    #    "//toolchains/android_sdk:toolchain_type",
+    #],
+    attrs = {
+        "_sdk": attr.label(
+            allow_rules = ["android_sdk"],
+            default = configuration_field(
+                fragment = "android",
+                name = "android_sdk_label",
+            ),
+            providers = [AndroidSdkInfo],
+        ),
+    },
+)
diff --git a/tools/android/xslt/BUILD b/tools/android/xslt/BUILD
new file mode 100644
index 0000000..b9a60b0
--- /dev/null
+++ b/tools/android/xslt/BUILD
@@ -0,0 +1,7 @@
+exports_files(["add_g3itr.xslt"])
+
+sh_binary(
+    name = "xslt",
+    srcs = ["xslt.sh"],
+    visibility = ["//visibility:public"],
+)
diff --git a/tools/android/xslt/add_g3itr.xslt b/tools/android/xslt/add_g3itr.xslt
new file mode 100644
index 0000000..9ce9a1e
--- /dev/null
+++ b/tools/android/xslt/add_g3itr.xslt
@@ -0,0 +1,7 @@
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+  <xsl:template match="@*|node()">
+    <xsl:copy>
+      <xsl:apply-templates select="@*|node()"/>
+    </xsl:copy>
+  </xsl:template>
+</xsl:stylesheet>
\ No newline at end of file
diff --git a/tools/android/xslt/xslt.sh b/tools/android/xslt/xslt.sh
new file mode 100755
index 0000000..fef6235
--- /dev/null
+++ b/tools/android/xslt/xslt.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# noop
+cp $6 $4
diff --git a/tools/jdk/BUILD b/tools/jdk/BUILD
new file mode 100644
index 0000000..c688d1a
--- /dev/null
+++ b/tools/jdk/BUILD
@@ -0,0 +1,11 @@
+load("@bazel_tools//tools/jdk:default_java_toolchain.bzl", "default_java_toolchain")
+
+default_java_toolchain(
+    name = "toolchain_android_only",
+    bootclasspath = [
+        "//tools/android:android_jar",
+        # TODO(b/175805830): Add this only when desugaring is enabled.
+        "@bazel_tools//tools/android:desugar_java8_extra_bootclasspath",
+    ],
+    visibility = ["//visibility:public"],
+)