Merge "Do not call getStagedApexInfos repeatedly" into main
diff --git a/Android.bp b/Android.bp
index 5b6e65c..b114898 100644
--- a/Android.bp
+++ b/Android.bp
@@ -168,12 +168,6 @@
         //same purpose.
         "//external/robolectric:__subpackages__",
         "//frameworks/layoutlib:__subpackages__",
-
-        // This is for the same purpose as robolectric -- to build "framework.jar" for host-side
-        // testing.
-        // TODO: Once Ravenwood is stable, move the host side jar targets to this directory,
-        // and remove this line.
-        "//frameworks/base/tools/hoststubgen:__subpackages__",
     ],
 }
 
diff --git a/Ravenwood.bp b/Ravenwood.bp
index ec58210..2e038e0 100644
--- a/Ravenwood.bp
+++ b/Ravenwood.bp
@@ -12,256 +12,19 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-// We need this "trampoline" rule to force soong to give a host-side jar to
-// framework-minus-apex.ravenwood-base. Otherwise, soong would mix up the arch (?) and we'd get
-// a dex jar.
-java_library {
-    name: "framework-minus-apex-for-hoststubgen",
-    installable: false, // host only jar.
-    static_libs: [
-        "framework-minus-apex",
-    ],
-    sdk_version: "core_platform",
-    visibility: ["//visibility:private"],
-}
-
-// Process framework-all with hoststubgen for Ravenwood.
-// This step takes several tens of seconds, so we manually shard it to multiple modules.
-// All the copies have to be kept in sync.
-// TODO: Do the sharding better, either by making hostsubgen support sharding natively, or
-// making a better build rule.
-
-genrule_defaults {
-    name: "framework-minus-apex.ravenwood-base_defaults",
-    defaults: ["ravenwood-internal-only-visibility-genrule"],
-    tools: ["hoststubgen"],
-    srcs: [
-        ":framework-minus-apex-for-hoststubgen",
-        ":ravenwood-framework-policies",
-        ":ravenwood-standard-options",
-        ":ravenwood-annotation-allowed-classes",
-    ],
-    out: [
-        "ravenwood.jar",
-        "hoststubgen_framework-minus-apex.log",
-    ],
-}
-
-framework_minus_apex_cmd = "$(location hoststubgen) " +
-    "@$(location :ravenwood-standard-options) " +
-    "--debug-log $(location hoststubgen_framework-minus-apex.log) " +
-    "--out-jar $(location ravenwood.jar) " +
-    "--in-jar $(location :framework-minus-apex-for-hoststubgen) " +
-    "--policy-override-file $(location :ravenwood-framework-policies) " +
-    "--annotation-allowed-classes-file $(location :ravenwood-annotation-allowed-classes) "
-
-java_genrule {
-    name: "framework-minus-apex.ravenwood-base_X0",
-    defaults: ["framework-minus-apex.ravenwood-base_defaults"],
-    cmd: framework_minus_apex_cmd + " --num-shards 10 --shard-index 0",
-}
-
-java_genrule {
-    name: "framework-minus-apex.ravenwood-base_X1",
-    defaults: ["framework-minus-apex.ravenwood-base_defaults"],
-    cmd: framework_minus_apex_cmd + " --num-shards 10 --shard-index 1",
-}
-
-java_genrule {
-    name: "framework-minus-apex.ravenwood-base_X2",
-    defaults: ["framework-minus-apex.ravenwood-base_defaults"],
-    cmd: framework_minus_apex_cmd + " --num-shards 10 --shard-index 2",
-}
-
-java_genrule {
-    name: "framework-minus-apex.ravenwood-base_X3",
-    defaults: ["framework-minus-apex.ravenwood-base_defaults"],
-    cmd: framework_minus_apex_cmd + " --num-shards 10 --shard-index 3",
-}
-
-java_genrule {
-    name: "framework-minus-apex.ravenwood-base_X4",
-    defaults: ["framework-minus-apex.ravenwood-base_defaults"],
-    cmd: framework_minus_apex_cmd + " --num-shards 10 --shard-index 4",
-}
-
-java_genrule {
-    name: "framework-minus-apex.ravenwood-base_X5",
-    defaults: ["framework-minus-apex.ravenwood-base_defaults"],
-    cmd: framework_minus_apex_cmd + " --num-shards 10 --shard-index 5",
-}
-
-java_genrule {
-    name: "framework-minus-apex.ravenwood-base_X6",
-    defaults: ["framework-minus-apex.ravenwood-base_defaults"],
-    cmd: framework_minus_apex_cmd + " --num-shards 10 --shard-index 6",
-}
-
-java_genrule {
-    name: "framework-minus-apex.ravenwood-base_X7",
-    defaults: ["framework-minus-apex.ravenwood-base_defaults"],
-    cmd: framework_minus_apex_cmd + " --num-shards 10 --shard-index 7",
-}
-
-java_genrule {
-    name: "framework-minus-apex.ravenwood-base_X8",
-    defaults: ["framework-minus-apex.ravenwood-base_defaults"],
-    cmd: framework_minus_apex_cmd + " --num-shards 10 --shard-index 8",
-}
-
-java_genrule {
-    name: "framework-minus-apex.ravenwood-base_X9",
-    defaults: ["framework-minus-apex.ravenwood-base_defaults"],
-    cmd: framework_minus_apex_cmd + " --num-shards 10 --shard-index 9",
-}
-
-// Build framework-minus-apex.ravenwood-base without sharding.
-// We extract the various dump files from this one, rather than the sharded ones, because
-// some dumps use the output from other classes (e.g. base classes) which may not be in the
-// same shard. Also some of the dump files ("apis") may be slow even when sharded, because
-// the output contains the information from all the input classes, rather than the output classes.
-// Not using sharding is fine for this module because it's only used for collecting the
-// dump / stats files, which don't have to happen regularly.
-java_genrule {
-    name: "framework-minus-apex.ravenwood-base_all",
-    defaults: ["framework-minus-apex.ravenwood-base_defaults"],
-    cmd: framework_minus_apex_cmd +
-        "--stats-file $(location hoststubgen_framework-minus-apex_stats.csv) " +
-        "--supported-api-list-file $(location hoststubgen_framework-minus-apex_apis.csv) " +
-
-        "--gen-keep-all-file $(location hoststubgen_framework-minus-apex_keep_all.txt) " +
-        "--gen-input-dump-file $(location hoststubgen_framework-minus-apex_dump.txt) ",
-
-    out: [
-        "hoststubgen_framework-minus-apex_keep_all.txt",
-        "hoststubgen_framework-minus-apex_dump.txt",
-        "hoststubgen_framework-minus-apex_stats.csv",
-        "hoststubgen_framework-minus-apex_apis.csv",
-    ],
-}
-
-// Marge all the sharded jars
-java_genrule {
-    name: "framework-minus-apex.ravenwood",
-    defaults: ["ravenwood-internal-only-visibility-java"],
-    cmd: "$(location merge_zips) $(out) $(in)",
-    tools: ["merge_zips"],
-    srcs: [
-        ":framework-minus-apex.ravenwood-base_X0{ravenwood.jar}",
-        ":framework-minus-apex.ravenwood-base_X1{ravenwood.jar}",
-        ":framework-minus-apex.ravenwood-base_X2{ravenwood.jar}",
-        ":framework-minus-apex.ravenwood-base_X3{ravenwood.jar}",
-        ":framework-minus-apex.ravenwood-base_X4{ravenwood.jar}",
-        ":framework-minus-apex.ravenwood-base_X5{ravenwood.jar}",
-        ":framework-minus-apex.ravenwood-base_X6{ravenwood.jar}",
-        ":framework-minus-apex.ravenwood-base_X7{ravenwood.jar}",
-        ":framework-minus-apex.ravenwood-base_X8{ravenwood.jar}",
-        ":framework-minus-apex.ravenwood-base_X9{ravenwood.jar}",
-    ],
-    out: [
-        "framework-minus-apex.ravenwood.jar",
-    ],
-}
+// "framework-minus-apex" and "all-updatable-modules-system-stubs" are not
+// visible publicly. We re-export them to Ravenwood in this file.
 
 java_library {
-    name: "services.core-for-hoststubgen",
-    installable: false, // host only jar.
-    static_libs: [
-        "services.core",
-    ],
-    sdk_version: "core_platform",
-    visibility: ["//visibility:private"],
-}
-
-java_genrule {
-    name: "services.core.ravenwood-base",
-    tools: ["hoststubgen"],
-    cmd: "$(location hoststubgen) " +
-        "@$(location :ravenwood-standard-options) " +
-
-        "--debug-log $(location hoststubgen_services.core.log) " +
-        "--stats-file $(location hoststubgen_services.core_stats.csv) " +
-        "--supported-api-list-file $(location hoststubgen_services.core_apis.csv) " +
-
-        "--out-jar $(location ravenwood.jar) " +
-
-        "--gen-keep-all-file $(location hoststubgen_services.core_keep_all.txt) " +
-        "--gen-input-dump-file $(location hoststubgen_services.core_dump.txt) " +
-
-        "--in-jar $(location :services.core-for-hoststubgen) " +
-        "--policy-override-file $(location :ravenwood-services-policies) " +
-        "--annotation-allowed-classes-file $(location :ravenwood-annotation-allowed-classes) ",
-    srcs: [
-        ":services.core-for-hoststubgen",
-        ":ravenwood-services-policies",
-        ":ravenwood-standard-options",
-        ":ravenwood-annotation-allowed-classes",
-    ],
-    out: [
-        "ravenwood.jar",
-
-        // Following files are created just as FYI.
-        "hoststubgen_services.core_keep_all.txt",
-        "hoststubgen_services.core_dump.txt",
-
-        "hoststubgen_services.core.log",
-        "hoststubgen_services.core_stats.csv",
-        "hoststubgen_services.core_apis.csv",
-    ],
-    defaults: ["ravenwood-internal-only-visibility-genrule"],
-}
-
-java_genrule {
-    name: "services.core.ravenwood",
-    defaults: ["ravenwood-internal-only-visibility-genrule"],
-    cmd: "cp $(in) $(out)",
-    srcs: [
-        ":services.core.ravenwood-base{ravenwood.jar}",
-    ],
-    out: [
-        "services.core.ravenwood.jar",
-    ],
-}
-
-// TODO(b/313930116) This jarjar is a bit slow. We should use hoststubgen for renaming,
-// but services.core.ravenwood has complex dependencies, so it'll take more than
-// just using hoststubgen "rename"s.
-java_library {
-    name: "services.core.ravenwood-jarjar",
-    defaults: ["ravenwood-internal-only-visibility-java"],
+    name: "framework-minus-apex-for-host",
     installable: false,
-    static_libs: [
-        "services.core.ravenwood",
-    ],
-    jarjar_rules: ":ravenwood-services-jarjar-rules",
+    static_libs: ["framework-minus-apex"],
+    visibility: ["//frameworks/base/ravenwood"],
 }
 
-// Jars in "ravenwood-runtime" are set to the classpath, sorted alphabetically.
-// Rename some of the dependencies to make sure they're included in the intended order.
 java_library {
-    name: "100-framework-minus-apex.ravenwood",
-    defaults: ["ravenwood-internal-only-visibility-java"],
-    static_libs: [
-        "framework-minus-apex.ravenwood",
-    ],
-    sdk_version: "core_platform",
-    // See b/313930116. Jarjar is too slow on this jar. We use HostStubGen to do the rename.
-    // jarjar_rules: ":ravenwood-framework-jarjar-rules",
-}
-
-java_genrule {
-    // Use 200 to make sure it comes before the mainline stub ("all-updatable...").
-    name: "200-kxml2-android",
-    defaults: ["ravenwood-internal-only-visibility-genrule"],
-    cmd: "cp $(in) $(out)",
-    srcs: [":kxml2-android"],
-    out: ["200-kxml2-android.jar"],
-}
-
-java_genrule {
-    name: "z00-all-updatable-modules-system-stubs",
-    defaults: ["ravenwood-internal-only-visibility-genrule"],
-    cmd: "cp $(in) $(out)",
-    srcs: [":all-updatable-modules-system-stubs"],
-    out: ["z00-all-updatable-modules-system-stubs.jar"],
+    name: "all-updatable-modules-system-stubs-for-host",
+    installable: false,
+    static_libs: ["all-updatable-modules-system-stubs"],
+    visibility: ["//frameworks/base/ravenwood"],
 }
diff --git a/cmds/bootanimation/OWNERS b/cmds/bootanimation/OWNERS
index b6fb007..2eda44d 100644
--- a/cmds/bootanimation/OWNERS
+++ b/cmds/bootanimation/OWNERS
@@ -1,3 +1,4 @@
 dupin@google.com
 shanh@google.com
 jreck@google.com
+rahulbanerjee@google.com
\ No newline at end of file
diff --git a/core/java/android/app/AppOps.md b/core/java/android/app/AppOps.md
index 7b11a03..535d62c 100644
--- a/core/java/android/app/AppOps.md
+++ b/core/java/android/app/AppOps.md
@@ -119,20 +119,20 @@
 In addition to proc state, the `AppOpsService` also receives process capability update from the
 `ActivityManagerService`. Proc capability specifies what while-in-use(`MODE_FOREGROUND`) operations
  the proc is allowed to perform in its current proc state. There are three proc capabilities
- defined so far: 
+ defined so far:
 `PROCESS_CAPABILITY_FOREGROUND_LOCATION`, `PROCESS_CAPABILITY_FOREGROUND_CAMERA` and
 `PROCESS_CAPABILITY_FOREGROUND_MICROPHONE`, they correspond to the while-in-use operation of
 location, camera and microphone (microphone is `RECORD_AUDIO`).
 
 In `ActivityManagerService`, `PROCESS_STATE_TOP` and `PROCESS_STATE_PERSISTENT` have all
 three capabilities, `PROCESS_STATE_FOREGROUND_SERVICE` has capabilities defined by
- `foregroundServiceType` that is specified in foreground service's manifest file. A client process 
+ `foregroundServiceType` that is specified in foreground service's manifest file. A client process
  can pass its capabilities to service using `BIND_INCLUDE_CAPABILITIES` flag.
 
 The proc state and capability are used for two use cases: Firstly, Tracking remembers the proc state
  for each tracked event. Secondly, `noteOp`/`checkOp` calls for app-op that are set to
  `MODE_FOREGROUND` are translated using the `AppOpsService.UidState.evalMode` method into
- `MODE_ALLOWED` when the app has the capability and `MODE_IGNORED` when the app does not have the 
+ `MODE_ALLOWED` when the app has the capability and `MODE_IGNORED` when the app does not have the
  capability. `checkOpRaw` calls are not affected.
 
 The current proc state and capability for an app can be read from `dumpsys appops`.
@@ -284,7 +284,7 @@
 ##### Self data accesses
 
 This is similar to the [synchronous data access](#synchronous-data-accesses) case only that the data
-provider and client are in the same process. In this case Android's RPC code is no involved and
+provider and client are in the same process. In this case Android's RPC code is not involved and
 `AppOpsManager.noteOp` directly triggers `OnOpNotedCallback.onSelfNoted`. This should be a uncommon
 case as it is uncommon for an app to provide data, esp. to itself.
 
diff --git a/core/java/android/net/vcn/flags.aconfig b/core/java/android/net/vcn/flags.aconfig
index dcb363c..efddd1f 100644
--- a/core/java/android/net/vcn/flags.aconfig
+++ b/core/java/android/net/vcn/flags.aconfig
@@ -21,38 +21,4 @@
     namespace: "vcn"
     description: "Feature flag for enabling network metric monitor"
     bug: "282996138"
-}
-
-flag{
-    name: "validate_network_on_ipsec_loss"
-    namespace: "vcn"
-    description: "Trigger network validation when IPsec packet loss exceeds the threshold"
-    bug: "329139898"
-}
-
-flag{
-    name: "evaluate_ipsec_loss_on_lp_nc_change"
-    namespace: "vcn"
-    description: "Re-evaluate IPsec packet loss on LinkProperties or NetworkCapabilities change"
-    bug: "323238888"
-}
-
-flag{
-    name: "enforce_main_user"
-    namespace: "vcn"
-    description: "Enforce main user to make VCN HSUM compatible"
-    bug: "310310661"
-    metadata {
-      purpose: PURPOSE_BUGFIX
-    }
-}
-
-flag{
-    name: "handle_seq_num_leap"
-    namespace: "vcn"
-    description: "Do not report bad network when there is a suspected sequence number leap"
-    bug: "332598276"
-    metadata {
-      purpose: PURPOSE_BUGFIX
-    }
 }
\ No newline at end of file
diff --git a/core/java/com/android/internal/util/MemInfoReader.java b/core/java/com/android/internal/util/MemInfoReader.java
index 0c5c853..d34bca6 100644
--- a/core/java/com/android/internal/util/MemInfoReader.java
+++ b/core/java/com/android/internal/util/MemInfoReader.java
@@ -88,6 +88,13 @@
     }
 
     /**
+     * Amount of RAM that used by shared memory (shmem) and tmpfs
+     */
+    public long getShmemSizeKb() {
+        return mInfos[Debug.MEMINFO_SHMEM];
+    }
+
+    /**
      * Amount of RAM that the kernel is being used for caches, not counting caches
      * that are mapped in to processes.
      */
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index c71f9bd..e4c56a6 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -155,6 +155,7 @@
 
     <protected-broadcast android:name="android.bluetooth.intent.DISCOVERABLE_TIMEOUT" />
     <protected-broadcast android:name="android.bluetooth.action.AUTO_ON_STATE_CHANGED" />
+    <protected-broadcast android:name="android.bluetooth.action.CONNECTION_STATE_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.adapter.action.STATE_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.adapter.action.SCAN_MODE_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.adapter.action.DISCOVERY_STARTED" />
@@ -240,6 +241,8 @@
     <protected-broadcast
         android:name="android.bluetooth.avrcp-controller.profile.action.FOLDER_LIST" />
     <protected-broadcast
+        android:name="android.bluetooth.avrcp-controller.profile.action.PLAYER_SETTING" />
+    <protected-broadcast
         android:name="android.bluetooth.avrcp-controller.profile.action.TRACK_EVENT" />
     <protected-broadcast
         android:name="android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED" />
@@ -266,6 +269,7 @@
     <protected-broadcast
         android:name="android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.action.HAP_CONNECTION_STATE_CHANGED" />
+    <protected-broadcast android:name="android.bluetooth.action.HAP_DEVICE_AVAILABLE" />
     <protected-broadcast android:name="android.bluetooth.action.LE_AUDIO_CONNECTION_STATE_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.action.LE_AUDIO_ACTIVE_DEVICE_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.action.LE_AUDIO_CONF_CHANGED" />
diff --git a/core/res/OWNERS b/core/res/OWNERS
index 5293131..d109cee 100644
--- a/core/res/OWNERS
+++ b/core/res/OWNERS
@@ -60,6 +60,7 @@
 
 # Wear
 per-file res/*-watch/* = file:/WEAR_OWNERS
+per-file res/*-watch-v*/* = file:/WEAR_OWNERS
 
 # Performance
 per-file res/values/config.xml = file:/PERFORMANCE_OWNERS
diff --git a/ravenwood/Android.bp b/ravenwood/Android.bp
index 9629a87..bfa801f 100644
--- a/ravenwood/Android.bp
+++ b/ravenwood/Android.bp
@@ -8,7 +8,15 @@
 
     // OWNER: g/ravenwood
     // Bug component: 25698
-    default_team: "trendy_team_framework_backstage_power",
+    default_team: "trendy_team_ravenwood",
+}
+
+filegroup {
+    name: "ravenwood-common-policies",
+    srcs: [
+        "texts/ravenwood-common-policies.txt",
+    ],
+    visibility: ["//visibility:private"],
 }
 
 filegroup {
@@ -16,7 +24,7 @@
     srcs: [
         "texts/ravenwood-services-policies.txt",
     ],
-    visibility: ["//visibility:public"],
+    visibility: ["//visibility:private"],
 }
 
 filegroup {
@@ -24,7 +32,7 @@
     srcs: [
         "texts/ravenwood-framework-policies.txt",
     ],
-    visibility: ["//visibility:public"],
+    visibility: ["//visibility:private"],
 }
 
 filegroup {
@@ -32,7 +40,7 @@
     srcs: [
         "texts/ravenwood-standard-options.txt",
     ],
-    visibility: ["//visibility:public"],
+    visibility: ["//visibility:private"],
 }
 
 filegroup {
@@ -40,7 +48,7 @@
     srcs: [
         "texts/ravenwood-annotation-allowed-classes.txt",
     ],
-    visibility: ["//visibility:public"],
+    visibility: ["//visibility:private"],
 }
 
 // This and the next module contain the same classes with different implementations.
@@ -337,6 +345,30 @@
     ],
 }
 
+// JARs in "ravenwood-runtime" are set to the classpath, sorted alphabetically.
+// Rename some of the dependencies to make sure they're included in the intended order.
+
+java_library {
+    name: "100-framework-minus-apex.ravenwood",
+    installable: false,
+    static_libs: ["framework-minus-apex.ravenwood"],
+    visibility: ["//visibility:private"],
+}
+
+java_library {
+    name: "200-kxml2-android",
+    installable: false,
+    static_libs: ["kxml2-android"],
+    visibility: ["//visibility:private"],
+}
+
+java_library {
+    name: "z00-all-updatable-modules-system-stubs",
+    installable: false,
+    static_libs: ["all-updatable-modules-system-stubs-for-host"],
+    visibility: ["//visibility:private"],
+}
+
 android_ravenwood_libgroup {
     name: "ravenwood-runtime",
     data: [
@@ -395,3 +427,7 @@
         "inline-mockito-ravenwood-prebuilt",
     ],
 }
+
+build = [
+    "Framework.bp",
+]
diff --git a/ravenwood/Framework.bp b/ravenwood/Framework.bp
new file mode 100644
index 0000000..5cb1479
--- /dev/null
+++ b/ravenwood/Framework.bp
@@ -0,0 +1,292 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// 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.
+
+// This file hosts all the genrule and module definitions for all Android specific
+// code that needs further post-processing by hoststubgen to support Ravenwood.
+
+/////////////////////////
+// framework-minus-apex
+/////////////////////////
+
+// Process framework-minus-apex with hoststubgen for Ravenwood.
+// This step takes several tens of seconds, so we manually shard it to multiple modules.
+// All the copies have to be kept in sync.
+// TODO: Do the sharding better, either by making hostsubgen support sharding natively, or
+// making a better build rule.
+
+genrule_defaults {
+    name: "framework-minus-apex.ravenwood-base_defaults",
+    tools: ["hoststubgen"],
+    srcs: [
+        ":framework-minus-apex-for-host",
+        ":ravenwood-common-policies",
+        ":ravenwood-framework-policies",
+        ":ravenwood-standard-options",
+        ":ravenwood-annotation-allowed-classes",
+    ],
+    out: [
+        "ravenwood.jar",
+        "hoststubgen_framework-minus-apex.log",
+    ],
+    visibility: ["//visibility:private"],
+}
+
+framework_minus_apex_cmd = "$(location hoststubgen) " +
+    "@$(location :ravenwood-standard-options) " +
+    "--debug-log $(location hoststubgen_framework-minus-apex.log) " +
+    "--out-jar $(location ravenwood.jar) " +
+    "--in-jar $(location :framework-minus-apex-for-host) " +
+    "--policy-override-file $(location :ravenwood-common-policies) " +
+    "--policy-override-file $(location :ravenwood-framework-policies) " +
+    "--annotation-allowed-classes-file $(location :ravenwood-annotation-allowed-classes) "
+
+java_genrule {
+    name: "framework-minus-apex.ravenwood-base_X0",
+    defaults: ["framework-minus-apex.ravenwood-base_defaults"],
+    cmd: framework_minus_apex_cmd + " --num-shards 10 --shard-index 0",
+}
+
+java_genrule {
+    name: "framework-minus-apex.ravenwood-base_X1",
+    defaults: ["framework-minus-apex.ravenwood-base_defaults"],
+    cmd: framework_minus_apex_cmd + " --num-shards 10 --shard-index 1",
+}
+
+java_genrule {
+    name: "framework-minus-apex.ravenwood-base_X2",
+    defaults: ["framework-minus-apex.ravenwood-base_defaults"],
+    cmd: framework_minus_apex_cmd + " --num-shards 10 --shard-index 2",
+}
+
+java_genrule {
+    name: "framework-minus-apex.ravenwood-base_X3",
+    defaults: ["framework-minus-apex.ravenwood-base_defaults"],
+    cmd: framework_minus_apex_cmd + " --num-shards 10 --shard-index 3",
+}
+
+java_genrule {
+    name: "framework-minus-apex.ravenwood-base_X4",
+    defaults: ["framework-minus-apex.ravenwood-base_defaults"],
+    cmd: framework_minus_apex_cmd + " --num-shards 10 --shard-index 4",
+}
+
+java_genrule {
+    name: "framework-minus-apex.ravenwood-base_X5",
+    defaults: ["framework-minus-apex.ravenwood-base_defaults"],
+    cmd: framework_minus_apex_cmd + " --num-shards 10 --shard-index 5",
+}
+
+java_genrule {
+    name: "framework-minus-apex.ravenwood-base_X6",
+    defaults: ["framework-minus-apex.ravenwood-base_defaults"],
+    cmd: framework_minus_apex_cmd + " --num-shards 10 --shard-index 6",
+}
+
+java_genrule {
+    name: "framework-minus-apex.ravenwood-base_X7",
+    defaults: ["framework-minus-apex.ravenwood-base_defaults"],
+    cmd: framework_minus_apex_cmd + " --num-shards 10 --shard-index 7",
+}
+
+java_genrule {
+    name: "framework-minus-apex.ravenwood-base_X8",
+    defaults: ["framework-minus-apex.ravenwood-base_defaults"],
+    cmd: framework_minus_apex_cmd + " --num-shards 10 --shard-index 8",
+}
+
+java_genrule {
+    name: "framework-minus-apex.ravenwood-base_X9",
+    defaults: ["framework-minus-apex.ravenwood-base_defaults"],
+    cmd: framework_minus_apex_cmd + " --num-shards 10 --shard-index 9",
+}
+
+// Build framework-minus-apex.ravenwood-base without sharding.
+// We extract the various dump files from this one, rather than the sharded ones, because
+// some dumps use the output from other classes (e.g. base classes) which may not be in the
+// same shard. Also some of the dump files ("apis") may be slow even when sharded, because
+// the output contains the information from all the input classes, rather than the output classes.
+// Not using sharding is fine for this module because it's only used for collecting the
+// dump / stats files, which don't have to happen regularly.
+java_genrule {
+    name: "framework-minus-apex.ravenwood-base_all",
+    defaults: ["framework-minus-apex.ravenwood-base_defaults"],
+    cmd: framework_minus_apex_cmd +
+        "--stats-file $(location hoststubgen_framework-minus-apex_stats.csv) " +
+        "--supported-api-list-file $(location hoststubgen_framework-minus-apex_apis.csv) " +
+
+        "--gen-keep-all-file $(location hoststubgen_framework-minus-apex_keep_all.txt) " +
+        "--gen-input-dump-file $(location hoststubgen_framework-minus-apex_dump.txt) ",
+
+    out: [
+        "hoststubgen_framework-minus-apex_keep_all.txt",
+        "hoststubgen_framework-minus-apex_dump.txt",
+        "hoststubgen_framework-minus-apex_stats.csv",
+        "hoststubgen_framework-minus-apex_apis.csv",
+    ],
+}
+
+// Marge all the sharded jars
+java_genrule {
+    name: "framework-minus-apex.ravenwood",
+    defaults: ["ravenwood-internal-only-visibility-java"],
+    cmd: "$(location merge_zips) $(out) $(in)",
+    tools: ["merge_zips"],
+    srcs: [
+        ":framework-minus-apex.ravenwood-base_X0{ravenwood.jar}",
+        ":framework-minus-apex.ravenwood-base_X1{ravenwood.jar}",
+        ":framework-minus-apex.ravenwood-base_X2{ravenwood.jar}",
+        ":framework-minus-apex.ravenwood-base_X3{ravenwood.jar}",
+        ":framework-minus-apex.ravenwood-base_X4{ravenwood.jar}",
+        ":framework-minus-apex.ravenwood-base_X5{ravenwood.jar}",
+        ":framework-minus-apex.ravenwood-base_X6{ravenwood.jar}",
+        ":framework-minus-apex.ravenwood-base_X7{ravenwood.jar}",
+        ":framework-minus-apex.ravenwood-base_X8{ravenwood.jar}",
+        ":framework-minus-apex.ravenwood-base_X9{ravenwood.jar}",
+    ],
+    out: [
+        "framework-minus-apex.ravenwood.jar",
+    ],
+}
+
+//////////////////
+// services.core
+//////////////////
+
+java_library {
+    name: "services.core-for-host",
+    installable: false, // host only jar.
+    static_libs: [
+        "services.core",
+    ],
+    sdk_version: "core_platform",
+    visibility: ["//visibility:private"],
+}
+
+java_genrule {
+    name: "services.core.ravenwood-base",
+    tools: ["hoststubgen"],
+    cmd: "$(location hoststubgen) " +
+        "@$(location :ravenwood-standard-options) " +
+
+        "--debug-log $(location hoststubgen_services.core.log) " +
+        "--stats-file $(location hoststubgen_services.core_stats.csv) " +
+        "--supported-api-list-file $(location hoststubgen_services.core_apis.csv) " +
+        "--gen-keep-all-file $(location hoststubgen_services.core_keep_all.txt) " +
+        "--gen-input-dump-file $(location hoststubgen_services.core_dump.txt) " +
+
+        "--out-jar $(location ravenwood.jar) " +
+        "--in-jar $(location :services.core-for-host) " +
+
+        "--policy-override-file $(location :ravenwood-common-policies) " +
+        "--policy-override-file $(location :ravenwood-services-policies) " +
+        "--annotation-allowed-classes-file $(location :ravenwood-annotation-allowed-classes) ",
+    srcs: [
+        ":services.core-for-host",
+        ":ravenwood-common-policies",
+        ":ravenwood-services-policies",
+        ":ravenwood-standard-options",
+        ":ravenwood-annotation-allowed-classes",
+    ],
+    out: [
+        "ravenwood.jar",
+
+        // Following files are created just as FYI.
+        "hoststubgen_services.core_keep_all.txt",
+        "hoststubgen_services.core_dump.txt",
+
+        "hoststubgen_services.core.log",
+        "hoststubgen_services.core_stats.csv",
+        "hoststubgen_services.core_apis.csv",
+    ],
+    visibility: ["//visibility:private"],
+}
+
+java_genrule {
+    name: "services.core.ravenwood",
+    defaults: ["ravenwood-internal-only-visibility-genrule"],
+    cmd: "cp $(in) $(out)",
+    srcs: [
+        ":services.core.ravenwood-base{ravenwood.jar}",
+    ],
+    out: [
+        "services.core.ravenwood.jar",
+    ],
+}
+
+// TODO(b/313930116) This jarjar is a bit slow. We should use hoststubgen for renaming,
+// but services.core.ravenwood has complex dependencies, so it'll take more than
+// just using hoststubgen "rename"s.
+java_library {
+    name: "services.core.ravenwood-jarjar",
+    defaults: ["ravenwood-internal-only-visibility-java"],
+    installable: false,
+    static_libs: [
+        "services.core.ravenwood",
+    ],
+    jarjar_rules: ":ravenwood-services-jarjar-rules",
+}
+
+///////////////
+// core-icu4j
+///////////////
+
+java_genrule {
+    name: "core-icu4j-for-host.ravenwood-base",
+    tools: ["hoststubgen"],
+    cmd: "$(location hoststubgen) " +
+        "@$(location :ravenwood-standard-options) " +
+
+        "--debug-log $(location hoststubgen_core-icu4j-for-host.log) " +
+        "--stats-file $(location hoststubgen_core-icu4j-for-host_stats.csv) " +
+        "--supported-api-list-file $(location hoststubgen_core-icu4j-for-host_apis.csv) " +
+        "--gen-keep-all-file $(location hoststubgen_core-icu4j-for-host_keep_all.txt) " +
+        "--gen-input-dump-file $(location hoststubgen_core-icu4j-for-host_dump.txt) " +
+
+        "--out-jar $(location ravenwood.jar) " +
+        "--in-jar $(location :core-icu4j-for-host) " +
+
+        "--policy-override-file $(location :ravenwood-common-policies) " +
+        "--policy-override-file $(location :icu-ravenwood-policies) ",
+    srcs: [
+        ":core-icu4j-for-host",
+
+        ":ravenwood-common-policies",
+        ":icu-ravenwood-policies",
+        ":ravenwood-standard-options",
+    ],
+    out: [
+        "ravenwood.jar",
+
+        // Following files are created just as FYI.
+        "hoststubgen_core-icu4j-for-host_keep_all.txt",
+        "hoststubgen_core-icu4j-for-host_dump.txt",
+
+        "hoststubgen_core-icu4j-for-host.log",
+        "hoststubgen_core-icu4j-for-host_stats.csv",
+        "hoststubgen_core-icu4j-for-host_apis.csv",
+    ],
+    visibility: ["//visibility:private"],
+}
+
+java_genrule {
+    name: "core-icu4j-for-host.ravenwood",
+    defaults: ["ravenwood-internal-only-visibility-genrule"],
+    cmd: "cp $(in) $(out)",
+    srcs: [
+        ":core-icu4j-for-host.ravenwood-base{ravenwood.jar}",
+    ],
+    out: [
+        "core-icu4j-for-host.ravenwood.jar",
+    ],
+}
diff --git a/ravenwood/texts/ravenwood-common-policies.txt b/ravenwood/texts/ravenwood-common-policies.txt
new file mode 100644
index 0000000..08f53977
--- /dev/null
+++ b/ravenwood/texts/ravenwood-common-policies.txt
@@ -0,0 +1,20 @@
+# Ravenwood "policy" that should apply to all code.
+
+# Keep all AIDL interfaces
+class :aidl keepclass
+
+# Keep all feature flag implementations
+class :feature_flags keepclass
+
+# Keep all sysprops generated code implementations
+class :sysprops keepclass
+
+# Keep all resource R classes
+class :r keepclass
+
+# Support APIs not available in standard JRE
+class java.io.FileDescriptor keep
+    method getInt$ ()I @com.android.ravenwood.RavenwoodJdkPatch.getInt$
+    method setInt$ (I)V @com.android.ravenwood.RavenwoodJdkPatch.setInt$
+class java.util.LinkedHashMap keep
+    method eldest ()Ljava/util/Map$Entry; @com.android.ravenwood.RavenwoodJdkPatch.eldest
diff --git a/ravenwood/texts/ravenwood-framework-policies.txt b/ravenwood/texts/ravenwood-framework-policies.txt
index d962c82..3649f0e 100644
--- a/ravenwood/texts/ravenwood-framework-policies.txt
+++ b/ravenwood/texts/ravenwood-framework-policies.txt
@@ -1,29 +1,10 @@
 # Ravenwood "policy" file for framework-minus-apex.
 
-# Keep all AIDL interfaces
-class :aidl keepclass
-
-# Keep all feature flag implementations
-class :feature_flags keepclass
-
-# Keep all sysprops generated code implementations
-class :sysprops keepclass
-
-# Keep all resource R classes
-class :r keepclass
-
 # To avoid VerifyError on nano proto files (b/324063814), we rename nano proto classes.
 # Note: The "rename" directive must use slashes (/) as a package name separator.
 rename com/.*/nano/   devicenano/
 rename android/.*/nano/   devicenano/
 
-# Support APIs not available in standard JRE
-class java.io.FileDescriptor keep
-    method getInt$ ()I @com.android.ravenwood.RavenwoodJdkPatch.getInt$
-    method setInt$ (I)V @com.android.ravenwood.RavenwoodJdkPatch.setInt$
-class java.util.LinkedHashMap keep
-    method eldest ()Ljava/util/Map$Entry; @com.android.ravenwood.RavenwoodJdkPatch.eldest
-
 # Exported to Mainline modules; cannot use annotations
 class com.android.internal.util.FastXmlSerializer keepclass
 class com.android.internal.util.FileRotator keepclass
diff --git a/ravenwood/texts/ravenwood-services-policies.txt b/ravenwood/texts/ravenwood-services-policies.txt
index 5cdb4f7..cc2fa60 100644
--- a/ravenwood/texts/ravenwood-services-policies.txt
+++ b/ravenwood/texts/ravenwood-services-policies.txt
@@ -1,7 +1 @@
 # Ravenwood "policy" file for services.core.
-
-# Keep all AIDL interfaces
-class :aidl keepclass
-
-# Keep all feature flag implementations
-class :feature_flags keepclass
diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java
index 12e8c57..947f6b7 100644
--- a/services/core/java/com/android/server/VcnManagementService.java
+++ b/services/core/java/com/android/server/VcnManagementService.java
@@ -48,7 +48,6 @@
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
-import android.net.vcn.Flags;
 import android.net.vcn.IVcnManagementService;
 import android.net.vcn.IVcnStatusCallback;
 import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
@@ -447,22 +446,16 @@
         }
 
         final UserHandle userHandle = UserHandle.getUserHandleForUid(uid);
+        final UserManager userManager = mContext.getSystemService(UserManager.class);
 
-        if (Flags.enforceMainUser()) {
-            final UserManager userManager = mContext.getSystemService(UserManager.class);
-
-            Binder.withCleanCallingIdentity(
-                    () -> {
-                        if (!Objects.equals(userManager.getMainUser(), userHandle)) {
-                            throw new SecurityException(
-                                    "VcnManagementService can only be used by callers running as"
-                                            + " the main user");
-                        }
-                    });
-        } else if (!userHandle.isSystem()) {
-            throw new SecurityException(
-                    "VcnManagementService can only be used by callers running as the primary user");
-        }
+        Binder.withCleanCallingIdentity(
+                () -> {
+                    if (!Objects.equals(userManager.getMainUser(), userHandle)) {
+                        throw new SecurityException(
+                                "VcnManagementService can only be used by callers running as"
+                                        + " the main user");
+                    }
+                });
     }
 
     private void enforceCallingUserAndCarrierPrivilege(
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 6cfacf7..d7c43b5 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -13143,6 +13143,8 @@
             final long lostRAM = memInfo.getTotalSizeKb()
                     - (ss[INDEX_TOTAL_PSS] - ss[INDEX_TOTAL_SWAP_PSS])
                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
+                    // NR_SHMEM is subtracted twice (getCachedSizeKb() and getKernelUsedSizeKb())
+                    + memInfo.getShmemSizeKb()
                     - kernelUsed - memInfo.getZramTotalSizeKb();
             if (!opts.isCompact) {
                 pw.print(" Used RAM: "); pw.print(stringifyKBSize(ss[INDEX_TOTAL_PSS] - cachedPss
@@ -13656,6 +13658,8 @@
             long lostRAM = memInfo.getTotalSizeKb()
                     - (ss[INDEX_TOTAL_PSS] - ss[INDEX_TOTAL_SWAP_PSS])
                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
+                    // NR_SHMEM is subtracted twice (getCachedSizeKb() and getKernelUsedSizeKb())
+                    + memInfo.getShmemSizeKb()
                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
             proto.write(MemInfoDumpProto.USED_PSS_KB, ss[INDEX_TOTAL_PSS] - cachedPss);
             proto.write(MemInfoDumpProto.USED_KERNEL_KB, memInfo.getKernelUsedSizeKb());
diff --git a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
index 5514ec7..636854b 100644
--- a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
+++ b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
@@ -62,9 +62,7 @@
 import com.android.internal.pm.parsing.PackageParser2;
 import com.android.internal.pm.pkg.parsing.ParsingPackageUtils;
 import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.FrameworkStatsLog;
 import com.android.server.LocalServices;
-import com.android.server.integrity.engine.RuleEvaluationEngine;
 import com.android.server.integrity.model.IntegrityCheckResult;
 import com.android.server.integrity.model.RuleMetadata;
 import com.android.server.pm.PackageManagerServiceUtils;
@@ -131,7 +129,6 @@
     private final Handler mHandler;
     private final PackageManagerInternal mPackageManagerInternal;
     private final Supplier<PackageParser2> mParserSupplier;
-    private final RuleEvaluationEngine mEvaluationEngine;
     private final IntegrityFileManager mIntegrityFileManager;
 
     /** Create an instance of {@link AppIntegrityManagerServiceImpl}. */
@@ -143,7 +140,6 @@
                 context,
                 LocalServices.getService(PackageManagerInternal.class),
                 PackageParserUtils::forParsingFileWithDefaults,
-                RuleEvaluationEngine.getRuleEvaluationEngine(),
                 IntegrityFileManager.getInstance(),
                 handlerThread.getThreadHandler());
     }
@@ -153,13 +149,11 @@
             Context context,
             PackageManagerInternal packageManagerInternal,
             Supplier<PackageParser2> parserSupplier,
-            RuleEvaluationEngine evaluationEngine,
             IntegrityFileManager integrityFileManager,
             Handler handler) {
         mContext = context;
         mPackageManagerInternal = packageManagerInternal;
         mParserSupplier = parserSupplier;
-        mEvaluationEngine = evaluationEngine;
         mIntegrityFileManager = integrityFileManager;
         mHandler = handler;
 
@@ -214,12 +208,6 @@
                                         version, ruleProvider));
                     }
 
-                    FrameworkStatsLog.write(
-                            FrameworkStatsLog.INTEGRITY_RULES_PUSHED,
-                            success,
-                            ruleProvider,
-                            version);
-
                     Intent intent = new Intent();
                     intent.putExtra(EXTRA_STATUS, success ? STATUS_SUCCESS : STATUS_FAILURE);
                     try {
@@ -337,7 +325,7 @@
                                 + " installers "
                                 + allowedInstallers);
             }
-            IntegrityCheckResult result = mEvaluationEngine.evaluate(appInstallMetadata);
+            IntegrityCheckResult result = IntegrityCheckResult.allow();
             if (!result.getMatchedRules().isEmpty() || DEBUG_INTEGRITY_COMPONENT) {
                 Slog.i(
                         TAG,
@@ -346,15 +334,6 @@
                                 packageName, result.getEffect(), result.getMatchedRules()));
             }
 
-            FrameworkStatsLog.write(
-                    FrameworkStatsLog.INTEGRITY_CHECK_RESULT_REPORTED,
-                    packageName,
-                    appCertificates.toString(),
-                    appInstallMetadata.getVersionCode(),
-                    installerPackageName,
-                    result.getLoggingResponse(),
-                    result.isCausedByAppCertRule(),
-                    result.isCausedByInstallerRule());
             mPackageManagerInternal.setIntegrityVerificationResult(
                     verificationId,
                     result.getEffect() == IntegrityCheckResult.Effect.ALLOW
diff --git a/services/core/java/com/android/server/integrity/engine/RuleEvaluationEngine.java b/services/core/java/com/android/server/integrity/engine/RuleEvaluationEngine.java
deleted file mode 100644
index 61da45d..0000000
--- a/services/core/java/com/android/server/integrity/engine/RuleEvaluationEngine.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * 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.
- */
-
-package com.android.server.integrity.engine;
-
-import android.content.integrity.AppInstallMetadata;
-import android.content.integrity.Rule;
-import android.util.Slog;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.integrity.IntegrityFileManager;
-import com.android.server.integrity.model.IntegrityCheckResult;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * The engine used to evaluate rules against app installs.
- *
- * <p>Every app install is evaluated against rules (pushed by the verifier) by the evaluation engine
- * to allow/block that install.
- */
-public class RuleEvaluationEngine {
-    private static final String TAG = "RuleEvaluation";
-
-    // The engine for loading rules, retrieving metadata for app installs, and evaluating app
-    // installs against rules.
-    private static RuleEvaluationEngine sRuleEvaluationEngine;
-
-    private final IntegrityFileManager mIntegrityFileManager;
-
-    @VisibleForTesting
-    RuleEvaluationEngine(IntegrityFileManager integrityFileManager) {
-        mIntegrityFileManager = integrityFileManager;
-    }
-
-    /** Provide a singleton instance of the rule evaluation engine. */
-    public static synchronized RuleEvaluationEngine getRuleEvaluationEngine() {
-        if (sRuleEvaluationEngine == null) {
-            return new RuleEvaluationEngine(IntegrityFileManager.getInstance());
-        }
-        return sRuleEvaluationEngine;
-    }
-
-    /**
-     * Load, and match the list of rules against an app install metadata.
-     *
-     * @param appInstallMetadata Metadata of the app to be installed, and to evaluate the rules
-     *                           against.
-     * @return result of the integrity check
-     */
-    public IntegrityCheckResult evaluate(
-            AppInstallMetadata appInstallMetadata) {
-        List<Rule> rules = loadRules(appInstallMetadata);
-        return RuleEvaluator.evaluateRules(rules, appInstallMetadata);
-    }
-
-    private List<Rule> loadRules(AppInstallMetadata appInstallMetadata) {
-        if (!mIntegrityFileManager.initialized()) {
-            Slog.w(TAG, "Integrity rule files are not available.");
-            return Collections.emptyList();
-        }
-
-        try {
-            return mIntegrityFileManager.readRules(appInstallMetadata);
-        } catch (Exception e) {
-            Slog.e(TAG, "Error loading rules.", e);
-            return new ArrayList<>();
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/integrity/engine/RuleEvaluator.java b/services/core/java/com/android/server/integrity/engine/RuleEvaluator.java
deleted file mode 100644
index 9d94304..0000000
--- a/services/core/java/com/android/server/integrity/engine/RuleEvaluator.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * 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.
- */
-
-package com.android.server.integrity.engine;
-
-import static android.content.integrity.Rule.DENY;
-import static android.content.integrity.Rule.FORCE_ALLOW;
-
-import android.annotation.NonNull;
-import android.content.integrity.AppInstallMetadata;
-import android.content.integrity.Rule;
-
-import com.android.server.integrity.model.IntegrityCheckResult;
-
-import java.util.List;
-import java.util.stream.Collectors;
-
-/**
- * A helper class for evaluating rules against app install metadata to find if there are matching
- * rules.
- */
-final class RuleEvaluator {
-
-    /**
-     * Match the list of rules against an app install metadata.
-     *
-     * <p>Rules must be in disjunctive normal form (DNF). A rule should contain AND'ed formulas
-     * only. All rules are OR'ed together by default.
-     *
-     * @param rules The list of rules to evaluate.
-     * @param appInstallMetadata Metadata of the app to be installed, and to evaluate the rules
-     *     against.
-     * @return result of the integrity check
-     */
-    @NonNull
-    static IntegrityCheckResult evaluateRules(
-            List<Rule> rules, AppInstallMetadata appInstallMetadata) {
-
-        // Identify the rules that match the {@code appInstallMetadata}.
-        List<Rule> matchedRules =
-                rules.stream()
-                        .filter(rule -> rule.getFormula().matches(appInstallMetadata))
-                        .collect(Collectors.toList());
-
-        // Identify the matched power allow rules and terminate early if we have any.
-        List<Rule> matchedPowerAllowRules =
-                matchedRules.stream()
-                        .filter(rule -> rule.getEffect() == FORCE_ALLOW)
-                        .collect(Collectors.toList());
-
-        if (!matchedPowerAllowRules.isEmpty()) {
-            return IntegrityCheckResult.allow(matchedPowerAllowRules);
-        }
-
-        // Identify the matched deny rules.
-        List<Rule> matchedDenyRules =
-                matchedRules.stream()
-                        .filter(rule -> rule.getEffect() == DENY)
-                        .collect(Collectors.toList());
-
-        if (!matchedDenyRules.isEmpty()) {
-            return IntegrityCheckResult.deny(matchedDenyRules);
-        }
-
-        // When no rules are denied, return default allow result.
-        return IntegrityCheckResult.allow();
-    }
-}
diff --git a/services/core/java/com/android/server/integrity/model/IntegrityCheckResult.java b/services/core/java/com/android/server/integrity/model/IntegrityCheckResult.java
index 1fa0670..b0647fc 100644
--- a/services/core/java/com/android/server/integrity/model/IntegrityCheckResult.java
+++ b/services/core/java/com/android/server/integrity/model/IntegrityCheckResult.java
@@ -19,8 +19,6 @@
 import android.annotation.Nullable;
 import android.content.integrity.Rule;
 
-import com.android.internal.util.FrameworkStatsLog;
-
 import java.util.Collections;
 import java.util.List;
 
@@ -82,21 +80,6 @@
         return new IntegrityCheckResult(Effect.DENY, ruleList);
     }
 
-    /**
-     * Returns the in value of the integrity check result for logging purposes.
-     */
-    public int getLoggingResponse() {
-        if (getEffect() == Effect.DENY) {
-            return FrameworkStatsLog.INTEGRITY_CHECK_RESULT_REPORTED__RESPONSE__REJECTED;
-        } else if (getEffect() == Effect.ALLOW && getMatchedRules().isEmpty()) {
-            return FrameworkStatsLog.INTEGRITY_CHECK_RESULT_REPORTED__RESPONSE__ALLOWED;
-        } else if (getEffect() == Effect.ALLOW && !getMatchedRules().isEmpty()) {
-            return FrameworkStatsLog.INTEGRITY_CHECK_RESULT_REPORTED__RESPONSE__FORCE_ALLOWED;
-        } else {
-            throw new IllegalStateException("IntegrityCheckResult is not valid.");
-        }
-    }
-
     /** Returns true when the {@code mEffect} is caused by an app certificate mismatch. */
     public boolean isCausedByAppCertRule() {
         return mRuleList.stream().anyMatch(rule -> rule.getFormula().isAppCertificateFormula());
diff --git a/services/core/java/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java b/services/core/java/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java
index 5f704a0..6f1e15b 100644
--- a/services/core/java/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java
+++ b/services/core/java/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java
@@ -29,7 +29,6 @@
 import android.net.ConnectivityManager;
 import android.net.IpSecTransformState;
 import android.net.Network;
-import android.net.vcn.Flags;
 import android.net.vcn.VcnManager;
 import android.os.Handler;
 import android.os.HandlerExecutor;
@@ -233,7 +232,7 @@
     @VisibleForTesting(visibility = Visibility.PRIVATE)
     static int getMaxSeqNumIncreasePerSecond(@Nullable PersistableBundleWrapper carrierConfig) {
         int maxSeqNumIncrease = MAX_SEQ_NUM_INCREASE_DEFAULT_DISABLED;
-        if (Flags.handleSeqNumLeap() && carrierConfig != null) {
+        if (carrierConfig != null) {
             maxSeqNumIncrease =
                     carrierConfig.getInt(
                             VcnManager.VCN_NETWORK_SELECTION_MAX_SEQ_NUM_INCREASE_PER_SECOND_KEY,
@@ -287,10 +286,8 @@
         // with the new interval
         mPollIpSecStateIntervalMs = getPollIpSecStateIntervalMs(carrierConfig);
 
-        if (Flags.handleSeqNumLeap()) {
-            mPacketLossRatePercentThreshold = getPacketLossRatePercentThreshold(carrierConfig);
-            mMaxSeqNumIncreasePerSecond = getMaxSeqNumIncreasePerSecond(carrierConfig);
-        }
+        mPacketLossRatePercentThreshold = getPacketLossRatePercentThreshold(carrierConfig);
+        mMaxSeqNumIncreasePerSecond = getMaxSeqNumIncreasePerSecond(carrierConfig);
 
         if (canStart() != isStarted()) {
             if (canStart()) {
@@ -438,13 +435,10 @@
                 onValidationResultReceivedInternal(true /* isFailed */);
             }
 
-            // In both "valid" or "unusual_seq_num_leap" cases, trigger network validation
-            if (Flags.validateNetworkOnIpsecLoss()) {
-                // Trigger re-validation of the underlying network; if it fails, the VCN will
-                // attempt to migrate away.
-                mConnectivityManager.reportNetworkConnectivity(
-                        getNetwork(), false /* hasConnectivity */);
-            }
+            // In both "invalid" and "unusual_seq_num_leap" cases, trigger network validation. If
+            // validation fails, the VCN will attempt to migrate away.
+            mConnectivityManager.reportNetworkConnectivity(
+                    getNetwork(), false /* hasConnectivity */);
         }
     }
 
@@ -474,8 +468,7 @@
             boolean isUnusualSeqNumLeap = false;
 
             // Handle sequence number leap
-            if (Flags.handleSeqNumLeap()
-                    && maxSeqNumIncreasePerSecond != MAX_SEQ_NUM_INCREASE_DEFAULT_DISABLED) {
+            if (maxSeqNumIncreasePerSecond != MAX_SEQ_NUM_INCREASE_DEFAULT_DISABLED) {
                 final long timeDiffMillis =
                         newState.getTimestampMillis() - oldState.getTimestampMillis();
                 final long maxSeqNumIncrease = timeDiffMillis * maxSeqNumIncreasePerSecond / 1000;
@@ -506,7 +499,7 @@
                             + " actualPktCntDiff: "
                             + actualPktCntDiff);
 
-            if (Flags.handleSeqNumLeap() && expectedPktCntDiff < MIN_VALID_EXPECTED_RX_PACKET_NUM) {
+            if (expectedPktCntDiff < MIN_VALID_EXPECTED_RX_PACKET_NUM) {
                 // The sample size is too small to ensure a reliable detection result
                 return PacketLossCalculationResult.invalid();
             }
diff --git a/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluator.java b/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluator.java
index 78e06d4..c852fb4 100644
--- a/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluator.java
+++ b/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluator.java
@@ -25,7 +25,6 @@
 import android.net.LinkProperties;
 import android.net.Network;
 import android.net.NetworkCapabilities;
-import android.net.vcn.Flags;
 import android.net.vcn.VcnManager;
 import android.net.vcn.VcnUnderlyingNetworkTemplate;
 import android.os.Handler;
@@ -297,10 +296,8 @@
         updatePriorityClass(
                 underlyingNetworkTemplates, subscriptionGroup, lastSnapshot, carrierConfig);
 
-        if (Flags.evaluateIpsecLossOnLpNcChange()) {
-            for (NetworkMetricMonitor monitor : mMetricMonitors) {
-                monitor.onLinkPropertiesOrCapabilitiesChanged();
-            }
+        for (NetworkMetricMonitor monitor : mMetricMonitors) {
+            monitor.onLinkPropertiesOrCapabilitiesChanged();
         }
     }
 
@@ -316,10 +313,8 @@
         updatePriorityClass(
                 underlyingNetworkTemplates, subscriptionGroup, lastSnapshot, carrierConfig);
 
-        if (Flags.evaluateIpsecLossOnLpNcChange()) {
-            for (NetworkMetricMonitor monitor : mMetricMonitors) {
-                monitor.onLinkPropertiesOrCapabilitiesChanged();
-            }
+        for (NetworkMetricMonitor monitor : mMetricMonitors) {
+            monitor.onLinkPropertiesOrCapabilitiesChanged();
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 49086af..7b27084 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -5807,6 +5807,12 @@
     }
 
     private boolean canMoveTaskToBack(Task task) {
+        // Checks whether a task is a child of this task because it can be reparetned when
+        // transition is deferred.
+        if (task != this && task.getParent() != this) {
+            return false;
+        }
+
         // In LockTask mode, moving a locked task to the back of the root task may expose unlocked
         // ones. Therefore we need to check if this operation is allowed.
         if (!mAtmService.getLockTaskController().canMoveTaskToBack(task)) {
@@ -5876,7 +5882,7 @@
                     (deferred) -> {
                         // Need to check again if deferred since the system might
                         // be in a different state.
-                        if (!isAttached() || (deferred && !canMoveTaskToBack(tr))) {
+                        if (!tr.isAttached() || (deferred && !canMoveTaskToBack(tr))) {
                             Slog.e(TAG, "Failed to move task to back after saying we could: "
                                     + tr.mTaskId);
                             transition.abort();
diff --git a/services/tests/security/forensic/OWNERS b/services/tests/security/forensic/OWNERS
new file mode 100644
index 0000000..80c9afb9
--- /dev/null
+++ b/services/tests/security/forensic/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 36824
+
+file:platform/frameworks/base:main:/core/java/android/security/forensic/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java b/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java
index eb9cce0..d1f6c2f 100644
--- a/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java
@@ -69,7 +69,6 @@
 import com.android.internal.R;
 import com.android.internal.pm.parsing.PackageParser2;
 import com.android.server.compat.PlatformCompat;
-import com.android.server.integrity.engine.RuleEvaluationEngine;
 import com.android.server.integrity.model.IntegrityCheckResult;
 import com.android.server.pm.parsing.TestPackageParser2;
 import com.android.server.testutils.TestUtils;
@@ -138,7 +137,6 @@
     @Mock PlatformCompat mPlatformCompat;
     @Mock Context mMockContext;
     @Mock Resources mMockResources;
-    @Mock RuleEvaluationEngine mRuleEvaluationEngine;
     @Mock IntegrityFileManager mIntegrityFileManager;
     @Mock Handler mHandler;
 
@@ -176,7 +174,6 @@
                         mMockContext,
                         mPackageManagerInternal,
                         mParserSupplier,
-                        mRuleEvaluationEngine,
                         mIntegrityFileManager,
                         mHandler);
 
@@ -307,91 +304,6 @@
     }
 
     @Test
-    public void handleBroadcast_correctArgs() throws Exception {
-        allowlistUsAsRuleProvider();
-        makeUsSystemApp();
-        ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
-                ArgumentCaptor.forClass(BroadcastReceiver.class);
-        verify(mMockContext)
-                .registerReceiver(broadcastReceiverCaptor.capture(), any(), any(), any());
-        Intent intent = makeVerificationIntent();
-        when(mRuleEvaluationEngine.evaluate(any())).thenReturn(IntegrityCheckResult.allow());
-
-        broadcastReceiverCaptor.getValue().onReceive(mMockContext, intent);
-        runJobInHandler();
-
-        ArgumentCaptor<AppInstallMetadata> metadataCaptor =
-                ArgumentCaptor.forClass(AppInstallMetadata.class);
-        verify(mRuleEvaluationEngine).evaluate(metadataCaptor.capture());
-        AppInstallMetadata appInstallMetadata = metadataCaptor.getValue();
-        assertEquals(PACKAGE_NAME, appInstallMetadata.getPackageName());
-        assertThat(appInstallMetadata.getAppCertificates()).containsExactly(APP_CERT);
-        assertEquals(INSTALLER_SHA256, appInstallMetadata.getInstallerName());
-        // we cannot check installer cert because it seems to be device specific.
-        assertEquals(VERSION_CODE, appInstallMetadata.getVersionCode());
-        assertFalse(appInstallMetadata.isPreInstalled());
-        // Asserting source stamp not present.
-        assertFalse(appInstallMetadata.isStampPresent());
-        assertFalse(appInstallMetadata.isStampVerified());
-        assertFalse(appInstallMetadata.isStampTrusted());
-        assertNull(appInstallMetadata.getStampCertificateHash());
-        // These are hardcoded in the test apk android manifest
-        Map<String, String> allowedInstallers =
-                appInstallMetadata.getAllowedInstallersAndCertificates();
-        assertEquals(2, allowedInstallers.size());
-        assertEquals(PLAY_STORE_CERT, allowedInstallers.get(PLAY_STORE_PKG));
-        assertEquals(INSTALLER_CERTIFICATE_NOT_EVALUATED, allowedInstallers.get(ADB_INSTALLER));
-    }
-
-    @Test
-    public void handleBroadcast_correctArgs_multipleCerts() throws Exception {
-        allowlistUsAsRuleProvider();
-        makeUsSystemApp();
-        ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
-                ArgumentCaptor.forClass(BroadcastReceiver.class);
-        verify(mMockContext)
-                .registerReceiver(broadcastReceiverCaptor.capture(), any(), any(), any());
-        Intent intent = makeVerificationIntent();
-        intent.setDataAndType(Uri.fromFile(mTestApkTwoCerts), PACKAGE_MIME_TYPE);
-        when(mRuleEvaluationEngine.evaluate(any())).thenReturn(IntegrityCheckResult.allow());
-
-        broadcastReceiverCaptor.getValue().onReceive(mMockContext, intent);
-        runJobInHandler();
-
-        ArgumentCaptor<AppInstallMetadata> metadataCaptor =
-                ArgumentCaptor.forClass(AppInstallMetadata.class);
-        verify(mRuleEvaluationEngine).evaluate(metadataCaptor.capture());
-        AppInstallMetadata appInstallMetadata = metadataCaptor.getValue();
-        assertThat(appInstallMetadata.getAppCertificates())
-                .containsExactly(DUMMY_APP_TWO_CERTS_CERT_1, DUMMY_APP_TWO_CERTS_CERT_2);
-    }
-
-    @Test
-    public void handleBroadcast_correctArgs_sourceStamp() throws Exception {
-        allowlistUsAsRuleProvider();
-        makeUsSystemApp();
-        ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
-                ArgumentCaptor.forClass(BroadcastReceiver.class);
-        verify(mMockContext)
-                .registerReceiver(broadcastReceiverCaptor.capture(), any(), any(), any());
-        Intent intent = makeVerificationIntent();
-        intent.setDataAndType(Uri.fromFile(mTestApkSourceStamp), PACKAGE_MIME_TYPE);
-        when(mRuleEvaluationEngine.evaluate(any())).thenReturn(IntegrityCheckResult.allow());
-
-        broadcastReceiverCaptor.getValue().onReceive(mMockContext, intent);
-        runJobInHandler();
-
-        ArgumentCaptor<AppInstallMetadata> metadataCaptor =
-                ArgumentCaptor.forClass(AppInstallMetadata.class);
-        verify(mRuleEvaluationEngine).evaluate(metadataCaptor.capture());
-        AppInstallMetadata appInstallMetadata = metadataCaptor.getValue();
-        assertTrue(appInstallMetadata.isStampPresent());
-        assertTrue(appInstallMetadata.isStampVerified());
-        assertTrue(appInstallMetadata.isStampTrusted());
-        assertEquals(SOURCE_STAMP_CERTIFICATE_HASH, appInstallMetadata.getStampCertificateHash());
-    }
-
-    @Test
     public void handleBroadcast_allow() throws Exception {
         allowlistUsAsRuleProvider();
         makeUsSystemApp();
@@ -400,7 +312,6 @@
         verify(mMockContext)
                 .registerReceiver(broadcastReceiverCaptor.capture(), any(), any(), any());
         Intent intent = makeVerificationIntent();
-        when(mRuleEvaluationEngine.evaluate(any())).thenReturn(IntegrityCheckResult.allow());
 
         broadcastReceiverCaptor.getValue().onReceive(mMockContext, intent);
         runJobInHandler();
@@ -411,32 +322,6 @@
     }
 
     @Test
-    public void handleBroadcast_reject() throws Exception {
-        allowlistUsAsRuleProvider();
-        makeUsSystemApp();
-        ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
-                ArgumentCaptor.forClass(BroadcastReceiver.class);
-        verify(mMockContext)
-                .registerReceiver(broadcastReceiverCaptor.capture(), any(), any(), any());
-        when(mRuleEvaluationEngine.evaluate(any()))
-                .thenReturn(
-                        IntegrityCheckResult.deny(
-                                Arrays.asList(
-                                        new Rule(
-                                                new AtomicFormula.BooleanAtomicFormula(
-                                                        AtomicFormula.PRE_INSTALLED, false),
-                                                Rule.DENY))));
-        Intent intent = makeVerificationIntent();
-
-        broadcastReceiverCaptor.getValue().onReceive(mMockContext, intent);
-        runJobInHandler();
-
-        verify(mPackageManagerInternal)
-                .setIntegrityVerificationResult(
-                        1, PackageManagerInternal.INTEGRITY_VERIFICATION_REJECT);
-    }
-
-    @Test
     public void handleBroadcast_notInitialized() throws Exception {
         allowlistUsAsRuleProvider();
         makeUsSystemApp();
@@ -446,7 +331,6 @@
         verify(mMockContext)
                 .registerReceiver(broadcastReceiverCaptor.capture(), any(), any(), any());
         Intent intent = makeVerificationIntent();
-        when(mRuleEvaluationEngine.evaluate(any())).thenReturn(IntegrityCheckResult.allow());
 
         broadcastReceiverCaptor.getValue().onReceive(mMockContext, intent);
         runJobInHandler();
@@ -467,8 +351,6 @@
         verify(mMockContext, atLeastOnce())
                 .registerReceiver(broadcastReceiverCaptor.capture(), any(), any(), any());
         Intent intent = makeVerificationIntent(TEST_FRAMEWORK_PACKAGE);
-        when(mRuleEvaluationEngine.evaluate(any()))
-                .thenReturn(IntegrityCheckResult.deny(/* rule= */ null));
 
         broadcastReceiverCaptor.getValue().onReceive(mMockContext, intent);
         runJobInHandler();
diff --git a/services/tests/servicestests/src/com/android/server/integrity/engine/RuleEvaluationEngineTest.java b/services/tests/servicestests/src/com/android/server/integrity/engine/RuleEvaluationEngineTest.java
deleted file mode 100644
index 1c860ca..0000000
--- a/services/tests/servicestests/src/com/android/server/integrity/engine/RuleEvaluationEngineTest.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * 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.
- */
-
-package com.android.server.integrity.engine;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.when;
-
-import android.content.integrity.AppInstallMetadata;
-import android.content.integrity.IntegrityFormula;
-import android.content.integrity.Rule;
-
-import com.android.server.integrity.IntegrityFileManager;
-import com.android.server.integrity.model.IntegrityCheckResult;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-@RunWith(JUnit4.class)
-public class RuleEvaluationEngineTest {
-
-    private static final String INSTALLER_1 = "installer1";
-    private static final String INSTALLER_1_CERT = "installer1_cert";
-    private static final String INSTALLER_2 = "installer2";
-    private static final String INSTALLER_2_CERT = "installer2_cert";
-
-    private static final String RANDOM_INSTALLER = "random";
-    private static final String RANDOM_INSTALLER_CERT = "random_cert";
-
-    @Mock
-    private IntegrityFileManager mIntegrityFileManager;
-
-    private RuleEvaluationEngine mEngine;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        mEngine = new RuleEvaluationEngine(mIntegrityFileManager);
-
-        when(mIntegrityFileManager.readRules(any())).thenReturn(Collections.singletonList(new Rule(
-                IntegrityFormula.Installer.notAllowedByManifest(), Rule.DENY)));
-
-        when(mIntegrityFileManager.initialized()).thenReturn(true);
-    }
-
-    @Test
-    public void testAllowedInstallers_empty() {
-        AppInstallMetadata appInstallMetadata1 =
-                getAppInstallMetadataBuilder()
-                        .setInstallerName(INSTALLER_1)
-                        .setInstallerCertificates(Collections.singletonList(INSTALLER_1_CERT))
-                        .build();
-        AppInstallMetadata appInstallMetadata2 =
-                getAppInstallMetadataBuilder()
-                        .setInstallerName(INSTALLER_2)
-                        .setInstallerCertificates(Collections.singletonList(INSTALLER_2_CERT))
-                        .build();
-        AppInstallMetadata appInstallMetadata3 =
-                getAppInstallMetadataBuilder()
-                        .setInstallerName(RANDOM_INSTALLER)
-                        .setInstallerCertificates(Collections.singletonList(RANDOM_INSTALLER_CERT))
-                        .build();
-
-        assertThat(mEngine.evaluate(appInstallMetadata1).getEffect())
-                .isEqualTo(IntegrityCheckResult.Effect.ALLOW);
-        assertThat(mEngine.evaluate(appInstallMetadata2).getEffect())
-                .isEqualTo(IntegrityCheckResult.Effect.ALLOW);
-        assertThat(mEngine.evaluate(appInstallMetadata3).getEffect())
-                .isEqualTo(IntegrityCheckResult.Effect.ALLOW);
-    }
-
-    @Test
-    public void testAllowedInstallers_oneElement() {
-        Map<String, String> allowedInstallers =
-                Collections.singletonMap(INSTALLER_1, INSTALLER_1_CERT);
-
-        AppInstallMetadata appInstallMetadata1 =
-                getAppInstallMetadataBuilder()
-                        .setInstallerName(INSTALLER_1)
-                        .setInstallerCertificates(Collections.singletonList(INSTALLER_1_CERT))
-                        .setAllowedInstallersAndCert(allowedInstallers)
-                        .build();
-        assertThat(mEngine.evaluate(appInstallMetadata1).getEffect())
-                .isEqualTo(IntegrityCheckResult.Effect.ALLOW);
-
-        AppInstallMetadata appInstallMetadata2 =
-                getAppInstallMetadataBuilder()
-                        .setInstallerName(RANDOM_INSTALLER)
-                        .setAllowedInstallersAndCert(allowedInstallers)
-                        .setInstallerCertificates(Collections.singletonList(INSTALLER_1_CERT))
-                        .build();
-        assertThat(mEngine.evaluate(appInstallMetadata2).getEffect())
-                .isEqualTo(IntegrityCheckResult.Effect.DENY);
-
-        AppInstallMetadata appInstallMetadata3 =
-                getAppInstallMetadataBuilder()
-                        .setInstallerName(INSTALLER_1)
-                        .setAllowedInstallersAndCert(allowedInstallers)
-                        .setInstallerCertificates(Collections.singletonList(RANDOM_INSTALLER_CERT))
-                        .build();
-        assertThat(mEngine.evaluate(appInstallMetadata3).getEffect())
-                .isEqualTo(IntegrityCheckResult.Effect.DENY);
-
-        AppInstallMetadata appInstallMetadata4 =
-                getAppInstallMetadataBuilder()
-                        .setInstallerName(INSTALLER_1)
-                        .setAllowedInstallersAndCert(allowedInstallers)
-                        .setInstallerCertificates(Collections.singletonList(RANDOM_INSTALLER_CERT))
-                        .build();
-        assertThat(mEngine.evaluate(appInstallMetadata4).getEffect())
-                .isEqualTo(IntegrityCheckResult.Effect.DENY);
-    }
-
-    @Test
-    public void testAllowedInstallers_multipleElement() {
-        Map<String, String> allowedInstallers = new HashMap<>(2);
-        allowedInstallers.put(INSTALLER_1, INSTALLER_1_CERT);
-        allowedInstallers.put(INSTALLER_2, INSTALLER_2_CERT);
-
-        AppInstallMetadata appInstallMetadata1 =
-                getAppInstallMetadataBuilder()
-                        .setInstallerName(INSTALLER_1)
-                        .setAllowedInstallersAndCert(allowedInstallers)
-                        .setInstallerCertificates(Collections.singletonList(INSTALLER_1_CERT))
-                        .build();
-        assertThat(mEngine.evaluate(appInstallMetadata1).getEffect())
-                .isEqualTo(IntegrityCheckResult.Effect.ALLOW);
-
-        AppInstallMetadata appInstallMetadata2 =
-                getAppInstallMetadataBuilder()
-                        .setInstallerName(INSTALLER_2)
-                        .setAllowedInstallersAndCert(allowedInstallers)
-                        .setInstallerCertificates(Collections.singletonList(INSTALLER_2_CERT))
-                        .build();
-        assertThat(mEngine.evaluate(appInstallMetadata2).getEffect())
-                .isEqualTo(IntegrityCheckResult.Effect.ALLOW);
-
-        AppInstallMetadata appInstallMetadata3 =
-                getAppInstallMetadataBuilder()
-                        .setInstallerName(INSTALLER_1)
-                        .setAllowedInstallersAndCert(allowedInstallers)
-                        .setInstallerCertificates(Collections.singletonList(INSTALLER_2_CERT))
-                        .build();
-        assertThat(mEngine.evaluate(appInstallMetadata3).getEffect())
-                .isEqualTo(IntegrityCheckResult.Effect.DENY);
-
-        AppInstallMetadata appInstallMetadata4 =
-                getAppInstallMetadataBuilder()
-                        .setInstallerName(INSTALLER_2)
-                        .setAllowedInstallersAndCert(allowedInstallers)
-                        .setInstallerCertificates(Collections.singletonList(INSTALLER_1_CERT))
-                        .build();
-        assertThat(mEngine.evaluate(appInstallMetadata4).getEffect())
-                .isEqualTo(IntegrityCheckResult.Effect.DENY);
-    }
-
-    /** Returns a builder with all fields filled with some placeholder data. */
-    private AppInstallMetadata.Builder getAppInstallMetadataBuilder() {
-        return new AppInstallMetadata.Builder()
-                .setPackageName("abc")
-                .setAppCertificates(Collections.singletonList("abc"))
-                .setAppCertificateLineage(Collections.singletonList("abc"))
-                .setInstallerCertificates(Collections.singletonList("abc"))
-                .setInstallerName("abc")
-                .setVersionCode(-1)
-                .setIsPreInstalled(true);
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/integrity/engine/RuleEvaluatorTest.java b/services/tests/servicestests/src/com/android/server/integrity/engine/RuleEvaluatorTest.java
deleted file mode 100644
index 5089f74..0000000
--- a/services/tests/servicestests/src/com/android/server/integrity/engine/RuleEvaluatorTest.java
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * 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.
- */
-
-package com.android.server.integrity.engine;
-
-import static com.android.server.integrity.model.IntegrityCheckResult.Effect.ALLOW;
-import static com.android.server.integrity.model.IntegrityCheckResult.Effect.DENY;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.integrity.AppInstallMetadata;
-import android.content.integrity.AtomicFormula;
-import android.content.integrity.AtomicFormula.LongAtomicFormula;
-import android.content.integrity.AtomicFormula.StringAtomicFormula;
-import android.content.integrity.CompoundFormula;
-import android.content.integrity.Rule;
-
-import com.android.server.integrity.model.IntegrityCheckResult;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-@RunWith(JUnit4.class)
-public class RuleEvaluatorTest {
-
-    private static final String PACKAGE_NAME_1 = "com.test.app";
-    private static final String PACKAGE_NAME_2 = "com.test.app2";
-    private static final String APP_CERTIFICATE = "test_cert";
-    private static final AppInstallMetadata APP_INSTALL_METADATA =
-            new AppInstallMetadata.Builder()
-                    .setPackageName(PACKAGE_NAME_1)
-                    .setAppCertificates(Collections.singletonList(APP_CERTIFICATE))
-                    .setAppCertificateLineage(Collections.singletonList(APP_CERTIFICATE))
-                    .setVersionCode(2)
-                    .build();
-
-    @Test
-    public void testEvaluateRules_noRules_allow() {
-        List<Rule> rules = new ArrayList<>();
-
-        IntegrityCheckResult result = RuleEvaluator.evaluateRules(rules, APP_INSTALL_METADATA);
-
-        assertThat(result.getEffect()).isEqualTo(ALLOW);
-    }
-
-    @Test
-    public void testEvaluateRules_noMatchedRules_allow() {
-        Rule rule =
-                new Rule(
-                        new StringAtomicFormula(
-                                AtomicFormula.PACKAGE_NAME,
-                                PACKAGE_NAME_2,
-                                /* isHashedValue= */ false),
-                        Rule.DENY);
-
-        IntegrityCheckResult result =
-                RuleEvaluator.evaluateRules(Collections.singletonList(rule), APP_INSTALL_METADATA);
-
-        assertThat(result.getEffect()).isEqualTo(ALLOW);
-    }
-
-    @Test
-    public void testEvaluateRules_oneMatch_deny() {
-        Rule rule1 =
-                new Rule(
-                        new StringAtomicFormula(
-                                AtomicFormula.PACKAGE_NAME,
-                                PACKAGE_NAME_1,
-                                /* isHashedValue= */ false),
-                        Rule.DENY);
-        Rule rule2 =
-                new Rule(
-                        new StringAtomicFormula(
-                                AtomicFormula.PACKAGE_NAME,
-                                PACKAGE_NAME_2,
-                                /* isHashedValue= */ false),
-                        Rule.DENY);
-
-        IntegrityCheckResult result =
-                RuleEvaluator.evaluateRules(Arrays.asList(rule1, rule2), APP_INSTALL_METADATA);
-
-        assertThat(result.getEffect()).isEqualTo(DENY);
-        assertThat(result.getMatchedRules()).containsExactly(rule1);
-    }
-
-    @Test
-    public void testEvaluateRules_multipleMatches_deny() {
-        Rule rule1 =
-                new Rule(
-                        new StringAtomicFormula(
-                                AtomicFormula.PACKAGE_NAME,
-                                PACKAGE_NAME_1,
-                                /* isHashedValue= */ false),
-                        Rule.DENY);
-        Rule rule2 = new Rule(
-                new CompoundFormula(
-                        CompoundFormula.AND,
-                        Arrays.asList(
-                                new StringAtomicFormula(
-                                        AtomicFormula.PACKAGE_NAME,
-                                        PACKAGE_NAME_1,
-                                        /* isHashedValue= */ false),
-                                new StringAtomicFormula(
-                                        AtomicFormula.APP_CERTIFICATE,
-                                        APP_CERTIFICATE,
-                                        /* isHashedValue= */ false))),
-                Rule.DENY);
-
-        IntegrityCheckResult result =
-                RuleEvaluator.evaluateRules(Arrays.asList(rule1, rule2), APP_INSTALL_METADATA);
-
-        assertThat(result.getEffect()).isEqualTo(DENY);
-        assertThat(result.getMatchedRules()).containsExactly(rule1, rule2);
-    }
-
-    @Test
-    public void testEvaluateRules_ruleWithNot_deny() {
-        Rule rule = new Rule(
-                new CompoundFormula(
-                        CompoundFormula.NOT,
-                        Collections.singletonList(
-                                new StringAtomicFormula(
-                                        AtomicFormula.PACKAGE_NAME,
-                                        PACKAGE_NAME_2,
-                                        /* isHashedValue= */ false))),
-                Rule.DENY);
-
-        IntegrityCheckResult result =
-                RuleEvaluator.evaluateRules(Collections.singletonList(rule), APP_INSTALL_METADATA);
-
-        assertThat(result.getEffect()).isEqualTo(DENY);
-        assertThat(result.getMatchedRules()).containsExactly(rule);
-    }
-
-    @Test
-    public void testEvaluateRules_ruleWithIntegerOperators_deny() {
-        Rule rule =
-                new Rule(
-                        new LongAtomicFormula(AtomicFormula.VERSION_CODE,
-                                AtomicFormula.GT, 1),
-                        Rule.DENY);
-
-        IntegrityCheckResult result =
-                RuleEvaluator.evaluateRules(Collections.singletonList(rule), APP_INSTALL_METADATA);
-
-        assertThat(result.getEffect()).isEqualTo(DENY);
-        assertThat(result.getMatchedRules()).containsExactly(rule);
-    }
-
-    @Test
-    public void testEvaluateRules_validForm_deny() {
-        Rule rule = new Rule(
-                new CompoundFormula(
-                        CompoundFormula.AND,
-                        Arrays.asList(
-                                new StringAtomicFormula(
-                                        AtomicFormula.PACKAGE_NAME,
-                                        PACKAGE_NAME_1,
-                                        /* isHashedValue= */ false),
-                                new StringAtomicFormula(
-                                        AtomicFormula.APP_CERTIFICATE,
-                                        APP_CERTIFICATE,
-                                        /* isHashedValue= */ false))),
-                Rule.DENY);
-
-        IntegrityCheckResult result =
-                RuleEvaluator.evaluateRules(Collections.singletonList(rule), APP_INSTALL_METADATA);
-
-        assertThat(result.getEffect()).isEqualTo(DENY);
-        assertThat(result.getMatchedRules()).containsExactly(rule);
-    }
-
-    @Test
-    public void testEvaluateRules_orRules() {
-        Rule rule = new Rule(
-                new CompoundFormula(
-                        CompoundFormula.OR,
-                        Arrays.asList(
-                                new StringAtomicFormula(
-                                        AtomicFormula.PACKAGE_NAME,
-                                        PACKAGE_NAME_1,
-                                        /* isHashedValue= */ false),
-                                new StringAtomicFormula(
-                                        AtomicFormula.APP_CERTIFICATE,
-                                        APP_CERTIFICATE,
-                                        /* isHashedValue= */ false))),
-                Rule.DENY);
-
-        IntegrityCheckResult result =
-                RuleEvaluator.evaluateRules(Collections.singletonList(rule), APP_INSTALL_METADATA);
-
-        assertThat(result.getEffect()).isEqualTo(DENY);
-        assertThat(result.getMatchedRules()).containsExactly(rule);
-    }
-
-    @Test
-    public void testEvaluateRules_compoundFormulaWithNot_deny() {
-        CompoundFormula openSubFormula =
-                new CompoundFormula(
-                        CompoundFormula.AND,
-                        Arrays.asList(
-                                new StringAtomicFormula(
-                                        AtomicFormula.PACKAGE_NAME,
-                                        PACKAGE_NAME_2,
-                                        /* isHashedValue= */ false),
-                                new StringAtomicFormula(
-                                        AtomicFormula.APP_CERTIFICATE,
-                                        APP_CERTIFICATE,
-                                        /* isHashedValue= */ false)));
-        CompoundFormula compoundFormula =
-                new CompoundFormula(CompoundFormula.NOT, Collections.singletonList(openSubFormula));
-        Rule rule = new Rule(compoundFormula, Rule.DENY);
-
-        IntegrityCheckResult result =
-                RuleEvaluator.evaluateRules(Collections.singletonList(rule), APP_INSTALL_METADATA);
-
-        assertThat(result.getEffect()).isEqualTo(DENY);
-        assertThat(result.getMatchedRules()).containsExactly(rule);
-    }
-
-    @Test
-    public void testEvaluateRules_forceAllow() {
-        Rule rule1 =
-                new Rule(
-                        new StringAtomicFormula(
-                                AtomicFormula.PACKAGE_NAME,
-                                PACKAGE_NAME_1,
-                                /* isHashedValue= */ false),
-                        Rule.FORCE_ALLOW);
-        Rule rule2 = new Rule(
-                new CompoundFormula(
-                        CompoundFormula.AND,
-                        Arrays.asList(
-                                new StringAtomicFormula(
-                                        AtomicFormula.PACKAGE_NAME,
-                                        PACKAGE_NAME_1,
-                                        /* isHashedValue= */ false),
-                                new StringAtomicFormula(
-                                        AtomicFormula.APP_CERTIFICATE,
-                                        APP_CERTIFICATE,
-                                        /* isHashedValue= */ false))),
-                Rule.DENY);
-
-        IntegrityCheckResult result =
-                RuleEvaluator.evaluateRules(Arrays.asList(rule1, rule2), APP_INSTALL_METADATA);
-
-        assertThat(result.getEffect()).isEqualTo(ALLOW);
-        assertThat(result.getMatchedRules()).containsExactly(rule1);
-    }
-
-    @Test
-    public void testEvaluateRules_multipleMatches_forceAllow() {
-        Rule rule1 =
-                new Rule(
-                        new StringAtomicFormula(
-                                AtomicFormula.PACKAGE_NAME,
-                                PACKAGE_NAME_1,
-                                /* isHashedValue= */ false),
-                        Rule.FORCE_ALLOW);
-        Rule rule2 = new Rule(
-                new CompoundFormula(
-                        CompoundFormula.AND,
-                        Arrays.asList(
-                                new StringAtomicFormula(
-                                        AtomicFormula.PACKAGE_NAME,
-                                        PACKAGE_NAME_1,
-                                        /* isHashedValue= */ false),
-                                new StringAtomicFormula(
-                                        AtomicFormula.APP_CERTIFICATE,
-                                        APP_CERTIFICATE,
-                                        /* isHashedValue= */ false))),
-                Rule.FORCE_ALLOW);
-
-        IntegrityCheckResult result =
-                RuleEvaluator.evaluateRules(Arrays.asList(rule1, rule2), APP_INSTALL_METADATA);
-
-        assertThat(result.getEffect()).isEqualTo(ALLOW);
-        assertThat(result.getMatchedRules()).containsExactly(rule1, rule2);
-    }
-}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/integrity/model/IntegrityCheckResultTest.java b/services/tests/servicestests/src/com/android/server/integrity/model/IntegrityCheckResultTest.java
index 6c23ff6..d31ed68 100644
--- a/services/tests/servicestests/src/com/android/server/integrity/model/IntegrityCheckResultTest.java
+++ b/services/tests/servicestests/src/com/android/server/integrity/model/IntegrityCheckResultTest.java
@@ -22,8 +22,6 @@
 import android.content.integrity.CompoundFormula;
 import android.content.integrity.Rule;
 
-import com.android.internal.util.FrameworkStatsLog;
-
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
@@ -40,8 +38,6 @@
 
         assertThat(allowResult.getEffect()).isEqualTo(IntegrityCheckResult.Effect.ALLOW);
         assertThat(allowResult.getMatchedRules()).isEmpty();
-        assertThat(allowResult.getLoggingResponse())
-                .isEqualTo(FrameworkStatsLog.INTEGRITY_CHECK_RESULT_REPORTED__RESPONSE__ALLOWED);
     }
 
     @Test
@@ -58,9 +54,6 @@
 
         assertThat(allowResult.getEffect()).isEqualTo(IntegrityCheckResult.Effect.ALLOW);
         assertThat(allowResult.getMatchedRules()).containsExactly(forceAllowRule);
-        assertThat(allowResult.getLoggingResponse())
-                .isEqualTo(
-                        FrameworkStatsLog.INTEGRITY_CHECK_RESULT_REPORTED__RESPONSE__FORCE_ALLOWED);
     }
 
     @Test
@@ -77,8 +70,6 @@
 
         assertThat(denyResult.getEffect()).isEqualTo(IntegrityCheckResult.Effect.DENY);
         assertThat(denyResult.getMatchedRules()).containsExactly(failedRule);
-        assertThat(denyResult.getLoggingResponse())
-                .isEqualTo(FrameworkStatsLog.INTEGRITY_CHECK_RESULT_REPORTED__RESPONSE__REJECTED);
     }
 
     @Test
diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
index 4cb7c91..7e0bbc4 100644
--- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
+++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
@@ -70,7 +70,6 @@
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
 import android.net.Uri;
-import android.net.vcn.Flags;
 import android.net.vcn.IVcnStatusCallback;
 import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
 import android.net.vcn.VcnConfig;
@@ -85,7 +84,6 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.test.TestLooper;
-import android.platform.test.flag.junit.SetFlagsRule;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
@@ -104,7 +102,6 @@
 import com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;
 
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
@@ -122,8 +119,6 @@
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class VcnManagementServiceTest {
-    @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
-
     private static final String CONTEXT_ATTRIBUTION_TAG = "VCN";
     private static final String TEST_PACKAGE_NAME =
             VcnManagementServiceTest.class.getPackage().getName();
@@ -285,8 +280,6 @@
 
     @Before
     public void setUp() {
-        mSetFlagsRule.enableFlags(Flags.FLAG_ENFORCE_MAIN_USER);
-
         doNothing()
                 .when(mMockContext)
                 .enforceCallingOrSelfPermission(
diff --git a/tests/vcn/java/com/android/server/vcn/routeselection/NetworkEvaluationTestBase.java b/tests/vcn/java/com/android/server/vcn/routeselection/NetworkEvaluationTestBase.java
index edad678..421e1ad 100644
--- a/tests/vcn/java/com/android/server/vcn/routeselection/NetworkEvaluationTestBase.java
+++ b/tests/vcn/java/com/android/server/vcn/routeselection/NetworkEvaluationTestBase.java
@@ -34,14 +34,12 @@
 import android.net.NetworkCapabilities;
 import android.net.TelephonyNetworkSpecifier;
 import android.net.vcn.FeatureFlags;
-import android.net.vcn.Flags;
 import android.os.Handler;
 import android.os.IPowerManager;
 import android.os.IThermalService;
 import android.os.ParcelUuid;
 import android.os.PowerManager;
 import android.os.test.TestLooper;
-import android.platform.test.flag.junit.SetFlagsRule;
 import android.telephony.TelephonyManager;
 
 import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
@@ -49,7 +47,6 @@
 import com.android.server.vcn.VcnNetworkProvider;
 
 import org.junit.Before;
-import org.junit.Rule;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
@@ -57,8 +54,6 @@
 import java.util.UUID;
 
 public abstract class NetworkEvaluationTestBase {
-    @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
-
     protected static final String SSID = "TestWifi";
     protected static final String SSID_OTHER = "TestWifiOther";
     protected static final String PLMN_ID = "123456";
@@ -120,10 +115,6 @@
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
 
-        mSetFlagsRule.enableFlags(Flags.FLAG_VALIDATE_NETWORK_ON_IPSEC_LOSS);
-        mSetFlagsRule.enableFlags(Flags.FLAG_EVALUATE_IPSEC_LOSS_ON_LP_NC_CHANGE);
-        mSetFlagsRule.enableFlags(Flags.FLAG_HANDLE_SEQ_NUM_LEAP);
-
         when(mNetwork.getNetId()).thenReturn(-1);
 
         mTestLooper = new TestLooper();
diff --git a/tools/hoststubgen/hoststubgen/Android.bp b/tools/hoststubgen/hoststubgen/Android.bp
index 4920f7b4..a5ff496 100644
--- a/tools/hoststubgen/hoststubgen/Android.bp
+++ b/tools/hoststubgen/hoststubgen/Android.bp
@@ -8,7 +8,7 @@
 
     // OWNER: g/ravenwood
     // Bug component: 25698
-    default_team: "trendy_team_framework_backstage_power",
+    default_team: "trendy_team_ravenwood",
 }
 
 // Visibility only for ravenwood prototype uses.
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt
index 165bb57..6d8d7b7 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt
@@ -27,7 +27,7 @@
 import com.android.hoststubgen.filters.KeepNativeFilter
 import com.android.hoststubgen.filters.OutputFilter
 import com.android.hoststubgen.filters.SanitizationFilter
-import com.android.hoststubgen.filters.createFilterFromTextPolicyFile
+import com.android.hoststubgen.filters.TextFileFilterPolicyParser
 import com.android.hoststubgen.filters.printAsTextPolicy
 import com.android.hoststubgen.utils.ClassFilter
 import com.android.hoststubgen.visitors.BaseAdapter
@@ -178,8 +178,10 @@
 
         // Next, "text based" filter, which allows to override polices without touching
         // the target code.
-        options.policyOverrideFile.ifSet {
-            filter = createFilterFromTextPolicyFile(it, allClasses, filter)
+        if (options.policyOverrideFiles.isNotEmpty()) {
+            val parser = TextFileFilterPolicyParser(allClasses, filter)
+            options.policyOverrideFiles.forEach(parser::parse)
+            filter = parser.createOutputFilter()
         }
 
         // Apply the implicit filter.
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGenOptions.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGenOptions.kt
index b083d89..55e853e 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGenOptions.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGenOptions.kt
@@ -100,7 +100,7 @@
         var defaultClassLoadHook: SetOnce<String?> = SetOnce(null),
         var defaultMethodCallHook: SetOnce<String?> = SetOnce(null),
 
-        var policyOverrideFile: SetOnce<String?> = SetOnce(null),
+        var policyOverrideFiles: MutableList<String> = mutableListOf(),
 
         var defaultPolicy: SetOnce<FilterPolicy> = SetOnce(FilterPolicy.Remove),
 
@@ -164,7 +164,7 @@
                         "--out-jar", "--out-impl-jar" -> ret.outJar.set(nextArg())
 
                         "--policy-override-file" ->
-                            ret.policyOverrideFile.set(nextArg())!!.ensureFileExists()
+                            ret.policyOverrideFiles.add(nextArg().ensureFileExists())
 
                         "--clean-up-on-error" -> ret.cleanUpOnError.set(true)
                         "--no-clean-up-on-error" -> ret.cleanUpOnError.set(false)
@@ -291,7 +291,7 @@
               annotationAllowedClassesFile=$annotationAllowedClassesFile,
               defaultClassLoadHook=$defaultClassLoadHook,
               defaultMethodCallHook=$defaultMethodCallHook,
-              policyOverrideFile=$policyOverrideFile,
+              policyOverrideFiles=${policyOverrideFiles.toTypedArray().contentToString()},
               defaultPolicy=$defaultPolicy,
               cleanUpOnError=$cleanUpOnError,
               enableClassChecker=$enableClassChecker,
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt
index 073b503..caf80eb 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt
@@ -23,13 +23,10 @@
 import com.android.hoststubgen.log
 import com.android.hoststubgen.normalizeTextLine
 import com.android.hoststubgen.whitespaceRegex
-import org.objectweb.asm.Opcodes
-import org.objectweb.asm.tree.ClassNode
-import java.io.BufferedReader
-import java.io.FileReader
+import java.io.File
 import java.io.PrintWriter
-import java.util.Objects
 import java.util.regex.Pattern
+import org.objectweb.asm.tree.ClassNode
 
 /**
  * Print a class node as a "keep" policy.
@@ -49,256 +46,56 @@
     }
 }
 
-/** Return true if [access] is either public or protected. */
-private fun isVisible(access: Int): Boolean {
-    return (access and (Opcodes.ACC_PUBLIC or Opcodes.ACC_PROTECTED)) != 0
-}
-
 private const val FILTER_REASON = "file-override"
 
-/**
- * Read a given "policy" file and return as an [OutputFilter]
- */
-fun createFilterFromTextPolicyFile(
-        filename: String,
-        classes: ClassNodes,
-        fallback: OutputFilter,
-        ): OutputFilter {
-    log.i("Loading offloaded annotations from $filename ...")
-    log.withIndent {
-        val subclassFilter = SubclassFilter(classes, fallback)
-        val packageFilter = PackageFilter(subclassFilter)
-        val imf = InMemoryOutputFilter(classes, packageFilter)
+private enum class SpecialClass {
+    NotSpecial,
+    Aidl,
+    FeatureFlags,
+    Sysprops,
+    RFile,
+}
 
-        var lineNo = 0
+class TextFileFilterPolicyParser(
+    private val classes: ClassNodes,
+    fallback: OutputFilter
+) {
+    private val subclassFilter = SubclassFilter(classes, fallback)
+    private val packageFilter = PackageFilter(subclassFilter)
+    private val imf = InMemoryOutputFilter(classes, packageFilter)
+    private var aidlPolicy: FilterPolicyWithReason? = null
+    private var featureFlagsPolicy: FilterPolicyWithReason? = null
+    private var syspropsPolicy: FilterPolicyWithReason? = null
+    private var rFilePolicy: FilterPolicyWithReason? = null
+    private val typeRenameSpec = mutableListOf<TextFilePolicyRemapperFilter.TypeRenameSpec>()
+    private val methodReplaceSpec =
+        mutableListOf<TextFilePolicyMethodReplaceFilter.MethodCallReplaceSpec>()
 
-        var aidlPolicy: FilterPolicyWithReason? = null
-        var featureFlagsPolicy: FilterPolicyWithReason? = null
-        var syspropsPolicy: FilterPolicyWithReason? = null
-        var rFilePolicy: FilterPolicyWithReason? = null
-        val typeRenameSpec = mutableListOf<TextFilePolicyRemapperFilter.TypeRenameSpec>()
-        val methodReplaceSpec =
-            mutableListOf<TextFilePolicyMethodReplaceFilter.MethodCallReplaceSpec>()
+    private lateinit var currentClassName: String
 
-        try {
-            BufferedReader(FileReader(filename)).use { reader ->
-                var className = ""
-
-                while (true) {
-                    var line = reader.readLine() ?: break
+    /**
+     * Read a given "policy" file and return as an [OutputFilter]
+     */
+    fun parse(file: String) {
+        log.i("Loading offloaded annotations from $file ...")
+        log.withIndent {
+            var lineNo = 0
+            try {
+                File(file).forEachLine {
                     lineNo++
-
-                    line = normalizeTextLine(line)
-
+                    val line = normalizeTextLine(it)
                     if (line.isEmpty()) {
-                        continue // skip empty lines.
+                        return@forEachLine // skip empty lines.
                     }
-
-
-                    // TODO: Method too long, break it up.
-
-                    val fields = line.split(whitespaceRegex).toTypedArray()
-                    when (fields[0].lowercase()) {
-                        "p", "package" -> {
-                            if (fields.size < 3) {
-                                throw ParseException("Package ('p') expects 2 fields.")
-                            }
-                            val name = fields[1]
-                            val rawPolicy = fields[2]
-                            if (resolveExtendingClass(name) != null) {
-                                throw ParseException("Package can't be a super class type")
-                            }
-                            if (resolveSpecialClass(name) != SpecialClass.NotSpecial) {
-                                throw ParseException("Package can't be a special class type")
-                            }
-                            if (rawPolicy.startsWith("!")) {
-                                throw ParseException("Package can't have a substitution")
-                            }
-                            if (rawPolicy.startsWith("~")) {
-                                throw ParseException("Package can't have a class load hook")
-                            }
-                            val policy = parsePolicy(rawPolicy)
-                            if (!policy.isUsableWithClasses) {
-                                throw ParseException("Package can't have policy '$policy'")
-                            }
-                            packageFilter.addPolicy(name, policy.withReason(FILTER_REASON))
-                        }
-
-                        "c", "class" -> {
-                            if (fields.size < 3) {
-                                throw ParseException("Class ('c') expects 2 fields.")
-                            }
-                            className = fields[1]
-
-                            // superClass is set when the class name starts with a "*".
-                            val superClass = resolveExtendingClass(className)
-
-                            // :aidl, etc?
-                            val classType = resolveSpecialClass(className)
-
-                            if (fields[2].startsWith("!")) {
-                                if (classType != SpecialClass.NotSpecial) {
-                                    // We could support it, but not needed at least for now.
-                                    throw ParseException(
-                                            "Special class can't have a substitution")
-                                }
-                                // It's a redirection class.
-                                val toClass = fields[2].substring(1)
-                                imf.setRedirectionClass(className, toClass)
-                            } else if (fields[2].startsWith("~")) {
-                                if (classType != SpecialClass.NotSpecial) {
-                                    // We could support it, but not needed at least for now.
-                                    throw ParseException(
-                                            "Special class can't have a class load hook")
-                                }
-                                // It's a class-load hook
-                                val callback = fields[2].substring(1)
-                                imf.setClassLoadHook(className, callback)
-                            } else {
-                                val policy = parsePolicy(fields[2])
-                                if (!policy.isUsableWithClasses) {
-                                    throw ParseException("Class can't have policy '$policy'")
-                                }
-                                Objects.requireNonNull(className)
-
-                                when (classType) {
-                                    SpecialClass.NotSpecial -> {
-                                        // TODO: Duplicate check, etc
-                                        if (superClass == null) {
-                                            imf.setPolicyForClass(
-                                                className, policy.withReason(FILTER_REASON)
-                                            )
-                                        } else {
-                                            subclassFilter.addPolicy(superClass,
-                                                policy.withReason("extends $superClass"))
-                                        }
-                                    }
-                                    SpecialClass.Aidl -> {
-                                        if (aidlPolicy != null) {
-                                            throw ParseException(
-                                                    "Policy for AIDL classes already defined")
-                                        }
-                                        aidlPolicy = policy.withReason(
-                                                "$FILTER_REASON (special-class AIDL)")
-                                    }
-                                    SpecialClass.FeatureFlags -> {
-                                        if (featureFlagsPolicy != null) {
-                                            throw ParseException(
-                                                    "Policy for feature flags already defined")
-                                        }
-                                        featureFlagsPolicy = policy.withReason(
-                                                "$FILTER_REASON (special-class feature flags)")
-                                    }
-                                    SpecialClass.Sysprops -> {
-                                        if (syspropsPolicy != null) {
-                                            throw ParseException(
-                                                    "Policy for sysprops already defined")
-                                        }
-                                        syspropsPolicy = policy.withReason(
-                                                "$FILTER_REASON (special-class sysprops)")
-                                    }
-                                    SpecialClass.RFile -> {
-                                        if (rFilePolicy != null) {
-                                            throw ParseException(
-                                                "Policy for R file already defined")
-                                        }
-                                        rFilePolicy = policy.withReason(
-                                            "$FILTER_REASON (special-class R file)")
-                                    }
-                                }
-                            }
-                        }
-
-                        "f", "field" -> {
-                            if (fields.size < 3) {
-                                throw ParseException("Field ('f') expects 2 fields.")
-                            }
-                            val name = fields[1]
-                            val policy = parsePolicy(fields[2])
-                            if (!policy.isUsableWithFields) {
-                                throw ParseException("Field can't have policy '$policy'")
-                            }
-                            Objects.requireNonNull(className)
-
-                            // TODO: Duplicate check, etc
-                            imf.setPolicyForField(className, name, policy.withReason(FILTER_REASON))
-                        }
-
-                        "m", "method" -> {
-                            if (fields.size < 4) {
-                                throw ParseException("Method ('m') expects 3 fields.")
-                            }
-                            val name = fields[1]
-                            val signature = fields[2]
-                            val policy = parsePolicy(fields[3])
-
-                            if (!policy.isUsableWithMethods) {
-                                throw ParseException("Method can't have policy '$policy'")
-                            }
-
-                            Objects.requireNonNull(className)
-
-                            imf.setPolicyForMethod(className, name, signature,
-                                    policy.withReason(FILTER_REASON))
-                            if (policy == FilterPolicy.Substitute) {
-                                val fromName = fields[3].substring(1)
-
-                                if (fromName == name) {
-                                    throw ParseException(
-                                            "Substitution must have a different name")
-                                }
-
-                                // Set the policy for the "from" method.
-                                imf.setPolicyForMethod(className, fromName, signature,
-                                    FilterPolicy.Keep.withReason(FILTER_REASON))
-
-                                val classAndMethod = splitWithLastPeriod(fromName)
-                                if (classAndMethod != null) {
-                                    // If the substitution target contains a ".", then
-                                    // it's a method call redirect.
-                                    methodReplaceSpec.add(
-                                        TextFilePolicyMethodReplaceFilter.MethodCallReplaceSpec(
-                                            className.toJvmClassName(),
-                                            name,
-                                            signature,
-                                            classAndMethod.first.toJvmClassName(),
-                                            classAndMethod.second,
-                                        )
-                                    )
-                                } else {
-                                    // It's an in-class replace.
-                                    // ("@RavenwoodReplace" equivalent)
-                                    imf.setRenameTo(className, fromName, signature, name)
-                                }
-                            }
-                        }
-                        "r", "rename" -> {
-                            if (fields.size < 3) {
-                                throw ParseException("Rename ('r') expects 2 fields.")
-                            }
-                            // Add ".*" to make it a prefix match.
-                            val pattern = Pattern.compile(fields[1] + ".*")
-
-                            // Removing the leading /'s from the prefix. This allows
-                            // using a single '/' as an empty suffix, which is useful to have a
-                            // "negative" rename rule to avoid subsequent raname's from getting
-                            // applied. (Which is needed for services.jar)
-                            val prefix = fields[2].trimStart('/')
-
-                            typeRenameSpec += TextFilePolicyRemapperFilter.TypeRenameSpec(
-                                pattern, prefix)
-                        }
-
-                        else -> {
-                            throw ParseException("Unknown directive \"${fields[0]}\"")
-                        }
-                    }
+                    parseLine(line)
                 }
+            } catch (e: ParseException) {
+                throw e.withSourceInfo(file, lineNo)
             }
-        } catch (e: ParseException) {
-            throw e.withSourceInfo(filename, lineNo)
         }
+    }
 
+    fun createOutputFilter(): OutputFilter {
         var ret: OutputFilter = imf
         if (typeRenameSpec.isNotEmpty()) {
             ret = TextFilePolicyRemapperFilter(typeRenameSpec, ret)
@@ -309,54 +106,271 @@
 
         // Wrap the in-memory-filter with AHF.
         ret = AndroidHeuristicsFilter(
-                classes, aidlPolicy, featureFlagsPolicy, syspropsPolicy, rFilePolicy, ret)
+            classes, aidlPolicy, featureFlagsPolicy, syspropsPolicy, rFilePolicy, ret
+        )
 
         return ret
     }
-}
 
-private enum class SpecialClass {
-    NotSpecial,
-    Aidl,
-    FeatureFlags,
-    Sysprops,
-    RFile,
-}
-
-private fun resolveSpecialClass(className: String): SpecialClass {
-    if (!className.startsWith(":")) {
-        return SpecialClass.NotSpecial
+    private fun parseLine(line: String) {
+        val fields = line.split(whitespaceRegex).toTypedArray()
+        when (fields[0].lowercase()) {
+            "p", "package" -> parsePackage(fields)
+            "c", "class" -> parseClass(fields)
+            "f", "field" -> parseField(fields)
+            "m", "method" -> parseMethod(fields)
+            "r", "rename" -> parseRename(fields)
+            else -> throw ParseException("Unknown directive \"${fields[0]}\"")
+        }
     }
-    when (className.lowercase()) {
-        ":aidl" -> return SpecialClass.Aidl
-        ":feature_flags" -> return SpecialClass.FeatureFlags
-        ":sysprops" -> return SpecialClass.Sysprops
-        ":r" -> return SpecialClass.RFile
-    }
-    throw ParseException("Invalid special class name \"$className\"")
-}
 
-private fun resolveExtendingClass(className: String): String? {
-    if (!className.startsWith("*")) {
-        return null
+    private fun resolveSpecialClass(className: String): SpecialClass {
+        if (!className.startsWith(":")) {
+            return SpecialClass.NotSpecial
+        }
+        when (className.lowercase()) {
+            ":aidl" -> return SpecialClass.Aidl
+            ":feature_flags" -> return SpecialClass.FeatureFlags
+            ":sysprops" -> return SpecialClass.Sysprops
+            ":r" -> return SpecialClass.RFile
+        }
+        throw ParseException("Invalid special class name \"$className\"")
     }
-    return className.substring(1)
-}
 
-private fun parsePolicy(s: String): FilterPolicy {
-    return when (s.lowercase()) {
-        "k", "keep" -> FilterPolicy.Keep
-        "t", "throw" -> FilterPolicy.Throw
-        "r", "remove" -> FilterPolicy.Remove
-        "kc", "keepclass" -> FilterPolicy.KeepClass
-        "i", "ignore" -> FilterPolicy.Ignore
-        "rdr", "redirect" -> FilterPolicy.Redirect
-        else -> {
-            if (s.startsWith("@")) {
-                FilterPolicy.Substitute
-            } else {
-                throw ParseException("Invalid policy \"$s\"")
+    private fun resolveExtendingClass(className: String): String? {
+        if (!className.startsWith("*")) {
+            return null
+        }
+        return className.substring(1)
+    }
+
+    private fun parsePolicy(s: String): FilterPolicy {
+        return when (s.lowercase()) {
+            "k", "keep" -> FilterPolicy.Keep
+            "t", "throw" -> FilterPolicy.Throw
+            "r", "remove" -> FilterPolicy.Remove
+            "kc", "keepclass" -> FilterPolicy.KeepClass
+            "i", "ignore" -> FilterPolicy.Ignore
+            "rdr", "redirect" -> FilterPolicy.Redirect
+            else -> {
+                if (s.startsWith("@")) {
+                    FilterPolicy.Substitute
+                } else {
+                    throw ParseException("Invalid policy \"$s\"")
+                }
             }
         }
     }
+
+    private fun parsePackage(fields: Array<String>) {
+        if (fields.size < 3) {
+            throw ParseException("Package ('p') expects 2 fields.")
+        }
+        val name = fields[1]
+        val rawPolicy = fields[2]
+        if (resolveExtendingClass(name) != null) {
+            throw ParseException("Package can't be a super class type")
+        }
+        if (resolveSpecialClass(name) != SpecialClass.NotSpecial) {
+            throw ParseException("Package can't be a special class type")
+        }
+        if (rawPolicy.startsWith("!")) {
+            throw ParseException("Package can't have a substitution")
+        }
+        if (rawPolicy.startsWith("~")) {
+            throw ParseException("Package can't have a class load hook")
+        }
+        val policy = parsePolicy(rawPolicy)
+        if (!policy.isUsableWithClasses) {
+            throw ParseException("Package can't have policy '$policy'")
+        }
+        packageFilter.addPolicy(name, policy.withReason(FILTER_REASON))
+    }
+
+    private fun parseClass(fields: Array<String>) {
+        if (fields.size < 3) {
+            throw ParseException("Class ('c') expects 2 fields.")
+        }
+        currentClassName = fields[1]
+
+        // superClass is set when the class name starts with a "*".
+        val superClass = resolveExtendingClass(currentClassName)
+
+        // :aidl, etc?
+        val classType = resolveSpecialClass(currentClassName)
+
+        if (fields[2].startsWith("!")) {
+            if (classType != SpecialClass.NotSpecial) {
+                // We could support it, but not needed at least for now.
+                throw ParseException(
+                    "Special class can't have a substitution"
+                )
+            }
+            // It's a redirection class.
+            val toClass = fields[2].substring(1)
+            imf.setRedirectionClass(currentClassName, toClass)
+        } else if (fields[2].startsWith("~")) {
+            if (classType != SpecialClass.NotSpecial) {
+                // We could support it, but not needed at least for now.
+                throw ParseException(
+                    "Special class can't have a class load hook"
+                )
+            }
+            // It's a class-load hook
+            val callback = fields[2].substring(1)
+            imf.setClassLoadHook(currentClassName, callback)
+        } else {
+            val policy = parsePolicy(fields[2])
+            if (!policy.isUsableWithClasses) {
+                throw ParseException("Class can't have policy '$policy'")
+            }
+
+            when (classType) {
+                SpecialClass.NotSpecial -> {
+                    // TODO: Duplicate check, etc
+                    if (superClass == null) {
+                        imf.setPolicyForClass(
+                            currentClassName, policy.withReason(FILTER_REASON)
+                        )
+                    } else {
+                        subclassFilter.addPolicy(
+                            superClass,
+                            policy.withReason("extends $superClass")
+                        )
+                    }
+                }
+
+                SpecialClass.Aidl -> {
+                    if (aidlPolicy != null) {
+                        throw ParseException(
+                            "Policy for AIDL classes already defined"
+                        )
+                    }
+                    aidlPolicy = policy.withReason(
+                        "$FILTER_REASON (special-class AIDL)"
+                    )
+                }
+
+                SpecialClass.FeatureFlags -> {
+                    if (featureFlagsPolicy != null) {
+                        throw ParseException(
+                            "Policy for feature flags already defined"
+                        )
+                    }
+                    featureFlagsPolicy = policy.withReason(
+                        "$FILTER_REASON (special-class feature flags)"
+                    )
+                }
+
+                SpecialClass.Sysprops -> {
+                    if (syspropsPolicy != null) {
+                        throw ParseException(
+                            "Policy for sysprops already defined"
+                        )
+                    }
+                    syspropsPolicy = policy.withReason(
+                        "$FILTER_REASON (special-class sysprops)"
+                    )
+                }
+
+                SpecialClass.RFile -> {
+                    if (rFilePolicy != null) {
+                        throw ParseException(
+                            "Policy for R file already defined"
+                        )
+                    }
+                    rFilePolicy = policy.withReason(
+                        "$FILTER_REASON (special-class R file)"
+                    )
+                }
+            }
+        }
+    }
+
+    private fun parseField(fields: Array<String>) {
+        if (fields.size < 3) {
+            throw ParseException("Field ('f') expects 2 fields.")
+        }
+        val name = fields[1]
+        val policy = parsePolicy(fields[2])
+        if (!policy.isUsableWithFields) {
+            throw ParseException("Field can't have policy '$policy'")
+        }
+        require(this::currentClassName.isInitialized)
+
+        // TODO: Duplicate check, etc
+        imf.setPolicyForField(currentClassName, name, policy.withReason(FILTER_REASON))
+    }
+
+    private fun parseMethod(fields: Array<String>) {
+        if (fields.size < 4) {
+            throw ParseException("Method ('m') expects 3 fields.")
+        }
+        val name = fields[1]
+        val signature = fields[2]
+        val policy = parsePolicy(fields[3])
+
+        if (!policy.isUsableWithMethods) {
+            throw ParseException("Method can't have policy '$policy'")
+        }
+
+        require(this::currentClassName.isInitialized)
+
+        imf.setPolicyForMethod(
+            currentClassName, name, signature,
+            policy.withReason(FILTER_REASON)
+        )
+        if (policy == FilterPolicy.Substitute) {
+            val fromName = fields[3].substring(1)
+
+            if (fromName == name) {
+                throw ParseException(
+                    "Substitution must have a different name"
+                )
+            }
+
+            // Set the policy for the "from" method.
+            imf.setPolicyForMethod(
+                currentClassName, fromName, signature,
+                FilterPolicy.Keep.withReason(FILTER_REASON)
+            )
+
+            val classAndMethod = splitWithLastPeriod(fromName)
+            if (classAndMethod != null) {
+                // If the substitution target contains a ".", then
+                // it's a method call redirect.
+                methodReplaceSpec.add(
+                    TextFilePolicyMethodReplaceFilter.MethodCallReplaceSpec(
+                        currentClassName.toJvmClassName(),
+                        name,
+                        signature,
+                        classAndMethod.first.toJvmClassName(),
+                        classAndMethod.second,
+                    )
+                )
+            } else {
+                // It's an in-class replace.
+                // ("@RavenwoodReplace" equivalent)
+                imf.setRenameTo(currentClassName, fromName, signature, name)
+            }
+        }
+    }
+
+    private fun parseRename(fields: Array<String>) {
+        if (fields.size < 3) {
+            throw ParseException("Rename ('r') expects 2 fields.")
+        }
+        // Add ".*" to make it a prefix match.
+        val pattern = Pattern.compile(fields[1] + ".*")
+
+        // Removing the leading /'s from the prefix. This allows
+        // using a single '/' as an empty suffix, which is useful to have a
+        // "negative" rename rule to avoid subsequent raname's from getting
+        // applied. (Which is needed for services.jar)
+        val prefix = fields[2].trimStart('/')
+
+        typeRenameSpec += TextFilePolicyRemapperFilter.TypeRenameSpec(
+            pattern, prefix
+        )
+    }
 }