Merge "statsd: fix -Wreorder-init-list"
diff --git a/Android.bp b/Android.bp
index ea14b9d..180e1d3 100644
--- a/Android.bp
+++ b/Android.bp
@@ -212,6 +212,7 @@
     name: "framework-non-updatable-sources",
     srcs: [
         // Java/AIDL sources under frameworks/base
+        ":framework-appsearch-sources",
         ":framework-blobstore-sources",
         ":framework-core-sources",
         ":framework-drm-sources",
diff --git a/apex/appsearch/framework/Android.bp b/apex/appsearch/framework/Android.bp
new file mode 100644
index 0000000..0a65f73
--- /dev/null
+++ b/apex/appsearch/framework/Android.bp
@@ -0,0 +1,39 @@
+// 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.
+
+filegroup {
+  name: "framework-appsearch-sources",
+  srcs: [
+    "java/**/*.java",
+    "java/**/*.aidl",
+  ],
+  path: "java",
+}
+
+java_library {
+  name: "framework-appsearch",
+  installable: false,
+  sdk_version: "core_platform",
+  srcs: [
+    ":framework-appsearch-sources",
+  ],
+  aidl: {
+    export_include_dirs: [
+      "java",
+    ],
+  },
+  libs: [
+    "framework-minus-apex",
+  ],
+}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
new file mode 100644
index 0000000..a8ee35c
--- /dev/null
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
@@ -0,0 +1,35 @@
+/*
+ * 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 android.app.appsearch;
+
+import android.annotation.SystemService;
+import android.content.Context;
+
+/**
+ * TODO(b/142567528): add comments when implement this class
+ * @hide
+ */
+@SystemService(Context.APP_SEARCH_SERVICE)
+public class AppSearchManager {
+    private final IAppSearchManager mService;
+    /**
+     * TODO(b/142567528): add comments when implement this class
+     * @hide
+     */
+    public AppSearchManager(IAppSearchManager service) {
+        mService = service;
+    }
+}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManagerFrameworkInitializer.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManagerFrameworkInitializer.java
new file mode 100644
index 0000000..fcebe3d
--- /dev/null
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManagerFrameworkInitializer.java
@@ -0,0 +1,37 @@
+/*
+ * 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 android.app.appsearch;
+
+import android.app.SystemServiceRegistry;
+import android.content.Context;
+
+/**
+ * This is where the AppSearchManagerService wrapper is registered.
+ *
+ * TODO(b/142567528): add comments when implement this class
+ * @hide
+ */
+public class AppSearchManagerFrameworkInitializer {
+
+    /**
+     * TODO(b/142567528): add comments when implement this class
+     */
+    public static void initialize() {
+        SystemServiceRegistry.registerStaticService(
+                Context.APP_SEARCH_SERVICE, AppSearchManager.class,
+                (service) -> new AppSearchManager(IAppSearchManager.Stub.asInterface(service)));
+    }
+}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl b/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl
new file mode 100644
index 0000000..f0f4f51
--- /dev/null
+++ b/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright 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 android.app.appsearch;
+/** {@hide} */
+interface IAppSearchManager {
+}
diff --git a/apex/appsearch/service/Android.bp b/apex/appsearch/service/Android.bp
new file mode 100644
index 0000000..2821fbe
--- /dev/null
+++ b/apex/appsearch/service/Android.bp
@@ -0,0 +1,24 @@
+// 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.
+java_library {
+  name: "appsearch-service",
+  installable: true,
+  srcs: [
+    "java/**/*.java",
+  ],
+  libs: [
+    "framework",
+    "services.core",
+  ],
+}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
new file mode 100644
index 0000000..4d44d9d
--- /dev/null
+++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
@@ -0,0 +1,39 @@
+/*
+ * 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.appsearch;
+
+import android.app.appsearch.IAppSearchManager;
+import android.content.Context;
+
+import com.android.server.SystemService;
+
+/**
+ * TODO(b/142567528): add comments when implement this class
+ */
+public class AppSearchManagerService extends SystemService {
+
+    public AppSearchManagerService(Context context) {
+        super(context);
+    }
+
+    @Override
+    public void onStart() {
+        publishBinderService(Context.APP_SEARCH_SERVICE, new Stub());
+    }
+
+    private class Stub extends IAppSearchManager.Stub {
+    }
+}
diff --git a/api/current.txt b/api/current.txt
index a45583a..f899e40 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -9927,6 +9927,7 @@
     field public static final String ALARM_SERVICE = "alarm";
     field public static final String APPWIDGET_SERVICE = "appwidget";
     field public static final String APP_OPS_SERVICE = "appops";
+    field public static final String APP_SEARCH_SERVICE = "app_search";
     field public static final String AUDIO_SERVICE = "audio";
     field public static final String BATTERY_SERVICE = "batterymanager";
     field public static final int BIND_ABOVE_CLIENT = 8; // 0x8
@@ -45590,6 +45591,8 @@
     field public static final int PHONE_TYPE_NONE = 0; // 0x0
     field public static final int PHONE_TYPE_SIP = 3; // 0x3
     field public static final int SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION = 2; // 0x2
+    field public static final int SET_OPPORTUNISTIC_SUB_NO_OPPORTUNISTIC_SUB_AVAILABLE = 3; // 0x3
+    field public static final int SET_OPPORTUNISTIC_SUB_REMOTE_SERVICE_EXCEPTION = 4; // 0x4
     field public static final int SET_OPPORTUNISTIC_SUB_SUCCESS = 0; // 0x0
     field public static final int SET_OPPORTUNISTIC_SUB_VALIDATION_FAILED = 1; // 0x1
     field public static final int SIM_STATE_ABSENT = 1; // 0x1
@@ -45606,8 +45609,14 @@
     field public static final int UNKNOWN_CARRIER_ID = -1; // 0xffffffff
     field public static final int UNSUPPORTED_CARD_ID = -1; // 0xffffffff
     field public static final int UPDATE_AVAILABLE_NETWORKS_ABORTED = 2; // 0x2
+    field public static final int UPDATE_AVAILABLE_NETWORKS_DISABLE_MODEM_FAIL = 5; // 0x5
+    field public static final int UPDATE_AVAILABLE_NETWORKS_ENABLE_MODEM_FAIL = 6; // 0x6
     field public static final int UPDATE_AVAILABLE_NETWORKS_INVALID_ARGUMENTS = 3; // 0x3
+    field public static final int UPDATE_AVAILABLE_NETWORKS_MULTIPLE_NETWORKS_NOT_SUPPORTED = 7; // 0x7
     field public static final int UPDATE_AVAILABLE_NETWORKS_NO_CARRIER_PRIVILEGE = 4; // 0x4
+    field public static final int UPDATE_AVAILABLE_NETWORKS_NO_OPPORTUNISTIC_SUB_AVAILABLE = 8; // 0x8
+    field public static final int UPDATE_AVAILABLE_NETWORKS_REMOTE_SERVICE_EXCEPTION = 9; // 0x9
+    field public static final int UPDATE_AVAILABLE_NETWORKS_SERVICE_IS_DISABLED = 10; // 0xa
     field public static final int UPDATE_AVAILABLE_NETWORKS_SUCCESS = 0; // 0x0
     field public static final int UPDATE_AVAILABLE_NETWORKS_UNKNOWN_FAILURE = 1; // 0x1
     field public static final int USSD_ERROR_SERVICE_UNAVAIL = -2; // 0xfffffffe
diff --git a/api/system-current.txt b/api/system-current.txt
index e40fd24..f74b743 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5899,7 +5899,15 @@
   }
 
   public class WorkSource implements android.os.Parcelable {
+    ctor public WorkSource(int);
+    ctor public WorkSource(int, @NonNull String);
     method public android.os.WorkSource.WorkChain createWorkChain();
+    method @Nullable public String getPackageName(int);
+    method public int getUid(int);
+    method @Nullable public java.util.List<android.os.WorkSource.WorkChain> getWorkChains();
+    method public boolean isEmpty();
+    method public int size();
+    method @NonNull public android.os.WorkSource withoutNames();
   }
 
   public static final class WorkSource.WorkChain implements android.os.Parcelable {
@@ -8655,6 +8663,10 @@
     method @Deprecated public static android.telephony.SubscriptionPlan.Builder createRecurringWeekly(java.time.ZonedDateTime);
   }
 
+  public class TelephonyFrameworkInitializer {
+    method public static void registerServiceWrappers();
+  }
+
   public final class TelephonyHistogram implements android.os.Parcelable {
     ctor public TelephonyHistogram(int, int, int);
     ctor public TelephonyHistogram(android.telephony.TelephonyHistogram);
diff --git a/api/test-current.txt b/api/test-current.txt
index 897e825..95b0cae 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -2185,10 +2185,12 @@
     method public boolean add(int);
     method public boolean add(int, String);
     method @Deprecated public android.os.WorkSource addReturningNewbs(android.os.WorkSource);
-    method public int get(int);
-    method public String getName(int);
+    method @Nullable public String getPackageName(int);
+    method public int getUid(int);
+    method public boolean isEmpty();
     method @Deprecated public android.os.WorkSource[] setReturningDiffs(android.os.WorkSource);
     method public int size();
+    method @NonNull public android.os.WorkSource withoutNames();
   }
 
 }
diff --git a/config/preloaded-classes b/config/preloaded-classes
index ab98e5b..0394a7a 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -514,6 +514,7 @@
 android.app.admin.SystemUpdateInfo
 android.app.admin.SystemUpdatePolicy$1
 android.app.admin.SystemUpdatePolicy
+android.app.appsearch.AppSearchManagerFrameworkInitializer
 android.app.assist.AssistContent$1
 android.app.assist.AssistContent
 android.app.assist.AssistStructure$1
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index d0ba879..5effa1b 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -22,6 +22,7 @@
 import android.app.ContextImpl.ServiceInitializationState;
 import android.app.admin.DevicePolicyManager;
 import android.app.admin.IDevicePolicyManager;
+import android.app.appsearch.AppSearchManagerFrameworkInitializer;
 import android.app.blob.BlobStoreManagerFrameworkInitializer;
 import android.app.contentsuggestions.ContentSuggestionsManager;
 import android.app.contentsuggestions.IContentSuggestionsManager;
@@ -166,12 +167,8 @@
 import android.service.persistentdata.PersistentDataBlockManager;
 import android.service.vr.IVrManager;
 import android.telecom.TelecomManager;
-import android.telephony.CarrierConfigManager;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
+import android.telephony.TelephonyFrameworkInitializer;
 import android.telephony.TelephonyRegistryManager;
-import android.telephony.euicc.EuiccCardManager;
-import android.telephony.euicc.EuiccManager;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.view.ContextThemeWrapper;
@@ -604,13 +601,6 @@
                         return new SystemUpdateManager(service);
                     }});
 
-        registerService(Context.TELEPHONY_SERVICE, TelephonyManager.class,
-                new CachedServiceFetcher<TelephonyManager>() {
-            @Override
-            public TelephonyManager createService(ContextImpl ctx) {
-                return new TelephonyManager(ctx.getOuterContext());
-            }});
-
         registerService(Context.TELEPHONY_REGISTRY_SERVICE, TelephonyRegistryManager.class,
             new CachedServiceFetcher<TelephonyRegistryManager>() {
                 @Override
@@ -618,20 +608,6 @@
                     return new TelephonyRegistryManager(ctx);
                 }});
 
-        registerService(Context.TELEPHONY_SUBSCRIPTION_SERVICE, SubscriptionManager.class,
-                new CachedServiceFetcher<SubscriptionManager>() {
-            @Override
-            public SubscriptionManager createService(ContextImpl ctx) throws ServiceNotFoundException {
-                return new SubscriptionManager(ctx.getOuterContext());
-            }});
-
-        registerService(Context.CARRIER_CONFIG_SERVICE, CarrierConfigManager.class,
-                new CachedServiceFetcher<CarrierConfigManager>() {
-            @Override
-            public CarrierConfigManager createService(ContextImpl ctx) {
-                return new CarrierConfigManager(ctx.getOuterContext());
-            }});
-
         registerService(Context.TELECOM_SERVICE, TelecomManager.class,
                 new CachedServiceFetcher<TelecomManager>() {
             @Override
@@ -639,20 +615,6 @@
                 return new TelecomManager(ctx.getOuterContext());
             }});
 
-        registerService(Context.EUICC_SERVICE, EuiccManager.class,
-                new CachedServiceFetcher<EuiccManager>() {
-            @Override
-            public EuiccManager createService(ContextImpl ctx) {
-                return new EuiccManager(ctx.getOuterContext());
-            }});
-
-        registerService(Context.EUICC_CARD_SERVICE, EuiccCardManager.class,
-                new CachedServiceFetcher<EuiccCardManager>() {
-                    @Override
-                    public EuiccCardManager createService(ContextImpl ctx) {
-                        return new EuiccCardManager(ctx.getOuterContext());
-                    }});
-
         registerService(Context.UI_MODE_SERVICE, UiModeManager.class,
                 new CachedServiceFetcher<UiModeManager>() {
             @Override
@@ -1301,6 +1263,8 @@
 
             JobSchedulerFrameworkInitializer.registerServiceWrappers();
             BlobStoreManagerFrameworkInitializer.initialize();
+            TelephonyFrameworkInitializer.registerServiceWrappers();
+            AppSearchManagerFrameworkInitializer.initialize();
         } finally {
             // If any of the above code throws, we're in a pretty bad shape and the process
             // will likely crash, but we'll reset it just in case there's an exception handler...
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 7703e08..8507316 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -4898,6 +4898,15 @@
     public static final String BATTERY_STATS_SERVICE = "batterystats";
 
     /**
+     * Use with {@link #getSystemService(String)} to retrieve an
+     * AppSearchManager for indexing and querying app data managed
+     * by the system.
+     *
+     * @see #getSystemService(String)
+     */
+    public static final String APP_SEARCH_SERVICE = "app_search";
+
+    /**
      * Determine whether the given permission is allowed for a particular
      * process and user ID running in the system.
      *
diff --git a/core/java/android/content/om/OverlayableInfo.java b/core/java/android/content/om/OverlayableInfo.java
new file mode 100644
index 0000000..5923907
--- /dev/null
+++ b/core/java/android/content/om/OverlayableInfo.java
@@ -0,0 +1,120 @@
+/*
+ * 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 android.content.om;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import com.android.internal.util.DataClass;
+
+import java.util.Objects;
+
+/**
+ * Immutable info on an overlayable defined inside a target package.
+ *
+ * @hide
+ */
+@DataClass(genSetters = false, genEqualsHashCode = true, genHiddenConstructor = true)
+public final class OverlayableInfo {
+
+    /**
+     * The "name" attribute of the overlayable tag. Used to identify the set of resources overlaid.
+     */
+    @NonNull
+    public final String name;
+
+    /**
+     * The "actor" attribute of the overlayable tag. Used to signal which apps are allowed to
+     * modify overlay state for this overlayable.
+     */
+    @Nullable
+    public final String actor;
+
+    // CHECKSTYLE:OFF Generated code
+    //
+
+
+
+    // Code below generated by codegen v1.0.3.
+    //
+    // DO NOT MODIFY!
+    // CHECKSTYLE:OFF Generated code
+    //
+    // To regenerate run:
+    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/om/OverlayableInfo.java
+
+
+    /**
+     * Creates a new OverlayableInfo.
+     *
+     * @param name
+     *   The "name" attribute of the overlayable tag. Used to identify the set of resources overlaid.
+     * @param actor
+     *   The "actor" attribute of the overlayable tag. Used to signal which apps are allowed to
+     *   modify overlay state for this overlayable.
+     * @hide
+     */
+    @DataClass.Generated.Member
+    public OverlayableInfo(
+            @NonNull String name,
+            @Nullable String actor) {
+        this.name = name;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, name);
+        this.actor = actor;
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public boolean equals(Object o) {
+        // You can override field equality logic by defining either of the methods like:
+        // boolean fieldNameEquals(OverlayableInfo other) { ... }
+        // boolean fieldNameEquals(FieldType otherValue) { ... }
+
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        @SuppressWarnings("unchecked")
+        OverlayableInfo that = (OverlayableInfo) o;
+        //noinspection PointlessBooleanExpression
+        return true
+                && Objects.equals(name, that.name)
+                && Objects.equals(actor, that.actor);
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public int hashCode() {
+        // You can override field hashCode logic by defining methods like:
+        // int fieldNameHashCode() { ... }
+
+        int _hash = 1;
+        _hash = 31 * _hash + Objects.hashCode(name);
+        _hash = 31 * _hash + Objects.hashCode(actor);
+        return _hash;
+    }
+
+    @DataClass.Generated(
+            time = 1570059850579L,
+            codegenVersion = "1.0.3",
+            sourceFile = "frameworks/base/core/java/android/content/om/OverlayableInfo.java",
+            inputSignatures = "public final @android.annotation.NonNull java.lang.String name\npublic final @android.annotation.Nullable java.lang.String actor\nclass OverlayableInfo extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genSetters=false, genEqualsHashCode=true, genHiddenConstructor=true)")
+    @Deprecated
+    private void __metadata() {}
+
+}
diff --git a/core/java/android/content/res/ApkAssets.java b/core/java/android/content/res/ApkAssets.java
index de1d514..ad37555 100644
--- a/core/java/android/content/res/ApkAssets.java
+++ b/core/java/android/content/res/ApkAssets.java
@@ -18,6 +18,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
+import android.content.om.OverlayableInfo;
 import android.content.res.loader.ResourcesProvider;
 import android.text.TextUtils;
 
@@ -254,6 +255,17 @@
         }
     }
 
+    /** @hide */
+    @Nullable
+    public OverlayableInfo getOverlayableInfo(String overlayableName) throws IOException {
+        return nativeGetOverlayableInfo(mNativePtr, overlayableName);
+    }
+
+    /** @hide */
+    public boolean definesOverlayable() throws IOException {
+        return nativeDefinesOverlayable(mNativePtr);
+    }
+
     /**
      * Returns false if the underlying APK was changed since this ApkAssets was loaded.
      */
@@ -305,4 +317,7 @@
     private static native long nativeGetStringBlock(long ptr);
     private static native boolean nativeIsUpToDate(long ptr);
     private static native long nativeOpenXml(long ptr, @NonNull String fileName) throws IOException;
+    private static native @Nullable OverlayableInfo nativeGetOverlayableInfo(long ptr,
+            String overlayableName) throws IOException;
+    private static native boolean nativeDefinesOverlayable(long ptr) throws IOException;
 }
diff --git a/core/java/android/os/StatsLogEventWrapper.java b/core/java/android/os/StatsLogEventWrapper.java
index 89c9bb2..320fc13 100644
--- a/core/java/android/os/StatsLogEventWrapper.java
+++ b/core/java/android/os/StatsLogEventWrapper.java
@@ -139,7 +139,7 @@
         out.writeLong(mElapsedTimeNs);
         out.writeLong(mWallClockTimeNs);
         if (mWorkSource != null) {
-            ArrayList<android.os.WorkSource.WorkChain> workChains = mWorkSource.getWorkChains();
+            List<WorkSource.WorkChain> workChains = mWorkSource.getWorkChains();
             // number of chains
             out.writeInt(workChains.size());
             for (int i = 0; i < workChains.size(); i++) {
diff --git a/core/java/android/os/WorkSource.java b/core/java/android/os/WorkSource.java
index 825fc64..b5635a4 100644
--- a/core/java/android/os/WorkSource.java
+++ b/core/java/android/os/WorkSource.java
@@ -13,13 +13,15 @@
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.Preconditions;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 
 /**
  * Describes the source of some work that may be done by someone else.
- * Currently the public representation of what a work source is is not
+ * Currently the public representation of what a work source is not
  * defined; this is an opaque container.
  */
 public class WorkSource implements Parcelable {
@@ -48,7 +50,7 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     static WorkSource sNewbWork;
     /**
-     * For returning gone work form a modification operation.
+     * For returning gone work from a modification operation.
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     static WorkSource sGoneWork;
@@ -91,9 +93,14 @@
         }
     }
 
-    /** @hide */
-    @UnsupportedAppUsage
+
+    /**
+     * Creates a work source with the given uid.
+     * @param uid the uid performing the work
+     * @hide
+     */
     @TestApi
+    @SystemApi
     public WorkSource(int uid) {
         mNum = 1;
         mUids = new int[] { uid, 0 };
@@ -101,14 +108,18 @@
         mChains = null;
     }
 
-    /** @hide */
-    public WorkSource(int uid, String name) {
-        if (name == null) {
-            throw new NullPointerException("Name can't be null");
-        }
+    /**
+     * Creates a work source with the given uid and package name.
+     * @param uid the uid performing the work
+     * @param packageName the package performing the work
+     * @hide
+     */
+    @SystemApi
+    public WorkSource(int uid, @NonNull String packageName) {
+        Preconditions.checkNotNull(packageName, "packageName can't be null");
         mNum = 1;
         mUids = new int[] { uid, 0 };
-        mNames = new String[] { name, null };
+        mNames = new String[] { packageName, null };
         mChains = null;
     }
 
@@ -138,17 +149,34 @@
                 Global.CHAINED_BATTERY_ATTRIBUTION_ENABLED, 0) == 1;
     }
 
-    /** @hide */
-    @UnsupportedAppUsage
+    /**
+     * Returns the size of this work source.
+     * @hide
+     */
     @TestApi
+    @SystemApi
     public int size() {
         return mNum;
     }
 
-    /** @hide */
+    /**
+     * @deprecated use {{@link #getUid(int)}} instead.
+     * @hide
+     */
     @UnsupportedAppUsage
-    @TestApi
+    @Deprecated
     public int get(int index) {
+        return getUid(index);
+    }
+
+    /**
+     * Get the uid at the given index.
+     * If {@code index} < 0 or {@code index} >= {@link #size() N}, then the behavior is undefined.
+     * @hide
+     */
+    @TestApi
+    @SystemApi
+    public int getUid(int index) {
         return mUids[index];
     }
 
@@ -167,10 +195,25 @@
         return mNum > 0 ? mUids[0] : mChains.get(0).getAttributionUid();
     }
 
-    /** @hide */
+    /**
+     * @deprecated use {{@link #getPackageName(int)}} instead.
+     * @hide
+     */
     @UnsupportedAppUsage
-    @TestApi
+    @Deprecated
     public String getName(int index) {
+        return getPackageName(index);
+    }
+
+    /**
+     * Get the package name at the given index.
+     * If {@code index} < 0 or {@code index} >= {@link #size() N}, then the behavior is undefined.
+     * @hide
+     */
+    @TestApi
+    @SystemApi
+    @Nullable
+    public String getPackageName(int index) {
         return mNames != null ? mNames[index] : null;
     }
 
@@ -179,9 +222,8 @@
      * intact.
      *
      * <p>Useful when combining with another WorkSource that doesn't have names.
-     * @hide
      */
-    public void clearNames() {
+    private void clearNames() {
         if (mNames != null) {
             mNames = null;
             // Clear out any duplicate uids now that we don't have names to disambiguate them.
@@ -407,6 +449,22 @@
     }
 
     /**
+     * Returns a copy of this work source without any package names.
+     * If any {@link WorkChain WorkChains} are present, they are left intact.
+     *
+     * @return a {@link WorkSource} without any package names.
+     * @hide
+     */
+    @SystemApi
+    @TestApi
+    @NonNull
+    public WorkSource withoutNames() {
+        final WorkSource copy = new WorkSource(this);
+        copy.clearNames();
+        return copy;
+    }
+
+    /**
      * Legacy API: DO NOT USE. Only in use from unit tests.
      *
      * @hide
@@ -524,6 +582,8 @@
      *
      * @hide for internal use only.
      */
+    @SystemApi
+    @TestApi
     public boolean isEmpty() {
         return mNum == 0 && (mChains == null || mChains.isEmpty());
     }
@@ -532,7 +592,9 @@
      * @return the list of {@code WorkChains} associated with this {@code WorkSource}.
      * @hide
      */
-    public ArrayList<WorkChain> getWorkChains() {
+    @SystemApi
+    @Nullable
+    public List<WorkChain> getWorkChains() {
         return mChains;
     }
 
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 3251127..6458737 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -199,6 +199,8 @@
     private static native void nativeWriteTransactionToParcel(long nativeObject, Parcel out);
     private static native void nativeSetShadowRadius(long transactionObj, long nativeObject,
             float shadowRadius);
+    private static native void nativeSetGlobalShadowSettings(@Size(4) float[] ambientColor,
+            @Size(4) float[] spotColor, float lightPosY, float lightPosZ, float lightRadius);
 
     private final CloseGuard mCloseGuard = CloseGuard.get();
     private String mName;
@@ -1979,6 +1981,42 @@
         return sc;
     }
 
+    private static void validateColorArg(@Size(4) float[] color) {
+        final String msg = "Color must be specified as a float array with"
+                + " four values to represent r, g, b, a in range [0..1]";
+        if (color.length != 4) {
+            throw new IllegalArgumentException(msg);
+        }
+        for (float c:color) {
+            if ((c < 0.f) || (c > 1.f)) {
+                throw new IllegalArgumentException(msg);
+            }
+        }
+    }
+
+    /**
+     * Sets the global configuration for all the shadows drawn by SurfaceFlinger. Shadow follows
+     * material design guidelines.
+     *
+     * @param ambientColor Color applied to the ambient shadow. The alpha is premultiplied. A
+     *                     float array with four values to represent r, g, b, a in range [0..1]
+     * @param spotColor Color applied to the spot shadow. The alpha is premultiplied. The position
+     *                  of the spot shadow depends on the light position. A float array with
+     *                  four values to represent r, g, b, a in range [0..1]
+     * @param lightPosY Y axis position of the light used to cast the spot shadow in pixels.
+     * @param lightPosZ Z axis position of the light used to cast the spot shadow in pixels. The X
+     *                  axis position is set to the display width / 2.
+     * @param lightRadius Radius of the light casting the shadow in pixels.
+     *[
+     * @hide
+     */
+    public static void setGlobalShadowSettings(@Size(4) float[] ambientColor,
+            @Size(4) float[] spotColor, float lightPosY, float lightPosZ, float lightRadius) {
+        validateColorArg(ambientColor);
+        validateColorArg(spotColor);
+        nativeSetGlobalShadowSettings(ambientColor, spotColor, lightPosY, lightPosZ, lightRadius);
+    }
+
      /**
      * An atomic set of changes to a set of SurfaceControl.
      */
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index f5bfe5c..75a5804 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -4086,7 +4086,7 @@
 
         if (workSource != null) {
             for (int i = 0; i < workSource.size(); ++i) {
-                uid = mapUid(workSource.get(i));
+                uid = mapUid(workSource.getUid(i));
                 if (mActiveEvents.updateState(historyItem, name, uid, 0)) {
                     addHistoryEventLocked(elapsedRealtime, uptime, historyItem, name, uid);
                 }
@@ -4114,8 +4114,8 @@
             String tag) {
         if (workSource != null) {
             for (int i = 0; i < workSource.size(); ++i) {
-                uid = workSource.get(i);
-                final String workSourceName = workSource.getName(i);
+                uid = workSource.getUid(i);
+                final String workSourceName = workSource.getPackageName(i);
 
                 if (isOnBattery()) {
                     BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid,
@@ -4124,7 +4124,7 @@
                 }
             }
 
-            ArrayList<WorkChain> workChains = workSource.getWorkChains();
+            List<WorkChain> workChains = workSource.getWorkChains();
             if (workChains != null) {
                 for (int i = 0; i < workChains.size(); ++i) {
                     final WorkChain wc = workChains.get(i);
@@ -4350,7 +4350,7 @@
         final long uptime = mClocks.uptimeMillis();
         final int N = ws.size();
         for (int i=0; i<N; i++) {
-            noteStartWakeLocked(ws.get(i), pid, null, name, historyName, type,
+            noteStartWakeLocked(ws.getUid(i), pid, null, name, historyName, type,
                     unimportantForLogging, elapsedRealtime, uptime);
         }
 
@@ -4379,7 +4379,7 @@
         // First the starts :
         final int NN = newWs.size();
         for (int i=0; i<NN; i++) {
-            noteStartWakeLocked(newWs.get(i), newPid, null, newName, newHistoryName, newType,
+            noteStartWakeLocked(newWs.getUid(i), newPid, null, newName, newHistoryName, newType,
                     newUnimportantForLogging, elapsedRealtime, uptime);
         }
         if (wcs != null) {
@@ -4397,7 +4397,7 @@
         // Then the stops :
         final int NO = ws.size();
         for (int i=0; i<NO; i++) {
-            noteStopWakeLocked(ws.get(i), pid, null, name, historyName, type, elapsedRealtime,
+            noteStopWakeLocked(ws.getUid(i), pid, null, name, historyName, type, elapsedRealtime,
                     uptime);
         }
         if (wcs != null) {
@@ -4418,7 +4418,7 @@
         final long uptime = mClocks.uptimeMillis();
         final int N = ws.size();
         for (int i=0; i<N; i++) {
-            noteStopWakeLocked(ws.get(i), pid, null, name, historyName, type, elapsedRealtime,
+            noteStopWakeLocked(ws.getUid(i), pid, null, name, historyName, type, elapsedRealtime,
                     uptime);
         }
 
@@ -4441,11 +4441,11 @@
             WorkSource workSource) {
         final int N = workSource.size();
         for (int i = 0; i < N; ++i) {
-            final int uid = mapUid(workSource.get(i));
+            final int uid = mapUid(workSource.getUid(i));
             noteLongPartialWakeLockStartInternal(name, historyName, uid);
         }
 
-        final ArrayList<WorkChain> workChains = workSource.getWorkChains();
+        final List<WorkChain> workChains = workSource.getWorkChains();
         if (workChains != null) {
             for (int i = 0; i < workChains.size(); ++i) {
                 final WorkChain workChain = workChains.get(i);
@@ -4478,11 +4478,11 @@
             WorkSource workSource) {
         final int N = workSource.size();
         for (int i = 0; i < N; ++i) {
-            final int uid = mapUid(workSource.get(i));
+            final int uid = mapUid(workSource.getUid(i));
             noteLongPartialWakeLockFinishInternal(name, historyName, uid);
         }
 
-        final ArrayList<WorkChain> workChains = workSource.getWorkChains();
+        final List<WorkChain> workChains = workSource.getWorkChains();
         if (workChains != null) {
             for (int i = 0; i < workChains.size(); ++i) {
                 final WorkChain workChain = workChains.get(i);
@@ -4615,11 +4615,11 @@
 
     public void noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs) {
         for (int i = 0; i < newWs.size(); ++i) {
-            noteStartGpsLocked(newWs.get(i), null);
+            noteStartGpsLocked(newWs.getUid(i), null);
         }
 
         for (int i = 0; i < oldWs.size(); ++i) {
-            noteStopGpsLocked((oldWs.get(i)), null);
+            noteStopGpsLocked((oldWs.getUid(i)), null);
         }
 
         List<WorkChain>[] wcs = WorkSource.diffChains(oldWs, newWs);
@@ -5564,7 +5564,7 @@
     public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized) {
         final int N = ws.size();
         for (int i = 0; i < N; i++) {
-            noteBluetoothScanStartedLocked(null, ws.get(i), isUnoptimized);
+            noteBluetoothScanStartedLocked(null, ws.getUid(i), isUnoptimized);
         }
 
         final List<WorkChain> workChains = ws.getWorkChains();
@@ -5602,7 +5602,7 @@
     public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized) {
         final int N = ws.size();
         for (int i = 0; i < N; i++) {
-            noteBluetoothScanStoppedLocked(null, ws.get(i), isUnoptimized);
+            noteBluetoothScanStoppedLocked(null, ws.getUid(i), isUnoptimized);
         }
 
         final List<WorkChain> workChains = ws.getWorkChains();
@@ -5633,7 +5633,7 @@
     public void noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults) {
         final int N = ws.size();
         for (int i = 0; i < N; i++) {
-            int uid = mapUid(ws.get(i));
+            int uid = mapUid(ws.getUid(i));
             getUidStatsLocked(uid).noteBluetoothScanResultsLocked(numNewResults);
         }
 
@@ -5692,7 +5692,7 @@
             mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtime);
             int N = ws.size();
             for (int i=0; i<N; i++) {
-                int uid = mapUid(ws.get(i));
+                int uid = mapUid(ws.getUid(i));
                 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
             }
 
@@ -5715,7 +5715,7 @@
             final long elapsedRealtime = mClocks.elapsedRealtime();
             int N = oldWs.size();
             for (int i=0; i<N; i++) {
-                int uid = mapUid(oldWs.get(i));
+                int uid = mapUid(oldWs.getUid(i));
                 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
             }
 
@@ -5729,7 +5729,7 @@
 
             N = newWs.size();
             for (int i=0; i<N; i++) {
-                int uid = mapUid(newWs.get(i));
+                int uid = mapUid(newWs.getUid(i));
                 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
             }
 
@@ -5757,7 +5757,7 @@
             mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtime);
             int N = ws.size();
             for (int i=0; i<N; i++) {
-                int uid = mapUid(ws.get(i));
+                int uid = mapUid(ws.getUid(i));
                 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
             }
 
@@ -5963,7 +5963,7 @@
     public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) {
         int N = ws.size();
         for (int i=0; i<N; i++) {
-            final int uid = mapUid(ws.get(i));
+            final int uid = mapUid(ws.getUid(i));
             noteFullWifiLockAcquiredLocked(uid);
         }
 
@@ -5980,7 +5980,7 @@
     public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) {
         int N = ws.size();
         for (int i=0; i<N; i++) {
-            final int uid = mapUid(ws.get(i));
+            final int uid = mapUid(ws.getUid(i));
             noteFullWifiLockReleasedLocked(uid);
         }
 
@@ -5997,7 +5997,7 @@
     public void noteWifiScanStartedFromSourceLocked(WorkSource ws) {
         int N = ws.size();
         for (int i=0; i<N; i++) {
-            final int uid = mapUid(ws.get(i));
+            final int uid = mapUid(ws.getUid(i));
             noteWifiScanStartedLocked(uid);
         }
 
@@ -6014,7 +6014,7 @@
     public void noteWifiScanStoppedFromSourceLocked(WorkSource ws) {
         int N = ws.size();
         for (int i=0; i<N; i++) {
-            final int uid = mapUid(ws.get(i));
+            final int uid = mapUid(ws.getUid(i));
             noteWifiScanStoppedLocked(uid);
         }
 
@@ -6031,7 +6031,7 @@
     public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph) {
         int N = ws.size();
         for (int i=0; i<N; i++) {
-            noteWifiBatchedScanStartedLocked(ws.get(i), csph);
+            noteWifiBatchedScanStartedLocked(ws.getUid(i), csph);
         }
 
         final List<WorkChain> workChains = ws.getWorkChains();
@@ -6045,7 +6045,7 @@
     public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws) {
         int N = ws.size();
         for (int i=0; i<N; i++) {
-            noteWifiBatchedScanStoppedLocked(ws.get(i));
+            noteWifiBatchedScanStoppedLocked(ws.getUid(i));
         }
 
         final List<WorkChain> workChains = ws.getWorkChains();
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index ed7f5de..49a73ee 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -18,6 +18,7 @@
 
 import static com.android.internal.util.ArrayUtils.appendInt;
 
+import android.annotation.NonNull;
 import android.app.ActivityManager;
 import android.content.ComponentName;
 import android.content.pm.FeatureInfo;
@@ -221,6 +222,12 @@
     private ArrayMap<String, Set<String>> mPackageToUserTypeWhitelist = new ArrayMap<>();
     private ArrayMap<String, Set<String>> mPackageToUserTypeBlacklist = new ArrayMap<>();
 
+    /**
+     * Map of system pre-defined, uniquely named actors; keys are namespace,
+     * value maps actor name to package name.
+     */
+    private ArrayMap<String, ArrayMap<String, String>> mNamedActors = null;
+
     public static SystemConfig getInstance() {
         if (!isSystemProcess()) {
             Slog.wtf(TAG, "SystemConfig is being accessed by a process other than "
@@ -398,12 +405,17 @@
         return r;
     }
 
+    @NonNull
+    public Map<String, ? extends Map<String, String>> getNamedActors() {
+        return mNamedActors != null ? mNamedActors : Collections.emptyMap();
+    }
+
     /**
      * Only use for testing. Do NOT use in production code.
      * @param readPermissions false to create an empty SystemConfig; true to read the permissions.
      */
     @VisibleForTesting
-    protected SystemConfig(boolean readPermissions) {
+    public SystemConfig(boolean readPermissions) {
         if (readPermissions) {
             Slog.w(TAG, "Constructing a test SystemConfig");
             readAllPermissions();
@@ -1028,6 +1040,44 @@
                         readInstallInUserType(parser,
                                 mPackageToUserTypeWhitelist, mPackageToUserTypeBlacklist);
                     } break;
+                    case "named-actor": {
+                        String namespace = TextUtils.safeIntern(
+                                parser.getAttributeValue(null, "namespace"));
+                        String actorName = parser.getAttributeValue(null, "name");
+                        String pkgName = TextUtils.safeIntern(
+                                parser.getAttributeValue(null, "package"));
+                        if (TextUtils.isEmpty(namespace)) {
+                            Slog.wtf(TAG, "<" + name + "> without namespace in " + permFile
+                                    + " at " + parser.getPositionDescription());
+                        } else if (TextUtils.isEmpty(actorName)) {
+                            Slog.wtf(TAG, "<" + name + "> without actor name in " + permFile
+                                    + " at " + parser.getPositionDescription());
+                        } else if (TextUtils.isEmpty(pkgName)) {
+                            Slog.wtf(TAG, "<" + name + "> without package name in " + permFile
+                                    + " at " + parser.getPositionDescription());
+                        } else if ("android".equalsIgnoreCase(namespace)) {
+                            throw new IllegalStateException("Defining " + actorName + " as "
+                                    + pkgName + " for the android namespace is not allowed");
+                        } else {
+                            if (mNamedActors == null) {
+                                mNamedActors = new ArrayMap<>();
+                            }
+
+                            ArrayMap<String, String> nameToPkgMap = mNamedActors.get(namespace);
+                            if (nameToPkgMap == null) {
+                                nameToPkgMap = new ArrayMap<>();
+                                mNamedActors.put(namespace, nameToPkgMap);
+                            } else if (nameToPkgMap.containsKey(actorName)) {
+                                String existing = nameToPkgMap.get(actorName);
+                                throw new IllegalStateException("Duplicate actor definition for "
+                                        + namespace + "/" + actorName
+                                        + "; defined as both " + existing + " and " + pkgName);
+                            }
+
+                            nameToPkgMap.put(actorName, pkgName);
+                        }
+                        XmlUtils.skipCurrentTag(parser);
+                    } break;
                     default: {
                         Slog.w(TAG, "Tag " + name + " is unknown in "
                                 + permFile + " at " + parser.getPositionDescription());
diff --git a/core/jni/android_content_res_ApkAssets.cpp b/core/jni/android_content_res_ApkAssets.cpp
index 6370253..f3a626e 100644
--- a/core/jni/android_content_res_ApkAssets.cpp
+++ b/core/jni/android_content_res_ApkAssets.cpp
@@ -194,6 +194,59 @@
   return reinterpret_cast<jlong>(xml_tree.release());
 }
 
+static jobject NativeGetOverlayableInfo(JNIEnv* env, jclass /*clazz*/, jlong ptr,
+                                         jstring overlayable_name) {
+  const ApkAssets* apk_assets = reinterpret_cast<const ApkAssets*>(ptr);
+
+  const auto& packages = apk_assets->GetLoadedArsc()->GetPackages();
+  if (packages.empty()) {
+    jniThrowException(env, "java/io/IOException", "Error reading overlayable from APK");
+    return 0;
+  }
+
+  // TODO(b/119899133): Convert this to a search for the info rather than assuming it's at index 0
+  const auto& overlayable_map = packages[0]->GetOverlayableMap();
+  if (overlayable_map.empty()) {
+    return nullptr;
+  }
+
+  auto overlayable_name_native = std::string(env->GetStringUTFChars(overlayable_name, NULL));
+  auto actor = overlayable_map.find(overlayable_name_native);
+  if (actor == overlayable_map.end()) {
+    return nullptr;
+  }
+
+  jstring actor_string = env->NewStringUTF(actor->first.c_str());
+  if (env->ExceptionCheck() || actor_string == nullptr) {
+    jniThrowException(env, "java/io/IOException", "Error reading overlayable from APK");
+    return 0;
+  }
+
+  jclass overlayable_class = env->FindClass("android/content/om/OverlayableInfo");
+  jmethodID overlayable_constructor = env->GetMethodID(overlayable_class, "<init>",
+                                                       "(Ljava/lang/String;Ljava/lang/String;I)V");
+  return env->NewObject(
+      overlayable_class,
+      overlayable_constructor,
+      overlayable_name,
+      actor_string
+  );
+}
+
+static jboolean NativeDefinesOverlayable(JNIEnv* env, jclass /*clazz*/, jlong ptr) {
+  const ApkAssets* apk_assets = reinterpret_cast<const ApkAssets*>(ptr);
+
+  const auto& packages = apk_assets->GetLoadedArsc()->GetPackages();
+  if (packages.empty()) {
+    // Must throw to prevent bypass by returning false
+    jniThrowException(env, "java/io/IOException", "Error reading overlayable from APK");
+    return 0;
+  }
+
+  const auto& overlayable_infos = packages[0]->GetOverlayableMap();
+  return overlayable_infos.empty() ? JNI_FALSE : JNI_TRUE;
+}
+
 // JNI registration.
 static const JNINativeMethod gApkAssetsMethods[] = {
     {"nativeLoad", "(Ljava/lang/String;ZZZZ)J", (void*)NativeLoad},
@@ -208,6 +261,9 @@
     {"nativeGetStringBlock", "(J)J", (void*)NativeGetStringBlock},
     {"nativeIsUpToDate", "(J)Z", (void*)NativeIsUpToDate},
     {"nativeOpenXml", "(JLjava/lang/String;)J", (void*)NativeOpenXml},
+    {"nativeGetOverlayableInfo", "(JLjava/lang/String;)Landroid/content/om/OverlayableInfo;",
+     (void*)NativeGetOverlayableInfo},
+    {"nativeDefinesOverlayable", "(J)Z", (void*)NativeDefinesOverlayable},
 };
 
 int register_android_content_res_ApkAssets(JNIEnv* env) {
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index f8a2744..9f20388 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -491,6 +491,7 @@
     float* floatColors = env->GetFloatArrayElements(fColor, 0);
     half3 color(floatColors[0], floatColors[1], floatColors[2]);
     transaction->setColor(ctrl, color);
+    env->ReleaseFloatArrayElements(fColor, floatColors, 0);
 }
 
 static void nativeSetMatrix(JNIEnv* env, jclass clazz, jlong transactionObj,
@@ -508,8 +509,12 @@
     SurfaceControl* const surfaceControl = reinterpret_cast<SurfaceControl*>(nativeObject);
     float* floatMatrix = env->GetFloatArrayElements(fMatrix, 0);
     mat3 matrix(static_cast<float const*>(floatMatrix));
+    env->ReleaseFloatArrayElements(fMatrix, floatMatrix, 0);
+
     float* floatTranslation = env->GetFloatArrayElements(fTranslation, 0);
     vec3 translation(floatTranslation[0], floatTranslation[1], floatTranslation[2]);
+    env->ReleaseFloatArrayElements(fTranslation, floatTranslation, 0);
+
     transaction->setColorTransform(surfaceControl, matrix, translation);
 }
 
@@ -1262,6 +1267,22 @@
     return reinterpret_cast<jlong>(surface.get());
 }
 
+static void nativeSetGlobalShadowSettings(JNIEnv* env, jclass clazz, jfloatArray jAmbientColor,
+        jfloatArray jSpotColor, jfloat lightPosY, jfloat lightPosZ, jfloat lightRadius) {
+    sp<SurfaceComposerClient> client = SurfaceComposerClient::getDefault();
+
+    float* floatAmbientColor = env->GetFloatArrayElements(jAmbientColor, 0);
+    half4 ambientColor = half4(floatAmbientColor[0], floatAmbientColor[1], floatAmbientColor[2],
+            floatAmbientColor[3]);
+    env->ReleaseFloatArrayElements(jAmbientColor, floatAmbientColor, 0);
+
+    float* floatSpotColor = env->GetFloatArrayElements(jSpotColor, 0);
+    half4 spotColor = half4(floatSpotColor[0], floatSpotColor[1], floatSpotColor[2],
+            floatSpotColor[3]);
+    env->ReleaseFloatArrayElements(jSpotColor, floatSpotColor, 0);
+
+    client->setGlobalShadowSettings(ambientColor, spotColor, lightPosY, lightPosZ, lightRadius);
+}
 // ----------------------------------------------------------------------------
 
 static const JNINativeMethod sSurfaceControlMethods[] = {
@@ -1416,6 +1437,8 @@
             (void*)nativeWriteTransactionToParcel },
     {"nativeMirrorSurface", "(J)J",
             (void*)nativeMirrorSurface },
+    {"nativeSetGlobalShadowSettings", "([F[FFFF)V",
+            (void*)nativeSetGlobalShadowSettings },
 };
 
 int register_android_view_SurfaceControl(JNIEnv* env)
diff --git a/core/tests/coretests/src/android/os/WorkSourceTest.java b/core/tests/coretests/src/android/os/WorkSourceTest.java
index e94d60c..4206fd2 100644
--- a/core/tests/coretests/src/android/os/WorkSourceTest.java
+++ b/core/tests/coretests/src/android/os/WorkSourceTest.java
@@ -228,13 +228,13 @@
         WorkSource ws = new WorkSource();
         ws.set(10);
         assertEquals(1, ws.size());
-        assertEquals(10, ws.get(0));
+        assertEquals(10, ws.getUid(0));
 
         WorkSource ws2 = new WorkSource();
         ws2.set(20, "foo");
         assertEquals(1, ws2.size());
-        assertEquals(20, ws2.get(0));
-        assertEquals("foo", ws2.getName(0));
+        assertEquals(20, ws2.getUid(0));
+        assertEquals("foo", ws2.getPackageName(0));
     }
 
     public void testDiffChains_noChanges() {
@@ -410,8 +410,8 @@
         assertTrue(ws2.remove(ws1));
 
         assertEquals(0, ws1.size());
-        assertEquals(50, ws1.get(0));
-        assertEquals("foo", ws1.getName(0));
+        assertEquals(50, ws1.getUid(0));
+        assertEquals("foo", ws1.getPackageName(0));
     }
 
     public void testTransferWorkChains() {
diff --git a/libs/androidfw/include/androidfw/LoadedArsc.h b/libs/androidfw/include/androidfw/LoadedArsc.h
index 6cbda07..b5d3a1f 100644
--- a/libs/androidfw/include/androidfw/LoadedArsc.h
+++ b/libs/androidfw/include/androidfw/LoadedArsc.h
@@ -273,6 +273,8 @@
   ByteBucketArray<uint32_t> resource_ids_;
   std::vector<DynamicPackageEntry> dynamic_package_map_;
   std::vector<const std::pair<OverlayableInfo, std::unordered_set<uint32_t>>> overlayable_infos_;
+
+  // A map of overlayable name to actor
   std::unordered_map<std::string, std::string> overlayable_map_;
 };
 
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index e1f6597..34c5842 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -1947,11 +1947,11 @@
         if (workSource.size() > 0) {
             // If the WorkSource has one or more non-chained UIDs, make sure they're accompanied
             // by tags.
-            return workSource.getName(0) != null;
+            return workSource.getPackageName(0) != null;
         } else {
             // For now, make sure callers have supplied an attribution tag for use with
             // AppOpsManager. This might be relaxed in the future.
-            final ArrayList<WorkChain> workChains = workSource.getWorkChains();
+            final List<WorkChain> workChains = workSource.getWorkChains();
             return workChains != null && !workChains.isEmpty() &&
                     workChains.get(0).getAttributionTag() != null;
         }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 3dc745b..88d0e4b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -8649,7 +8649,7 @@
 
         mBatteryStatsService.noteWakupAlarm(sourcePkg, sourceUid, workSource, tag);
         if (workSource != null) {
-            String workSourcePackage = workSource.getName(0);
+            String workSourcePackage = workSource.getPackageName(0);
             int workSourceUid = workSource.getAttributionUid();
             if (workSourcePackage == null) {
                 workSourcePackage = sourcePkg;
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 637bcae..c84745e 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -1169,14 +1169,15 @@
             if (newWork != null) {
                 for (int i = 0; i < newWork.size(); i++) {
                     mAppOps.startOpNoThrow(AppOpsManager.OP_GPS,
-                            newWork.get(i), newWork.getName(i));
+                            newWork.getUid(i), newWork.getPackageName(i));
                 }
             }
 
             // Update sources that are no longer tracked.
             if (goneWork != null) {
                 for (int i = 0; i < goneWork.size(); i++) {
-                    mAppOps.finishOp(AppOpsManager.OP_GPS, goneWork.get(i), goneWork.getName(i));
+                    mAppOps.finishOp(AppOpsManager.OP_GPS, goneWork.getUid(i),
+                            goneWork.getPackageName(i));
                 }
             }
         }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 0ae4a8f..b60306b 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -360,9 +360,11 @@
     private static final String EXTRA_KEY = "key";
 
     /**
-     * Apps targeting R+ that post custom toasts in the background will have those blocked. Apps can
+     * Apps that post custom toasts in the background will have those blocked. Apps can
      * still post toasts created with {@link Toast#makeText(Context, CharSequence, int)} and its
      * variants while in the background.
+     *
+     * TODO(b/144152069): Add @EnabledAfter(Q) to target R+ after assessing impact on dogfood
      */
     @ChangeId
     private static final long CHANGE_BACKGROUND_CUSTOM_TOAST_BLOCK = 128611929L;
diff --git a/services/core/java/com/android/server/om/OverlayActorEnforcer.java b/services/core/java/com/android/server/om/OverlayActorEnforcer.java
new file mode 100644
index 0000000..e055116
--- /dev/null
+++ b/services/core/java/com/android/server/om/OverlayActorEnforcer.java
@@ -0,0 +1,261 @@
+/*
+ * 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.om;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.om.OverlayInfo;
+import android.content.om.OverlayableInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.net.Uri;
+import android.os.Process;
+import android.os.RemoteException;
+import android.text.TextUtils;
+
+import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.CollectionUtils;
+import com.android.server.SystemConfig;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Performs verification that a calling UID can act on a target package's overlayable.
+ *
+ * @hide
+ */
+public class OverlayActorEnforcer {
+
+    private final VerifyCallback mVerifyCallback;
+
+    public OverlayActorEnforcer(@NonNull VerifyCallback verifyCallback) {
+        mVerifyCallback = verifyCallback;
+    }
+
+    void enforceActor(@NonNull OverlayInfo overlayInfo, @NonNull String methodName,
+            int callingUid, int userId) throws SecurityException {
+        ActorState actorState = isAllowedActor(methodName, overlayInfo, callingUid, userId);
+        if (actorState == ActorState.ALLOWED) {
+            return;
+        }
+
+        String targetOverlayableName = overlayInfo.targetOverlayableName;
+        throw new SecurityException("UID" + callingUid + " is not allowed to call "
+                + methodName + " for "
+                + (TextUtils.isEmpty(targetOverlayableName) ? "" : (targetOverlayableName + " in "))
+                + overlayInfo.targetPackageName + " because " + actorState
+        );
+    }
+
+    /**
+     * An actor is valid if any of the following is true:
+     * - is {@link Process#ROOT_UID}, {@link Process#SYSTEM_UID}
+     * - is the target overlay package
+     * - has the CHANGE_OVERLAY_PACKAGES permission and an actor is not defined
+     * - is the same the as the package defined in {@link SystemConfig#getNamedActors()} for a given
+     *     namespace and actor name
+     *
+     * @return true if the actor is allowed to act on the target overlayInfo
+     */
+    private ActorState isAllowedActor(String methodName, OverlayInfo overlayInfo,
+            int callingUid, int userId) {
+        switch (callingUid) {
+            case Process.ROOT_UID:
+            case Process.SYSTEM_UID:
+                return ActorState.ALLOWED;
+        }
+
+        String[] callingPackageNames = mVerifyCallback.getPackagesForUid(callingUid);
+        if (ArrayUtils.isEmpty(callingPackageNames)) {
+            return ActorState.NO_PACKAGES_FOR_UID;
+        }
+
+        // A target is always an allowed actor for itself
+        String targetPackageName = overlayInfo.targetPackageName;
+        if (ArrayUtils.contains(callingPackageNames, targetPackageName)) {
+            return ActorState.ALLOWED;
+        }
+
+        String targetOverlayableName = overlayInfo.targetOverlayableName;
+
+        if (TextUtils.isEmpty(targetOverlayableName)) {
+            try {
+                if (mVerifyCallback.doesTargetDefineOverlayable(targetPackageName, userId)) {
+                    return ActorState.MISSING_TARGET_OVERLAYABLE_NAME;
+                } else {
+                    // If there's no overlayable defined, fallback to the legacy permission check
+                    try {
+                        mVerifyCallback.enforcePermission(
+                                android.Manifest.permission.CHANGE_OVERLAY_PACKAGES, methodName);
+
+                        // If the previous method didn't throw, check passed
+                        return ActorState.ALLOWED;
+                    } catch (SecurityException e) {
+                        return ActorState.MISSING_LEGACY_PERMISSION;
+                    }
+                }
+            } catch (RemoteException | IOException e) {
+                return ActorState.ERROR_READING_OVERLAYABLE;
+            }
+        }
+
+        OverlayableInfo targetOverlayable;
+        try {
+            targetOverlayable = mVerifyCallback.getOverlayableForTarget(targetPackageName,
+                    targetOverlayableName, userId);
+        } catch (IOException e) {
+            return ActorState.UNABLE_TO_GET_TARGET;
+        }
+
+        if (targetOverlayable == null) {
+            return ActorState.MISSING_OVERLAYABLE;
+        }
+
+        String actor = targetOverlayable.actor;
+        if (TextUtils.isEmpty(actor)) {
+            // If there's no actor defined, fallback to the legacy permission check
+            try {
+                mVerifyCallback.enforcePermission(
+                        android.Manifest.permission.CHANGE_OVERLAY_PACKAGES, methodName);
+
+                // If the previous method didn't throw, check passed
+                return ActorState.ALLOWED;
+            } catch (SecurityException e) {
+                return ActorState.MISSING_LEGACY_PERMISSION;
+            }
+        }
+
+        Map<String, ? extends Map<String, String>> namedActors = mVerifyCallback.getNamedActors();
+        if (namedActors.isEmpty()) {
+            return ActorState.NO_NAMED_ACTORS;
+        }
+
+        Uri actorUri = Uri.parse(actor);
+
+        String actorScheme = actorUri.getScheme();
+        List<String> actorPathSegments = actorUri.getPathSegments();
+        if (!"overlay".equals(actorScheme) || CollectionUtils.size(actorPathSegments) != 1) {
+            return ActorState.INVALID_OVERLAYABLE_ACTOR_NAME;
+        }
+
+        String actorNamespace = actorUri.getAuthority();
+        Map<String, String> namespace = namedActors.get(actorNamespace);
+        if (namespace == null) {
+            return ActorState.MISSING_NAMESPACE;
+        }
+
+        String actorName = actorPathSegments.get(0);
+        String packageName = namespace.get(actorName);
+        if (TextUtils.isEmpty(packageName)) {
+            return ActorState.MISSING_ACTOR_NAME;
+        }
+
+        PackageInfo packageInfo = mVerifyCallback.getPackageInfo(packageName, userId);
+        if (packageInfo == null) {
+            return ActorState.MISSING_APP_INFO;
+        }
+
+        ApplicationInfo appInfo = packageInfo.applicationInfo;
+        if (appInfo == null) {
+            return ActorState.MISSING_APP_INFO;
+        }
+
+        // Currently only pre-installed apps can be actors
+        if (!appInfo.isSystemApp() && !appInfo.isUpdatedSystemApp()) {
+            return ActorState.ACTOR_NOT_PREINSTALLED;
+        }
+
+        if (ArrayUtils.contains(callingPackageNames, packageName)) {
+            return ActorState.ALLOWED;
+        }
+
+        return ActorState.INVALID_ACTOR;
+    }
+
+    /**
+     * For easier logging/debugging, a set of all possible failure/success states when running
+     * enforcement.
+     */
+    private enum ActorState {
+        ALLOWED,
+        INVALID_ACTOR,
+        MISSING_NAMESPACE,
+        MISSING_PACKAGE,
+        MISSING_APP_INFO,
+        ACTOR_NOT_PREINSTALLED,
+        NO_PACKAGES_FOR_UID,
+        MISSING_ACTOR_NAME,
+        ERROR_READING_OVERLAYABLE,
+        MISSING_TARGET_OVERLAYABLE_NAME,
+        MISSING_OVERLAYABLE,
+        INVALID_OVERLAYABLE_ACTOR_NAME,
+        NO_NAMED_ACTORS,
+        UNABLE_TO_GET_TARGET,
+        MISSING_LEGACY_PERMISSION
+    }
+
+    /**
+     * Delegate to the system for querying information about packages.
+     */
+    public interface VerifyCallback {
+
+        /**
+         * Read from the APK and AndroidManifest of a package to return the overlayable defined for
+         * a given name.
+         *
+         * @throws IOException if the target can't be read
+         */
+        @Nullable
+        OverlayableInfo getOverlayableForTarget(@NonNull String packageName,
+                @Nullable String targetOverlayableName, int userId)
+                throws IOException;
+
+        /**
+         * @see android.content.pm.PackageManager#getPackagesForUid(int)
+         */
+        @Nullable
+        String[] getPackagesForUid(int uid);
+
+        /**
+         * @param userId user to filter package visibility by
+         * @see android.content.pm.PackageManager#getPackageInfo(String, int)
+         */
+        @Nullable
+        PackageInfo getPackageInfo(@NonNull String packageName, int userId);
+
+        /**
+         * @return map of system pre-defined, uniquely named actors; keys are namespace,
+         * value maps actor name to package name
+         */
+        @NonNull
+        Map<String, ? extends Map<String, String>> getNamedActors();
+
+        /**
+         * @return true if the target package has declared an overlayable
+         */
+        boolean doesTargetDefineOverlayable(String targetPackageName, int userId)
+                throws RemoteException, IOException;
+
+        /**
+         * @throws SecurityException containing message if the caller doesn't have the given
+         *                           permission
+         */
+        void enforcePermission(String permission, String message) throws SecurityException;
+    }
+}
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index 5f3e503..63de61c 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -39,10 +39,12 @@
 import android.content.IntentFilter;
 import android.content.om.IOverlayManager;
 import android.content.om.OverlayInfo;
+import android.content.om.OverlayableInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.UserInfo;
+import android.content.res.ApkAssets;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Environment;
@@ -63,6 +65,7 @@
 import com.android.server.FgThread;
 import com.android.server.IoThread;
 import com.android.server.LocalServices;
+import com.android.server.SystemConfig;
 import com.android.server.SystemService;
 import com.android.server.pm.UserManagerService;
 
@@ -229,6 +232,8 @@
 
     private final OverlayManagerServiceImpl mImpl;
 
+    private final OverlayActorEnforcer mActorEnforcer;
+
     private final AtomicBoolean mPersistSettingsScheduled = new AtomicBoolean(false);
 
     public OverlayManagerService(@NonNull final Context context) {
@@ -237,12 +242,13 @@
             traceBegin(TRACE_TAG_RRO, "OMS#OverlayManagerService");
             mSettingsFile = new AtomicFile(
                     new File(Environment.getDataSystemDirectory(), "overlays.xml"), "overlays");
-            mPackageManager = new PackageManagerHelper();
+            mPackageManager = new PackageManagerHelper(context);
             mUserManager = UserManagerService.getInstance();
             IdmapManager im = new IdmapManager(mPackageManager);
             mSettings = new OverlayManagerSettings();
             mImpl = new OverlayManagerServiceImpl(mPackageManager, im, mSettings,
                     getDefaultOverlayPackages(), new OverlayChangeListener());
+            mActorEnforcer = new OverlayActorEnforcer(mPackageManager);
 
             final IntentFilter packageFilter = new IntentFilter();
             packageFilter.addAction(ACTION_PACKAGE_ADDED);
@@ -581,7 +587,7 @@
                 int userId) throws RemoteException {
             try {
                 traceBegin(TRACE_TAG_RRO, "OMS#setEnabled " + packageName + " " + enable);
-                enforceChangeOverlayPackagesPermission("setEnabled");
+                enforceActor(packageName, "setEnabled", userId);
                 userId = handleIncomingUser(userId, "setEnabled");
                 if (packageName == null) {
                     return false;
@@ -605,7 +611,7 @@
                 int userId) throws RemoteException {
             try {
                 traceBegin(TRACE_TAG_RRO, "OMS#setEnabledExclusive " + packageName + " " + enable);
-                enforceChangeOverlayPackagesPermission("setEnabledExclusive");
+                enforceActor(packageName, "setEnabledExclusive", userId);
                 userId = handleIncomingUser(userId, "setEnabledExclusive");
                 if (packageName == null || !enable) {
                     return false;
@@ -630,7 +636,7 @@
                 throws RemoteException {
             try {
                 traceBegin(TRACE_TAG_RRO, "OMS#setEnabledExclusiveInCategory " + packageName);
-                enforceChangeOverlayPackagesPermission("setEnabledExclusiveInCategory");
+                enforceActor(packageName, "setEnabledExclusiveInCategory", userId);
                 userId = handleIncomingUser(userId, "setEnabledExclusiveInCategory");
                 if (packageName == null) {
                     return false;
@@ -656,7 +662,7 @@
             try {
                 traceBegin(TRACE_TAG_RRO, "OMS#setPriority " + packageName + " "
                         + parentPackageName);
-                enforceChangeOverlayPackagesPermission("setPriority");
+                enforceActor(packageName, "setPriority", userId);
                 userId = handleIncomingUser(userId, "setPriority");
                 if (packageName == null || parentPackageName == null) {
                     return false;
@@ -680,7 +686,7 @@
                 throws RemoteException {
             try {
                 traceBegin(TRACE_TAG_RRO, "OMS#setHighestPriority " + packageName);
-                enforceChangeOverlayPackagesPermission("setHighestPriority");
+                enforceActor(packageName, "setHighestPriority", userId);
                 userId = handleIncomingUser(userId, "setHighestPriority");
                 if (packageName == null) {
                     return false;
@@ -704,7 +710,7 @@
                 throws RemoteException {
             try {
                 traceBegin(TRACE_TAG_RRO, "OMS#setLowestPriority " + packageName);
-                enforceChangeOverlayPackagesPermission("setLowestPriority");
+                enforceActor(packageName, "setLowestPriority", userId);
                 userId = handleIncomingUser(userId, "setLowestPriority");
                 if (packageName == null) {
                     return false;
@@ -750,7 +756,7 @@
                 return;
             }
 
-            enforceChangeOverlayPackagesPermission("invalidateCachesForOverlay");
+            enforceActor(packageName, "invalidateCachesForOverlay", userId);
             userId = handleIncomingUser(userId, "invalidateCachesForOverlay");
             final long ident = Binder.clearCallingIdentity();
             try {
@@ -861,18 +867,6 @@
         }
 
         /**
-         * Enforce that the caller holds the CHANGE_OVERLAY_PACKAGES permission (or is
-         * system or root).
-         *
-         * @param message used as message if SecurityException is thrown
-         * @throws SecurityException if the permission check fails
-         */
-        private void enforceChangeOverlayPackagesPermission(@NonNull final String message) {
-            getContext().enforceCallingOrSelfPermission(
-                    android.Manifest.permission.CHANGE_OVERLAY_PACKAGES, message);
-        }
-
-        /**
          * Enforce that the caller holds the DUMP permission (or is system or root).
          *
          * @param message used as message if SecurityException is thrown
@@ -881,6 +875,13 @@
         private void enforceDumpPermission(@NonNull final String message) {
             getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, message);
         }
+
+        private void enforceActor(String packageName, String methodName, int userId)
+                throws SecurityException {
+            OverlayInfo overlayInfo = mImpl.getOverlayInfo(packageName, userId);
+            int callingUid = Binder.getCallingUid();
+            mActorEnforcer.enforceActor(overlayInfo, methodName, callingUid, userId);
+        }
     };
 
     private final class OverlayChangeListener
@@ -1035,9 +1036,16 @@
         }
     }
 
-    private static final class PackageManagerHelper implements
-            OverlayManagerServiceImpl.PackageManagerHelper {
+    /**
+     * Delegate for {@link android.content.pm.PackageManager} and {@link PackageManagerInternal}
+     * functionality, separated for easy testing.
+     *
+     * @hide
+     */
+    public static final class PackageManagerHelper implements
+            OverlayManagerServiceImpl.PackageManagerHelper, OverlayActorEnforcer.VerifyCallback {
 
+        private final Context mContext;
         private final IPackageManager mPackageManager;
         private final PackageManagerInternal mPackageManagerInternal;
 
@@ -1048,11 +1056,14 @@
         // behind until all pending intents have been processed.
         private final SparseArray<HashMap<String, PackageInfo>> mCache = new SparseArray<>();
 
-        PackageManagerHelper() {
+        PackageManagerHelper(Context context) {
+            mContext = context;
             mPackageManager = getPackageManager();
             mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
         }
 
+        // TODO(b/143096091): Remove PackageInfo cache so that PackageManager is always queried
+        //  to enforce visibility/other permission checks
         public PackageInfo getPackageInfo(@NonNull final String packageName, final int userId,
                 final boolean useCache) {
             if (useCache) {
@@ -1075,7 +1086,19 @@
 
         @Override
         public PackageInfo getPackageInfo(@NonNull final String packageName, final int userId) {
-            return getPackageInfo(packageName, userId, true);
+            // TODO(b/143096091): Remove clearing calling ID
+            long callingIdentity = Binder.clearCallingIdentity();
+            try {
+                return getPackageInfo(packageName, userId, true);
+            } finally {
+                Binder.restoreCallingIdentity(callingIdentity);
+            }
+        }
+
+        @NonNull
+        @Override
+        public Map<String, ? extends Map<String, String>> getNamedActors() {
+            return SystemConfig.getInstance().getNamedActors();
         }
 
         @Override
@@ -1097,6 +1120,70 @@
             return mPackageManagerInternal.getOverlayPackages(userId);
         }
 
+        @Nullable
+        @Override
+        public OverlayableInfo getOverlayableForTarget(@NonNull String packageName,
+                @Nullable String targetOverlayableName, int userId)
+                throws IOException {
+            // TODO(b/143096091): Remove clearing calling ID
+            long callingIdentity = Binder.clearCallingIdentity();
+            try {
+                PackageInfo packageInfo = getPackageInfo(packageName, userId);
+                if (packageInfo == null) {
+                    throw new IOException("Unable to get target package");
+                }
+
+                String baseCodePath = packageInfo.applicationInfo.getBaseCodePath();
+
+                ApkAssets apkAssets = null;
+                try {
+                    apkAssets = ApkAssets.loadFromPath(baseCodePath);
+                    return apkAssets.getOverlayableInfo(targetOverlayableName);
+                } finally {
+                    if (apkAssets != null) {
+                        try {
+                            apkAssets.close();
+                        } catch (Throwable ignored) {
+                        }
+                    }
+                }
+            } finally {
+                Binder.restoreCallingIdentity(callingIdentity);
+            }
+        }
+
+        @Override
+        public boolean doesTargetDefineOverlayable(String targetPackageName, int userId)
+                throws RemoteException, IOException {
+            // TODO(b/143096091): Remove clearing calling ID
+            long callingIdentity = Binder.clearCallingIdentity();
+            try {
+                PackageInfo packageInfo = mPackageManager.getPackageInfo(targetPackageName, 0,
+                        userId);
+                String baseCodePath = packageInfo.applicationInfo.getBaseCodePath();
+
+                ApkAssets apkAssets = null;
+                try {
+                    apkAssets = ApkAssets.loadFromPath(baseCodePath);
+                    return apkAssets.definesOverlayable();
+                } finally {
+                    if (apkAssets != null) {
+                        try {
+                            apkAssets.close();
+                        } catch (Throwable ignored) {
+                        }
+                    }
+                }
+            } finally {
+                Binder.restoreCallingIdentity(callingIdentity);
+            }
+        }
+
+        @Override
+        public void enforcePermission(String permission, String message) throws SecurityException {
+            mContext.enforceCallingOrSelfPermission(permission, message);
+        }
+
         public PackageInfo getCachedPackageInfo(@NonNull final String packageName,
                 final int userId) {
             final HashMap<String, PackageInfo> map = mCache.get(userId);
@@ -1128,6 +1215,22 @@
             mCache.delete(userId);
         }
 
+        @Nullable
+        @Override
+        public String[] getPackagesForUid(int uid) {
+            // TODO(b/143096091): Remove clearing calling ID
+            long callingIdentity = Binder.clearCallingIdentity();
+            try {
+                try {
+                    return mPackageManager.getPackagesForUid(uid);
+                } catch (RemoteException ignored) {
+                    return null;
+                }
+            } finally {
+                Binder.restoreCallingIdentity(callingIdentity);
+            }
+        }
+
         private static final String TAB1 = "    ";
         private static final String TAB2 = TAB1 + TAB1;
 
diff --git a/services/core/java/com/android/server/pm/OWNERS b/services/core/java/com/android/server/pm/OWNERS
index 62ea95b..f8c173f 100644
--- a/services/core/java/com/android/server/pm/OWNERS
+++ b/services/core/java/com/android/server/pm/OWNERS
@@ -32,6 +32,9 @@
 per-file CrossProfileIntentResolver.java = omakoto@google.com, yamasani@google.com
 per-file UserManagerService.java = omakoto@google.com, yamasani@google.com
 per-file UserRestrictionsUtils.java = omakoto@google.com, rubinxu@google.com, sandness@google.com, yamasani@google.com
+per-file UserSystemPackageInstaller.java = bookatz@google.com, omakoto@google.com, yamasani@google.com
+per-file UserTypeDetails.java = bookatz@google.com, omakoto@google.com, yamasani@google.com
+per-file UserTypeFactory.java = bookatz@google.com, omakoto@google.com, yamasani@google.com
 
 # security
 per-file KeySetHandle.java = cbrubaker@google.com, nnk@google.com
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index fce7f04..9cfd095 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -107,6 +107,7 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 import java.util.Objects;
 
 /**
@@ -1174,9 +1175,9 @@
                     opPackageName = workChain.getAttributionTag();
                     opUid = workChain.getAttributionUid();
                 } else {
-                    opPackageName = workSource.getName(0) != null
-                            ? workSource.getName(0) : wakeLock.mPackageName;
-                    opUid = workSource.get(0);
+                    opPackageName = workSource.getPackageName(0) != null
+                            ? workSource.getPackageName(0) : wakeLock.mPackageName;
+                    opUid = workSource.getUid(0);
                 }
             } else {
                 opPackageName = wakeLock.mPackageName;
@@ -2004,13 +2005,13 @@
     private boolean wakeLockAffectsUser(WakeLock wakeLock, @UserIdInt int userId) {
         if (wakeLock.mWorkSource != null) {
             for (int k = 0; k < wakeLock.mWorkSource.size(); k++) {
-                final int uid = wakeLock.mWorkSource.get(k);
+                final int uid = wakeLock.mWorkSource.getUid(k);
                 if (userId == UserHandle.getUserId(uid)) {
                     return true;
                 }
             }
 
-            final ArrayList<WorkChain> workChains = wakeLock.mWorkSource.getWorkChains();
+            final List<WorkChain> workChains = wakeLock.mWorkSource.getWorkChains();
             if (workChains != null) {
                 for (int k = 0; k < workChains.size(); k++) {
                     final int uid = workChains.get(k).getAttributionUid();
diff --git a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
index d78aaa5..fe18fbf 100644
--- a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
+++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
@@ -27,6 +27,7 @@
 import android.os.SystemProperties;
 import android.util.Slog;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.SystemService;
 
 import libcore.io.IoUtils;
@@ -35,6 +36,7 @@
 import java.io.DataOutputStream;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 
 /**
  * The recovery system service is responsible for coordinating recovery related
@@ -43,7 +45,7 @@
  * triggers /system/bin/uncrypt via init to de-encrypt an OTA package on the
  * /data partition so that it can be accessed under the recovery image.
  */
-public final class RecoverySystemService extends SystemService {
+public class RecoverySystemService extends IRecoverySystem.Stub {
     private static final String TAG = "RecoverySystemService";
     private static final boolean DEBUG = false;
 
@@ -51,191 +53,321 @@
     private static final String UNCRYPT_SOCKET = "uncrypt";
 
     // The init services that communicate with /system/bin/uncrypt.
-    private static final String INIT_SERVICE_UNCRYPT = "init.svc.uncrypt";
-    private static final String INIT_SERVICE_SETUP_BCB = "init.svc.setup-bcb";
-    private static final String INIT_SERVICE_CLEAR_BCB = "init.svc.clear-bcb";
-
-    private static final int SOCKET_CONNECTION_MAX_RETRY = 30;
+    @VisibleForTesting
+    static final String INIT_SERVICE_UNCRYPT = "init.svc.uncrypt";
+    @VisibleForTesting
+    static final String INIT_SERVICE_SETUP_BCB = "init.svc.setup-bcb";
+    @VisibleForTesting
+    static final String INIT_SERVICE_CLEAR_BCB = "init.svc.clear-bcb";
 
     private static final Object sRequestLock = new Object();
 
-    private Context mContext;
+    private static final int SOCKET_CONNECTION_MAX_RETRY = 30;
 
-    public RecoverySystemService(Context context) {
-        super(context);
-        mContext = context;
+    private final Injector mInjector;
+    private final Context mContext;
+
+    static class Injector {
+        protected final Context mContext;
+
+        Injector(Context context) {
+            mContext = context;
+        }
+
+        public Context getContext() {
+            return mContext;
+        }
+
+        public PowerManager getPowerManager() {
+            return (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+        }
+
+        public String systemPropertiesGet(String key) {
+            return SystemProperties.get(key);
+        }
+
+        public void systemPropertiesSet(String key, String value) {
+            SystemProperties.set(key, value);
+        }
+
+        public boolean uncryptPackageFileDelete() {
+            return RecoverySystem.UNCRYPT_PACKAGE_FILE.delete();
+        }
+
+        public String getUncryptPackageFileName() {
+            return RecoverySystem.UNCRYPT_PACKAGE_FILE.getName();
+        }
+
+        public FileWriter getUncryptPackageFileWriter() throws IOException {
+            return new FileWriter(RecoverySystem.UNCRYPT_PACKAGE_FILE);
+        }
+
+        public UncryptSocket connectService() {
+            UncryptSocket socket = new UncryptSocket();
+            if (!socket.connectService()) {
+                socket.close();
+                return null;
+            }
+            return socket;
+        }
+
+        public void threadSleep(long millis) throws InterruptedException {
+            Thread.sleep(millis);
+        }
     }
 
-    @Override
-    public void onStart() {
-        publishBinderService(Context.RECOVERY_SERVICE, new BinderService());
+    /**
+     * Handles the lifecycle events for the RecoverySystemService.
+     */
+    public static final class Lifecycle extends SystemService {
+        public Lifecycle(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void onStart() {
+            RecoverySystemService recoverySystemService = new RecoverySystemService(getContext());
+            publishBinderService(Context.RECOVERY_SERVICE, recoverySystemService);
+        }
     }
 
-    private final class BinderService extends IRecoverySystem.Stub {
-        @Override // Binder call
-        public boolean uncrypt(String filename, IRecoverySystemProgressListener listener) {
-            if (DEBUG) Slog.d(TAG, "uncrypt: " + filename);
+    private RecoverySystemService(Context context) {
+        this(new Injector(context));
+    }
 
-            synchronized (sRequestLock) {
-                mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null);
+    @VisibleForTesting
+    RecoverySystemService(Injector injector) {
+        mInjector = injector;
+        mContext = injector.getContext();
+    }
 
-                final boolean available = checkAndWaitForUncryptService();
-                if (!available) {
-                    Slog.e(TAG, "uncrypt service is unavailable.");
-                    return false;
-                }
+    @Override // Binder call
+    public boolean uncrypt(String filename, IRecoverySystemProgressListener listener) {
+        if (DEBUG) Slog.d(TAG, "uncrypt: " + filename);
 
-                // Write the filename into UNCRYPT_PACKAGE_FILE to be read by
-                // uncrypt.
-                RecoverySystem.UNCRYPT_PACKAGE_FILE.delete();
+        synchronized (sRequestLock) {
+            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null);
 
-                try (FileWriter uncryptFile = new FileWriter(RecoverySystem.UNCRYPT_PACKAGE_FILE)) {
-                    uncryptFile.write(filename + "\n");
-                } catch (IOException e) {
-                    Slog.e(TAG, "IOException when writing \"" +
-                            RecoverySystem.UNCRYPT_PACKAGE_FILE + "\":", e);
-                    return false;
-                }
+            if (!checkAndWaitForUncryptService()) {
+                Slog.e(TAG, "uncrypt service is unavailable.");
+                return false;
+            }
 
-                // Trigger uncrypt via init.
-                SystemProperties.set("ctl.start", "uncrypt");
+            // Write the filename into uncrypt package file to be read by
+            // uncrypt.
+            mInjector.uncryptPackageFileDelete();
 
-                // Connect to the uncrypt service socket.
-                LocalSocket socket = connectService();
-                if (socket == null) {
-                    Slog.e(TAG, "Failed to connect to uncrypt socket");
-                    return false;
-                }
+            try (FileWriter uncryptFile = mInjector.getUncryptPackageFileWriter()) {
+                uncryptFile.write(filename + "\n");
+            } catch (IOException e) {
+                Slog.e(TAG, "IOException when writing \""
+                        + mInjector.getUncryptPackageFileName() + "\":", e);
+                return false;
+            }
 
-                // Read the status from the socket.
-                DataInputStream dis = null;
-                DataOutputStream dos = null;
-                try {
-                    dis = new DataInputStream(socket.getInputStream());
-                    dos = new DataOutputStream(socket.getOutputStream());
-                    int lastStatus = Integer.MIN_VALUE;
-                    while (true) {
-                        int status = dis.readInt();
-                        // Avoid flooding the log with the same message.
-                        if (status == lastStatus && lastStatus != Integer.MIN_VALUE) {
-                            continue;
-                        }
-                        lastStatus = status;
+            // Trigger uncrypt via init.
+            mInjector.systemPropertiesSet("ctl.start", "uncrypt");
 
-                        if (status >= 0 && status <= 100) {
-                            // Update status
-                            Slog.i(TAG, "uncrypt read status: " + status);
-                            if (listener != null) {
-                                try {
-                                    listener.onProgress(status);
-                                } catch (RemoteException ignored) {
-                                    Slog.w(TAG, "RemoteException when posting progress");
-                                }
-                            }
-                            if (status == 100) {
-                                Slog.i(TAG, "uncrypt successfully finished.");
-                                // Ack receipt of the final status code. uncrypt
-                                // waits for the ack so the socket won't be
-                                // destroyed before we receive the code.
-                                dos.writeInt(0);
-                                break;
-                            }
-                        } else {
-                            // Error in /system/bin/uncrypt.
-                            Slog.e(TAG, "uncrypt failed with status: " + status);
-                            // Ack receipt of the final status code. uncrypt waits
-                            // for the ack so the socket won't be destroyed before
-                            // we receive the code.
-                            dos.writeInt(0);
-                            return false;
-                        }
+            // Connect to the uncrypt service socket.
+            UncryptSocket socket = mInjector.connectService();
+            if (socket == null) {
+                Slog.e(TAG, "Failed to connect to uncrypt socket");
+                return false;
+            }
+
+            // Read the status from the socket.
+            try {
+                int lastStatus = Integer.MIN_VALUE;
+                while (true) {
+                    int status = socket.getPercentageUncrypted();
+                    // Avoid flooding the log with the same message.
+                    if (status == lastStatus && lastStatus != Integer.MIN_VALUE) {
+                        continue;
                     }
-                } catch (IOException e) {
-                    Slog.e(TAG, "IOException when reading status: ", e);
-                    return false;
-                } finally {
-                    IoUtils.closeQuietly(dis);
-                    IoUtils.closeQuietly(dos);
-                    IoUtils.closeQuietly(socket);
-                }
+                    lastStatus = status;
 
+                    if (status >= 0 && status <= 100) {
+                        // Update status
+                        Slog.i(TAG, "uncrypt read status: " + status);
+                        if (listener != null) {
+                            try {
+                                listener.onProgress(status);
+                            } catch (RemoteException ignored) {
+                                Slog.w(TAG, "RemoteException when posting progress");
+                            }
+                        }
+                        if (status == 100) {
+                            Slog.i(TAG, "uncrypt successfully finished.");
+                            // Ack receipt of the final status code. uncrypt
+                            // waits for the ack so the socket won't be
+                            // destroyed before we receive the code.
+                            socket.sendAck();
+                            break;
+                        }
+                    } else {
+                        // Error in /system/bin/uncrypt.
+                        Slog.e(TAG, "uncrypt failed with status: " + status);
+                        // Ack receipt of the final status code. uncrypt waits
+                        // for the ack so the socket won't be destroyed before
+                        // we receive the code.
+                        socket.sendAck();
+                        return false;
+                    }
+                }
+            } catch (IOException e) {
+                Slog.e(TAG, "IOException when reading status: ", e);
+                return false;
+            } finally {
+                socket.close();
+            }
+
+            return true;
+        }
+    }
+
+    @Override // Binder call
+    public boolean clearBcb() {
+        if (DEBUG) Slog.d(TAG, "clearBcb");
+        synchronized (sRequestLock) {
+            return setupOrClearBcb(false, null);
+        }
+    }
+
+    @Override // Binder call
+    public boolean setupBcb(String command) {
+        if (DEBUG) Slog.d(TAG, "setupBcb: [" + command + "]");
+        synchronized (sRequestLock) {
+            return setupOrClearBcb(true, command);
+        }
+    }
+
+    @Override // Binder call
+    public void rebootRecoveryWithCommand(String command) {
+        if (DEBUG) Slog.d(TAG, "rebootRecoveryWithCommand: [" + command + "]");
+        synchronized (sRequestLock) {
+            if (!setupOrClearBcb(true, command)) {
+                return;
+            }
+
+            // Having set up the BCB, go ahead and reboot.
+            PowerManager pm = mInjector.getPowerManager();
+            pm.reboot(PowerManager.REBOOT_RECOVERY);
+        }
+    }
+
+    /**
+     * Check if any of the init services is still running. If so, we cannot
+     * start a new uncrypt/setup-bcb/clear-bcb service right away; otherwise
+     * it may break the socket communication since init creates / deletes
+     * the socket (/dev/socket/uncrypt) on service start / exit.
+     */
+    private boolean checkAndWaitForUncryptService() {
+        for (int retry = 0; retry < SOCKET_CONNECTION_MAX_RETRY; retry++) {
+            final String uncryptService = mInjector.systemPropertiesGet(INIT_SERVICE_UNCRYPT);
+            final String setupBcbService = mInjector.systemPropertiesGet(INIT_SERVICE_SETUP_BCB);
+            final String clearBcbService = mInjector.systemPropertiesGet(INIT_SERVICE_CLEAR_BCB);
+            final boolean busy = "running".equals(uncryptService)
+                    || "running".equals(setupBcbService) || "running".equals(clearBcbService);
+            if (DEBUG) {
+                Slog.i(TAG, "retry: " + retry + " busy: " + busy
+                        + " uncrypt: [" + uncryptService + "]"
+                        + " setupBcb: [" + setupBcbService + "]"
+                        + " clearBcb: [" + clearBcbService + "]");
+            }
+
+            if (!busy) {
                 return true;
             }
-        }
 
-        @Override // Binder call
-        public boolean clearBcb() {
-            if (DEBUG) Slog.d(TAG, "clearBcb");
-            synchronized (sRequestLock) {
-                return setupOrClearBcb(false, null);
+            try {
+                mInjector.threadSleep(1000);
+            } catch (InterruptedException e) {
+                Slog.w(TAG, "Interrupted:", e);
             }
         }
 
-        @Override // Binder call
-        public boolean setupBcb(String command) {
-            if (DEBUG) Slog.d(TAG, "setupBcb: [" + command + "]");
-            synchronized (sRequestLock) {
-                return setupOrClearBcb(true, command);
-            }
-        }
+        return false;
+    }
 
-        @Override // Binder call
-        public void rebootRecoveryWithCommand(String command) {
-            if (DEBUG) Slog.d(TAG, "rebootRecoveryWithCommand: [" + command + "]");
-            synchronized (sRequestLock) {
-                if (!setupOrClearBcb(true, command)) {
-                    return;
-                }
+    private boolean setupOrClearBcb(boolean isSetup, String command) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null);
 
-                // Having set up the BCB, go ahead and reboot.
-                PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
-                pm.reboot(PowerManager.REBOOT_RECOVERY);
-            }
-        }
-
-        /**
-         * Check if any of the init services is still running. If so, we cannot
-         * start a new uncrypt/setup-bcb/clear-bcb service right away; otherwise
-         * it may break the socket communication since init creates / deletes
-         * the socket (/dev/socket/uncrypt) on service start / exit.
-         */
-        private boolean checkAndWaitForUncryptService() {
-            for (int retry = 0; retry < SOCKET_CONNECTION_MAX_RETRY; retry++) {
-                final String uncryptService = SystemProperties.get(INIT_SERVICE_UNCRYPT);
-                final String setupBcbService = SystemProperties.get(INIT_SERVICE_SETUP_BCB);
-                final String clearBcbService = SystemProperties.get(INIT_SERVICE_CLEAR_BCB);
-                final boolean busy = "running".equals(uncryptService) ||
-                        "running".equals(setupBcbService) || "running".equals(clearBcbService);
-                if (DEBUG) {
-                    Slog.i(TAG, "retry: " + retry + " busy: " + busy +
-                            " uncrypt: [" + uncryptService + "]" +
-                            " setupBcb: [" + setupBcbService + "]" +
-                            " clearBcb: [" + clearBcbService + "]");
-                }
-
-                if (!busy) {
-                    return true;
-                }
-
-                try {
-                    Thread.sleep(1000);
-                } catch (InterruptedException e) {
-                    Slog.w(TAG, "Interrupted:", e);
-                }
-            }
-
+        final boolean available = checkAndWaitForUncryptService();
+        if (!available) {
+            Slog.e(TAG, "uncrypt service is unavailable.");
             return false;
         }
 
-        private LocalSocket connectService() {
-            LocalSocket socket = new LocalSocket();
+        if (isSetup) {
+            mInjector.systemPropertiesSet("ctl.start", "setup-bcb");
+        } else {
+            mInjector.systemPropertiesSet("ctl.start", "clear-bcb");
+        }
+
+        // Connect to the uncrypt service socket.
+        UncryptSocket socket = mInjector.connectService();
+        if (socket == null) {
+            Slog.e(TAG, "Failed to connect to uncrypt socket");
+            return false;
+        }
+
+        try {
+            // Send the BCB commands if it's to setup BCB.
+            if (isSetup) {
+                socket.sendCommand(command);
+            }
+
+            // Read the status from the socket.
+            int status = socket.getPercentageUncrypted();
+
+            // Ack receipt of the status code. uncrypt waits for the ack so
+            // the socket won't be destroyed before we receive the code.
+            socket.sendAck();
+
+            if (status == 100) {
+                Slog.i(TAG, "uncrypt " + (isSetup ? "setup" : "clear")
+                        + " bcb successfully finished.");
+            } else {
+                // Error in /system/bin/uncrypt.
+                Slog.e(TAG, "uncrypt failed with status: " + status);
+                return false;
+            }
+        } catch (IOException e) {
+            Slog.e(TAG, "IOException when communicating with uncrypt:", e);
+            return false;
+        } finally {
+            socket.close();
+        }
+
+        return true;
+    }
+
+    /**
+     * Provides a wrapper for the low-level details of framing packets sent to the uncrypt
+     * socket.
+     */
+    public static class UncryptSocket {
+        private LocalSocket mLocalSocket;
+        private DataInputStream mInputStream;
+        private DataOutputStream mOutputStream;
+
+        /**
+         * Attempt to connect to the uncrypt service. Connection will be retried for up to
+         * {@link #SOCKET_CONNECTION_MAX_RETRY} times. If the connection is unsuccessful, the
+         * socket will be closed. If the connection is successful, the connection must be closed
+         * by the caller.
+         *
+         * @return true if connection was successful, false if unsuccessful
+         */
+        public boolean connectService() {
+            mLocalSocket = new LocalSocket();
             boolean done = false;
             // The uncrypt socket will be created by init upon receiving the
             // service request. It may not be ready by this point. So we will
             // keep retrying until success or reaching timeout.
             for (int retry = 0; retry < SOCKET_CONNECTION_MAX_RETRY; retry++) {
                 try {
-                    socket.connect(new LocalSocketAddress(UNCRYPT_SOCKET,
+                    mLocalSocket.connect(new LocalSocketAddress(UNCRYPT_SOCKET,
                             LocalSocketAddress.Namespace.RESERVED));
                     done = true;
                     break;
@@ -249,71 +381,69 @@
             }
             if (!done) {
                 Slog.e(TAG, "Timed out connecting to uncrypt socket");
-                return null;
-            }
-            return socket;
-        }
-
-        private boolean setupOrClearBcb(boolean isSetup, String command) {
-            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null);
-
-            final boolean available = checkAndWaitForUncryptService();
-            if (!available) {
-                Slog.e(TAG, "uncrypt service is unavailable.");
+                close();
                 return false;
             }
 
-            if (isSetup) {
-                SystemProperties.set("ctl.start", "setup-bcb");
-            } else {
-                SystemProperties.set("ctl.start", "clear-bcb");
-            }
-
-            // Connect to the uncrypt service socket.
-            LocalSocket socket = connectService();
-            if (socket == null) {
-                Slog.e(TAG, "Failed to connect to uncrypt socket");
-                return false;
-            }
-
-            DataInputStream dis = null;
-            DataOutputStream dos = null;
             try {
-                dis = new DataInputStream(socket.getInputStream());
-                dos = new DataOutputStream(socket.getOutputStream());
-
-                // Send the BCB commands if it's to setup BCB.
-                if (isSetup) {
-                    byte[] cmdUtf8 = command.getBytes("UTF-8");
-                    dos.writeInt(cmdUtf8.length);
-                    dos.write(cmdUtf8, 0, cmdUtf8.length);
-                }
-
-                // Read the status from the socket.
-                int status = dis.readInt();
-
-                // Ack receipt of the status code. uncrypt waits for the ack so
-                // the socket won't be destroyed before we receive the code.
-                dos.writeInt(0);
-
-                if (status == 100) {
-                    Slog.i(TAG, "uncrypt " + (isSetup ? "setup" : "clear") +
-                            " bcb successfully finished.");
-                } else {
-                    // Error in /system/bin/uncrypt.
-                    Slog.e(TAG, "uncrypt failed with status: " + status);
-                    return false;
-                }
+                mInputStream = new DataInputStream(mLocalSocket.getInputStream());
+                mOutputStream = new DataOutputStream(mLocalSocket.getOutputStream());
             } catch (IOException e) {
-                Slog.e(TAG, "IOException when communicating with uncrypt:", e);
+                close();
                 return false;
-            } finally {
-                IoUtils.closeQuietly(dis);
-                IoUtils.closeQuietly(dos);
-                IoUtils.closeQuietly(socket);
             }
 
             return true;
         }
+
+        /**
+         * Sends a command to the uncrypt service.
+         *
+         * @param command command to send to the uncrypt service
+         * @throws IOException if the socket is closed or there was an error writing to the socket
+         */
+        public void sendCommand(String command) throws IOException {
+            if (mLocalSocket.isClosed()) {
+                throw new IOException("socket is closed");
+            }
+
+            byte[] cmdUtf8 = command.getBytes(StandardCharsets.UTF_8);
+            mOutputStream.writeInt(cmdUtf8.length);
+            mOutputStream.write(cmdUtf8, 0, cmdUtf8.length);
+        }
+
+        /**
+         * Reads the status from the uncrypt service which is usually represented as a percentage.
+         * @return an integer representing the percentage completed
+         * @throws IOException if the socket was closed or there was an error reading the socket
+         */
+        public int getPercentageUncrypted() throws IOException {
+            if (mLocalSocket.isClosed()) {
+                throw new IOException("socket is closed");
+            }
+
+            return mInputStream.readInt();
+        }
+
+        /**
+         * Sends a confirmation to the uncrypt service.
+         * @throws IOException if the socket was closed or there was an error writing to the socket
+         */
+        public void sendAck() throws IOException {
+            if (mLocalSocket.isClosed()) {
+                throw new IOException("socket is closed");
+            }
+
+            mOutputStream.writeInt(0);
+        }
+
+        /**
+         * Closes the socket and all underlying data streams.
+         */
+        public void close() {
+            IoUtils.closeQuietly(mInputStream);
+            IoUtils.closeQuietly(mOutputStream);
+            IoUtils.closeQuietly(mLocalSocket);
+        }
     }
 }
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index 11f09d0..a0b878c 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -92,12 +92,13 @@
         // Refer to WindowManagerService#applyImeVisibility(token, false).
         // If IMMS's imeTarget is child of DisplayContent's imeTarget and child window
         // is above the parent, we will consider it as the same target for now.
+        // Also, if imeTarget is closing, it would be considered as outdated target.
         // TODO(b/139861270): Remove the child & sublayer check once IMMS is aware of
         //  actual IME target.
-        return mImeTargetFromIme == mDisplayContent.mInputMethodTarget
-                || (mDisplayContent.mInputMethodTarget.getParentWindow() == mImeTargetFromIme
-                        && mDisplayContent.mInputMethodTarget.mSubLayer
-                                > mImeTargetFromIme.mSubLayer);
+        final WindowState dcTarget = mDisplayContent.mInputMethodTarget;
+        return (!dcTarget.isClosing() && mImeTargetFromIme == dcTarget)
+                || (dcTarget.getParentWindow() == mImeTargetFromIme
+                        && dcTarget.mSubLayer > mImeTargetFromIme.mSubLayer);
     }
 
 }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 2d6d5f4..a42f2e1 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -143,6 +143,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
 import android.content.res.Configuration;
+import android.content.res.TypedArray;
 import android.database.ContentObserver;
 import android.graphics.Bitmap;
 import android.graphics.Insets;
@@ -1247,6 +1248,20 @@
 
         LocalServices.addService(WindowManagerInternal.class, new LocalService());
         mEmbeddedWindowController = new EmbeddedWindowController(mGlobalLock);
+        setGlobalShadowSettings();
+    }
+
+    private void setGlobalShadowSettings() {
+        final TypedArray a = mContext.obtainStyledAttributes(null, R.styleable.Lighting, 0, 0);
+        float lightY = a.getDimension(R.styleable.Lighting_lightY, 0);
+        float lightZ = a.getDimension(R.styleable.Lighting_lightZ, 0);
+        float lightRadius = a.getDimension(R.styleable.Lighting_lightRadius, 0);
+        float ambientShadowAlpha = a.getFloat(R.styleable.Lighting_ambientShadowAlpha, 0);
+        float spotShadowAlpha = a.getFloat(R.styleable.Lighting_spotShadowAlpha, 0);
+        float[] ambientColor = {0.f, 0.f, 0.f, ambientShadowAlpha};
+        float[] spotColor = {0.f, 0.f, 0.f, spotShadowAlpha};
+        SurfaceControl.setGlobalShadowSettings(ambientColor, spotColor, lightY, lightZ,
+                lightRadius);
     }
 
     /**
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index f1ed1d9..39d840f 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -281,7 +281,8 @@
             "com.android.server.DeviceIdleController";
     private static final String BLOB_STORE_MANAGER_SERVICE_CLASS =
             "com.android.server.blob.BlobStoreManagerService";
-
+    private static final String APP_SEARCH_MANAGER_SERVICE_CLASS =
+            "com.android.server.appsearch.AppSearchManagerService";
     private static final String PERSISTENT_DATA_BLOCK_PROP = "ro.frp.pst";
 
     private static final String UNCRYPT_PACKAGE_FILE = "/cache/recovery/uncrypt_file";
@@ -704,7 +705,7 @@
 
         // Bring up recovery system in case a rescue party needs a reboot
         t.traceBegin("StartRecoverySystemService");
-        mSystemServiceManager.startService(RecoverySystemService.class);
+        mSystemServiceManager.startService(RecoverySystemService.Lifecycle.class);
         t.traceEnd();
 
         // Now that we have the bare essentials of the OS up and running, take
@@ -2023,6 +2024,10 @@
         mSystemServiceManager.startBootPhase(t, SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY);
         t.traceEnd();
 
+        t.traceBegin("AppSearchManagerService");
+        mSystemServiceManager.startService(APP_SEARCH_MANAGER_SERVICE_CLASS);
+        t.traceEnd();
+
         // These are needed to propagate to the runnable below.
         final NetworkManagementService networkManagementF = networkManagement;
         final NetworkStatsService networkStatsF = networkStats;
diff --git a/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java b/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
index 6a90d0b..2510b60 100644
--- a/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
@@ -713,7 +713,7 @@
                     // Verify has set work source and hasn't unset yet.
                     verify(mBackupManagerService)
                             .setWorkSource(
-                                    argThat(workSource -> workSource.get(0) == PACKAGE_1.uid));
+                                    argThat(workSource -> workSource.getUid(0) == PACKAGE_1.uid));
                     verify(mBackupManagerService, never()).setWorkSource(null);
                 });
         KeyValueBackupTask task = createKeyValueBackupTask(transportMock, PACKAGE_1);
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index 30ccb71..52fb69e 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -8,6 +8,7 @@
     // Include all test java files.
     srcs: [
         "src/**/*.java",
+        "src/**/*.kt",
 
         "aidl/com/android/servicestests/aidl/INetworkStateObserver.aidl",
         "aidl/com/android/servicestests/aidl/ICmdReceiverService.aidl",
diff --git a/services/tests/servicestests/src/com/android/server/om/OverlayActorEnforcerTests.kt b/services/tests/servicestests/src/com/android/server/om/OverlayActorEnforcerTests.kt
new file mode 100644
index 0000000..233e16c
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/om/OverlayActorEnforcerTests.kt
@@ -0,0 +1,197 @@
+/*
+ * 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.om
+
+import android.content.om.OverlayInfo
+import android.content.om.OverlayableInfo
+import android.content.pm.ApplicationInfo
+import android.content.pm.PackageInfo
+import android.os.Process
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.ExpectedException
+
+class OverlayActorEnforcerTests {
+    companion object {
+        private const val NAMESPACE = "testnamespace"
+        private const val ACTOR_NAME = "testactor"
+        private const val ACTOR_PKG_NAME = "com.test.actor.one"
+        private const val OVERLAYABLE_NAME = "TestOverlayable"
+        private const val UID = 3536
+        private const val USER_ID = 55
+    }
+
+    @get:Rule
+    val expectedException = ExpectedException.none()!!
+
+    @Test
+    fun isRoot() {
+        verify(callingUid = Process.ROOT_UID)
+    }
+
+    @Test(expected = SecurityException::class)
+    fun isShell() {
+        verify(callingUid = Process.SHELL_UID)
+    }
+
+    @Test
+    fun isSystem() {
+        verify(callingUid = Process.SYSTEM_UID)
+    }
+
+    @Test(expected = SecurityException::class)
+    fun noOverlayable_noTarget() {
+        verify(targetOverlayableName = null)
+    }
+
+    @Test
+    fun noOverlayable_noTarget_withPermission() {
+        verify(targetOverlayableName = null, hasPermission = true)
+    }
+
+    @Test(expected = SecurityException::class)
+    fun noOverlayable_withTarget() {
+        verify(targetOverlayableName = OVERLAYABLE_NAME)
+    }
+
+    @Test(expected = SecurityException::class)
+    fun withOverlayable_noTarget() {
+        verify(
+                targetOverlayableName = null,
+                overlayableInfo = OverlayableInfo(OVERLAYABLE_NAME, null)
+        )
+    }
+
+    @Test(expected = SecurityException::class)
+    fun withOverlayable_noActor() {
+        verify(
+                overlayableInfo = OverlayableInfo(OVERLAYABLE_NAME, null)
+        )
+    }
+
+    @Test
+    fun withOverlayable_noActor_withPermission() {
+        verify(
+                hasPermission = true,
+                overlayableInfo = OverlayableInfo(OVERLAYABLE_NAME, null)
+        )
+    }
+
+    @Test(expected = SecurityException::class)
+    fun withOverlayable_withActor_notActor() {
+        verify(
+                isActor = false,
+                overlayableInfo = OverlayableInfo(OVERLAYABLE_NAME,
+                        "overlay://$NAMESPACE/$ACTOR_NAME")
+        )
+    }
+
+    @Test(expected = SecurityException::class)
+    fun withOverlayable_withActor_isActor_notPreInstalled() {
+        verify(
+                isActor = true,
+                isPreInstalled = false,
+                overlayableInfo = OverlayableInfo(OVERLAYABLE_NAME,
+                        "overlay://$NAMESPACE/$ACTOR_NAME")
+        )
+    }
+
+    @Test
+    fun withOverlayable_withActor_isActor_isPreInstalled() {
+        verify(
+                isActor = true,
+                isPreInstalled = true,
+                overlayableInfo = OverlayableInfo(OVERLAYABLE_NAME,
+                        "overlay://$NAMESPACE/$ACTOR_NAME")
+        )
+    }
+
+    @Test(expected = SecurityException::class)
+    fun withOverlayable_invalidActor() {
+        verify(
+                isActor = true,
+                isPreInstalled = true,
+                overlayableInfo = OverlayableInfo(OVERLAYABLE_NAME, "notValidActor")
+        )
+    }
+
+    private fun verify(
+        isActor: Boolean = false,
+        isPreInstalled: Boolean = false,
+        hasPermission: Boolean = false,
+        overlayableInfo: OverlayableInfo? = null,
+        callingUid: Int = UID,
+        targetOverlayableName: String? = OVERLAYABLE_NAME
+    ) {
+        val callback = MockCallback(
+                isActor = isActor,
+                isPreInstalled = isPreInstalled,
+                hasPermission = hasPermission,
+                overlayableInfo = overlayableInfo
+        )
+
+        val overlayInfo = overlayInfo(targetOverlayableName)
+        OverlayActorEnforcer(callback)
+                .enforceActor(overlayInfo, "test", callingUid, USER_ID)
+    }
+
+    private fun overlayInfo(targetOverlayableName: String?) = OverlayInfo("com.test.overlay",
+            "com.test.target", targetOverlayableName, null, "/path", OverlayInfo.STATE_UNKNOWN, 0,
+            0, false)
+
+    private class MockCallback(
+        private val isActor: Boolean = false,
+        private val isPreInstalled: Boolean = false,
+        private val hasPermission: Boolean = false,
+        private val overlayableInfo: OverlayableInfo? = null,
+        private vararg val packageNames: String = arrayOf("com.test.actor.one")
+    ) : OverlayActorEnforcer.VerifyCallback {
+
+        override fun getNamedActors() = if (isActor) {
+            mapOf(NAMESPACE to mapOf(ACTOR_NAME to ACTOR_PKG_NAME))
+        } else {
+            emptyMap()
+        }
+
+        override fun getOverlayableForTarget(
+            packageName: String,
+            targetOverlayableName: String?,
+            userId: Int
+        ) = overlayableInfo
+
+        override fun getPackagesForUid(uid: Int) = when (uid) {
+            UID -> packageNames
+            else -> null
+        }
+
+        override fun getPackageInfo(packageName: String, userId: Int) = PackageInfo().apply {
+            applicationInfo = ApplicationInfo().apply {
+                flags = if (isPreInstalled) ApplicationInfo.FLAG_SYSTEM else 0
+            }
+        }
+
+        override fun doesTargetDefineOverlayable(targetPackageName: String?, userId: Int): Boolean {
+            return overlayableInfo != null
+        }
+
+        override fun enforcePermission(permission: String?, message: String?) {
+            if (!hasPermission) {
+                throw SecurityException()
+            }
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java
new file mode 100644
index 0000000..1f312bf
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java
@@ -0,0 +1,197 @@
+/*
+ * 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.recoverysystem;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.IPowerManager;
+import android.os.IRecoverySystemProgressListener;
+import android.os.Looper;
+import android.os.PowerManager;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.FileWriter;
+
+/**
+ * atest FrameworksServicesTests:RecoverySystemServiceTest
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class RecoverySystemServiceTest {
+    private RecoverySystemService mRecoverySystemService;
+    private RecoverySystemServiceTestable.FakeSystemProperties mSystemProperties;
+    private RecoverySystemService.UncryptSocket mUncryptSocket;
+    private Context mContext;
+    private IPowerManager mIPowerManager;
+    private FileWriter mUncryptUpdateFileWriter;
+
+    @Before
+    public void setup() {
+        mContext = mock(Context.class);
+        mSystemProperties = new RecoverySystemServiceTestable.FakeSystemProperties();
+        mUncryptSocket = mock(RecoverySystemService.UncryptSocket.class);
+        mUncryptUpdateFileWriter = mock(FileWriter.class);
+
+        Looper looper = InstrumentationRegistry.getContext().getMainLooper();
+        mIPowerManager = mock(IPowerManager.class);
+        PowerManager powerManager = new PowerManager(mock(Context.class), mIPowerManager,
+                new Handler(looper));
+
+        mRecoverySystemService = new RecoverySystemServiceTestable(mContext, mSystemProperties,
+                powerManager, mUncryptUpdateFileWriter, mUncryptSocket);
+    }
+
+    @Test
+    public void clearBcb_success() throws Exception {
+        doNothing().when(mContext).enforceCallingOrSelfPermission(
+                eq(android.Manifest.permission.RECOVERY), any());
+        when(mUncryptSocket.getPercentageUncrypted()).thenReturn(100);
+
+        assertThat(mRecoverySystemService.clearBcb(), is(true));
+
+        assertThat(mSystemProperties.getCtlStart(), is("clear-bcb"));
+        verify(mUncryptSocket).sendAck();
+        verify(mUncryptSocket).close();
+    }
+
+    @Test
+    public void clearBcb_uncrypt_failure() throws Exception {
+        doNothing().when(mContext).enforceCallingOrSelfPermission(
+                eq(android.Manifest.permission.RECOVERY), any());
+        when(mUncryptSocket.getPercentageUncrypted()).thenReturn(0);
+
+        assertThat(mRecoverySystemService.clearBcb(), is(false));
+
+        assertThat(mSystemProperties.getCtlStart(), is("clear-bcb"));
+        verify(mUncryptSocket).sendAck();
+        verify(mUncryptSocket).close();
+    }
+
+    @Test(expected = SecurityException.class)
+    public void clearBcb_noPerm() {
+        doThrow(SecurityException.class).when(mContext).enforceCallingOrSelfPermission(
+                eq(android.Manifest.permission.RECOVERY), any());
+        mRecoverySystemService.clearBcb();
+    }
+
+    @Test
+    public void setupBcb_success() throws Exception {
+        doNothing().when(mContext).enforceCallingOrSelfPermission(
+                eq(android.Manifest.permission.RECOVERY), any());
+        when(mUncryptSocket.getPercentageUncrypted()).thenReturn(100);
+
+        assertThat(mRecoverySystemService.setupBcb("foo"), is(true));
+
+        assertThat(mSystemProperties.getCtlStart(), is("setup-bcb"));
+        verify(mUncryptSocket).sendCommand("foo");
+        verify(mUncryptSocket).sendAck();
+        verify(mUncryptSocket).close();
+    }
+
+    @Test
+    public void setupBcb_uncrypt_failure() throws Exception {
+        doNothing().when(mContext).enforceCallingOrSelfPermission(
+                eq(android.Manifest.permission.RECOVERY), any());
+        when(mUncryptSocket.getPercentageUncrypted()).thenReturn(0);
+
+        assertThat(mRecoverySystemService.setupBcb("foo"), is(false));
+
+        assertThat(mSystemProperties.getCtlStart(), is("setup-bcb"));
+        verify(mUncryptSocket).sendCommand("foo");
+        verify(mUncryptSocket).sendAck();
+        verify(mUncryptSocket).close();
+    }
+
+    @Test(expected = SecurityException.class)
+    public void setupBcb_noPerm() {
+        doThrow(SecurityException.class).when(mContext).enforceCallingOrSelfPermission(
+                eq(android.Manifest.permission.RECOVERY), any());
+        mRecoverySystemService.setupBcb("foo");
+    }
+
+    @Test
+    public void rebootRecoveryWithCommand_success() throws Exception {
+        doNothing().when(mContext).enforceCallingOrSelfPermission(
+                eq(android.Manifest.permission.RECOVERY), any());
+        when(mUncryptSocket.getPercentageUncrypted()).thenReturn(100);
+
+        mRecoverySystemService.rebootRecoveryWithCommand("foo");
+
+        assertThat(mSystemProperties.getCtlStart(), is("setup-bcb"));
+        verify(mUncryptSocket).sendCommand("foo");
+        verify(mUncryptSocket).sendAck();
+        verify(mUncryptSocket).close();
+        verify(mIPowerManager).reboot(anyBoolean(), eq("recovery"), anyBoolean());
+    }
+
+    @Test
+    public void rebootRecoveryWithCommand_failure() throws Exception {
+        doNothing().when(mContext).enforceCallingOrSelfPermission(
+                eq(android.Manifest.permission.RECOVERY), any());
+        when(mUncryptSocket.getPercentageUncrypted()).thenReturn(0);
+
+        mRecoverySystemService.rebootRecoveryWithCommand("foo");
+
+        assertThat(mSystemProperties.getCtlStart(), is("setup-bcb"));
+        verify(mUncryptSocket).sendCommand("foo");
+        verify(mUncryptSocket).sendAck();
+        verify(mUncryptSocket).close();
+        verifyNoMoreInteractions(mIPowerManager);
+    }
+
+    @Test(expected = SecurityException.class)
+    public void rebootRecoveryWithCommand_noPerm() {
+        doThrow(SecurityException.class).when(mContext).enforceCallingOrSelfPermission(
+                eq(android.Manifest.permission.RECOVERY), any());
+        mRecoverySystemService.rebootRecoveryWithCommand("foo");
+    }
+
+    @Test
+    public void uncrypt_success() throws Exception {
+        doNothing().when(mContext).enforceCallingOrSelfPermission(
+                eq(android.Manifest.permission.RECOVERY), any());
+        when(mUncryptSocket.getPercentageUncrypted()).thenReturn(0, 5, 25, 50, 90, 99, 100);
+
+        IRecoverySystemProgressListener listener = mock(IRecoverySystemProgressListener.class);
+        assertThat(mRecoverySystemService.uncrypt("foo.zip", listener), is(true));
+
+        assertThat(mSystemProperties.getCtlStart(), is("uncrypt"));
+        verify(mUncryptSocket, times(7)).getPercentageUncrypted();
+        verify(mUncryptSocket).sendAck();
+        verify(mUncryptSocket).close();
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java
new file mode 100644
index 0000000..a986b71
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java
@@ -0,0 +1,113 @@
+/*
+ * 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.recoverysystem;
+
+import android.content.Context;
+import android.os.PowerManager;
+
+import java.io.FileWriter;
+
+public class RecoverySystemServiceTestable extends RecoverySystemService {
+    private static class MockInjector extends RecoverySystemService.Injector {
+        private final FakeSystemProperties mSystemProperties;
+        private final PowerManager mPowerManager;
+        private final FileWriter mUncryptPackageFileWriter;
+        private final UncryptSocket mUncryptSocket;
+
+        MockInjector(Context context, FakeSystemProperties systemProperties,
+                PowerManager powerManager, FileWriter uncryptPackageFileWriter,
+                UncryptSocket uncryptSocket) {
+            super(context);
+            mSystemProperties = systemProperties;
+            mPowerManager = powerManager;
+            mUncryptPackageFileWriter = uncryptPackageFileWriter;
+            mUncryptSocket = uncryptSocket;
+        }
+
+        @Override
+        public PowerManager getPowerManager() {
+            return mPowerManager;
+        }
+
+        @Override
+        public String systemPropertiesGet(String key) {
+            return mSystemProperties.get(key);
+        }
+
+        @Override
+        public void systemPropertiesSet(String key, String value) {
+            mSystemProperties.set(key, value);
+        }
+
+        @Override
+        public boolean uncryptPackageFileDelete() {
+            return true;
+        }
+
+        @Override
+        public String getUncryptPackageFileName() {
+            return "mock-file.txt";
+        }
+
+        @Override
+        public FileWriter getUncryptPackageFileWriter() {
+            return mUncryptPackageFileWriter;
+        }
+
+        @Override
+        public UncryptSocket connectService() {
+            return mUncryptSocket;
+        }
+
+        @Override
+        public void threadSleep(long millis) {
+        }
+    }
+
+    RecoverySystemServiceTestable(Context context, FakeSystemProperties systemProperties,
+            PowerManager powerManager, FileWriter uncryptPackageFileWriter,
+            UncryptSocket uncryptSocket) {
+        super(new MockInjector(context, systemProperties, powerManager, uncryptPackageFileWriter,
+                uncryptSocket));
+    }
+
+    public static class FakeSystemProperties {
+        private String mCtlStart = null;
+
+        public String get(String key) {
+            if (RecoverySystemService.INIT_SERVICE_UNCRYPT.equals(key)
+                    || RecoverySystemService.INIT_SERVICE_SETUP_BCB.equals(key)
+                    || RecoverySystemService.INIT_SERVICE_CLEAR_BCB.equals(key)) {
+                return null;
+            } else {
+                throw new IllegalArgumentException("unexpected test key: " + key);
+            }
+        }
+
+        public void set(String key, String value) {
+            if ("ctl.start".equals(key)) {
+                mCtlStart = value;
+            } else {
+                throw new IllegalArgumentException("unexpected test key: " + key);
+            }
+        }
+
+        public String getCtlStart() {
+            return mCtlStart;
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigNamedActorTest.kt b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigNamedActorTest.kt
new file mode 100644
index 0000000..b7199d4
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigNamedActorTest.kt
@@ -0,0 +1,232 @@
+/*
+ * 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.systemconfig
+
+import android.content.Context
+import androidx.test.InstrumentationRegistry
+import com.android.server.SystemConfig
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.ExpectedException
+import org.junit.rules.TemporaryFolder
+
+class SystemConfigNamedActorTest {
+
+    companion object {
+        private const val NAMESPACE_TEST = "someTestNamespace"
+        private const val NAMESPACE_ANDROID = "android"
+        private const val ACTOR_ONE = "iconShaper"
+        private const val ACTOR_TWO = "colorChanger"
+        private const val PACKAGE_ONE = "com.test.actor.one"
+        private const val PACKAGE_TWO = "com.test.actor.two"
+    }
+
+    private val context: Context = InstrumentationRegistry.getContext()
+
+    @get:Rule
+    val tempFolder = TemporaryFolder(context.filesDir)
+
+    @get:Rule
+    val expected = ExpectedException.none()
+
+    private var uniqueCounter = 0
+
+    @Test
+    fun twoUnique() {
+        """
+            <config>
+                <named-actor
+                    namespace="$NAMESPACE_TEST"
+                    name="$ACTOR_ONE"
+                    package="$PACKAGE_ONE"
+                    />
+                <named-actor
+                    namespace="$NAMESPACE_TEST"
+                    name="$ACTOR_TWO"
+                    package="$PACKAGE_TWO"
+                    />
+            </config>
+        """.write()
+
+        assertPermissions().containsExactlyEntriesIn(
+                mapOf(
+                        NAMESPACE_TEST to mapOf(
+                            ACTOR_ONE to PACKAGE_ONE,
+                            ACTOR_TWO to PACKAGE_TWO
+                        )
+                )
+        )
+    }
+
+    @Test
+    fun twoSamePackage() {
+        """
+            <config>
+                <named-actor
+                    namespace="$NAMESPACE_TEST"
+                    name="$ACTOR_ONE"
+                    package="$PACKAGE_ONE"
+                    />
+                <named-actor
+                    namespace="$NAMESPACE_TEST"
+                    name="$ACTOR_TWO"
+                    package="$PACKAGE_ONE"
+                    />
+            </config>
+        """.write()
+
+        assertPermissions().containsExactlyEntriesIn(
+                mapOf(
+                        NAMESPACE_TEST to mapOf(
+                            ACTOR_ONE to PACKAGE_ONE,
+                            ACTOR_TWO to PACKAGE_ONE
+                        )
+                )
+        )
+    }
+
+    @Test
+    fun missingNamespace() {
+        """
+            <config>
+                <named-actor
+                    name="$ACTOR_ONE"
+                    package="$PACKAGE_ONE"
+                    />
+                <named-actor
+                    namespace="$NAMESPACE_TEST"
+                    name="$ACTOR_TWO"
+                    package="$PACKAGE_TWO"
+                    />
+            </config>
+        """.write()
+
+        assertPermissions().containsExactlyEntriesIn(
+                mapOf(
+                        NAMESPACE_TEST to mapOf(
+                                ACTOR_TWO to PACKAGE_TWO
+                        )
+                )
+        )
+    }
+
+    @Test
+    fun missingName() {
+        """
+            <config>
+                <named-actor
+                    namespace="$NAMESPACE_TEST"
+                    package="$PACKAGE_ONE"
+                    />
+                <named-actor
+                    namespace="$NAMESPACE_TEST"
+                    name="$ACTOR_TWO"
+                    package="$PACKAGE_TWO"
+                    />
+            </config>
+        """.write()
+
+        assertPermissions().containsExactlyEntriesIn(
+                mapOf(
+                        NAMESPACE_TEST to mapOf(
+                                ACTOR_TWO to PACKAGE_TWO
+                        )
+                )
+        )
+    }
+
+    @Test
+    fun missingPackage() {
+        """
+            <config>
+                <named-actor
+                    namespace="$NAMESPACE_TEST"
+                    name="$ACTOR_ONE"
+                    />
+                <named-actor
+                    namespace="$NAMESPACE_TEST"
+                    name="$ACTOR_TWO"
+                    package="$PACKAGE_TWO"
+                    />
+            </config>
+        """.write()
+
+        assertPermissions().containsExactlyEntriesIn(
+                mapOf(
+                        NAMESPACE_TEST to mapOf(
+                                ACTOR_TWO to PACKAGE_TWO
+                        )
+                )
+        )
+    }
+
+    @Test
+    fun androidNamespaceThrows() {
+        """
+            <config>
+                <named-actor
+                    namespace="$NAMESPACE_TEST"
+                    name="$ACTOR_ONE"
+                    package="$PACKAGE_ONE"
+                    />
+                <named-actor
+                    namespace="$NAMESPACE_ANDROID"
+                    name="$ACTOR_ONE"
+                    package="$PACKAGE_ONE"
+                    />
+            </config>
+        """.write()
+
+        expected.expect(IllegalStateException::class.java)
+        expected.expectMessage("Defining $ACTOR_ONE as $PACKAGE_ONE " +
+                "for the android namespace is not allowed")
+
+        assertPermissions()
+    }
+
+    @Test
+    fun duplicateActorNameThrows() {
+        """
+            <config>
+                <named-actor
+                    namespace="$NAMESPACE_TEST"
+                    name="$ACTOR_ONE"
+                    package="$PACKAGE_ONE"
+                    />
+                <named-actor
+                    namespace="$NAMESPACE_TEST"
+                    name="$ACTOR_ONE"
+                    package="$PACKAGE_TWO"
+                    />
+            </config>
+        """.write()
+
+        expected.expect(IllegalStateException::class.java)
+        expected.expectMessage("Duplicate actor definition for $NAMESPACE_TEST/$ACTOR_ONE;" +
+                " defined as both $PACKAGE_ONE and $PACKAGE_TWO")
+
+        assertPermissions()
+    }
+
+    private fun String.write() = tempFolder.root.resolve("${uniqueCounter++}.xml")
+            .writeText(this.trimIndent())
+
+    private fun assertPermissions() = SystemConfig(false).apply {
+        readPermissions(tempFolder.root, 0)
+    }. let { assertThat(it.namedActors) }
+}
diff --git a/services/tests/servicestests/src/com/android/server/SystemConfigTest.java b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
similarity index 98%
rename from services/tests/servicestests/src/com/android/server/SystemConfigTest.java
rename to services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
index ff03391..fde0ddf 100644
--- a/services/tests/servicestests/src/com/android/server/SystemConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server;
+package com.android.server.systemconfig;
 
 import static org.junit.Assert.assertEquals;
 
@@ -25,6 +25,8 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.server.SystemConfig;
+
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
diff --git a/telephony/java/android/telephony/TelephonyFrameworkInitializer.java b/telephony/java/android/telephony/TelephonyFrameworkInitializer.java
new file mode 100644
index 0000000..b75d533
--- /dev/null
+++ b/telephony/java/android/telephony/TelephonyFrameworkInitializer.java
@@ -0,0 +1,71 @@
+/*
+ * 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 android.telephony;
+
+import android.annotation.SystemApi;
+import android.app.SystemServiceRegistry;
+import android.content.Context;
+import android.telephony.euicc.EuiccCardManager;
+import android.telephony.euicc.EuiccManager;
+
+
+/**
+ * Class for performing registration for all telephony services.
+ *
+ * @hide
+ */
+@SystemApi
+public class TelephonyFrameworkInitializer {
+
+    private TelephonyFrameworkInitializer() {
+    }
+
+    /**
+     * Called by {@link SystemServiceRegistry}'s static initializer and registers all telephony
+     * services to {@link Context}, so that {@link Context#getSystemService} can return them.
+     *
+     * @throws IllegalStateException if this is called from anywhere besides
+     * {@link SystemServiceRegistry}
+     */
+    public static void registerServiceWrappers() {
+        SystemServiceRegistry.registerContextAwareService(
+                Context.TELEPHONY_SERVICE,
+                TelephonyManager.class,
+                context -> new TelephonyManager(context)
+        );
+        SystemServiceRegistry.registerContextAwareService(
+                Context.TELEPHONY_SUBSCRIPTION_SERVICE,
+                SubscriptionManager.class,
+                context -> new SubscriptionManager(context)
+        );
+        SystemServiceRegistry.registerContextAwareService(
+                Context.CARRIER_CONFIG_SERVICE,
+                CarrierConfigManager.class,
+                context -> new CarrierConfigManager(context)
+        );
+        SystemServiceRegistry.registerContextAwareService(
+                Context.EUICC_SERVICE,
+                EuiccManager.class,
+                context -> new EuiccManager(context)
+        );
+        SystemServiceRegistry.registerContextAwareService(
+                Context.EUICC_CARD_SERVICE,
+                EuiccCardManager.class,
+                context -> new EuiccCardManager(context)
+        );
+    }
+}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 60a2cd0..1357e9c 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -11298,7 +11298,9 @@
     @IntDef(prefix = {"SET_OPPORTUNISTIC_SUB"}, value = {
             SET_OPPORTUNISTIC_SUB_SUCCESS,
             SET_OPPORTUNISTIC_SUB_VALIDATION_FAILED,
-            SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION})
+            SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION,
+            SET_OPPORTUNISTIC_SUB_NO_OPPORTUNISTIC_SUB_AVAILABLE,
+            SET_OPPORTUNISTIC_SUB_REMOTE_SERVICE_EXCEPTION})
     public @interface SetOpportunisticSubscriptionResult {}
 
     /**
@@ -11316,6 +11318,17 @@
      */
     public static final int SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION = 2;
 
+    /**
+     * The subscription is not valid. It must be an opportunistic subscription.
+     */
+    public static final int SET_OPPORTUNISTIC_SUB_NO_OPPORTUNISTIC_SUB_AVAILABLE = 3;
+
+    /**
+     * Subscription service happened remote exception.
+     */
+    public static final int SET_OPPORTUNISTIC_SUB_REMOTE_SERVICE_EXCEPTION = 4;
+
+
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = {"UPDATE_AVAILABLE_NETWORKS"}, value = {
@@ -11323,7 +11336,13 @@
             UPDATE_AVAILABLE_NETWORKS_UNKNOWN_FAILURE,
             UPDATE_AVAILABLE_NETWORKS_ABORTED,
             UPDATE_AVAILABLE_NETWORKS_INVALID_ARGUMENTS,
-            UPDATE_AVAILABLE_NETWORKS_NO_CARRIER_PRIVILEGE})
+            UPDATE_AVAILABLE_NETWORKS_NO_CARRIER_PRIVILEGE,
+            UPDATE_AVAILABLE_NETWORKS_DISABLE_MODEM_FAIL,
+            UPDATE_AVAILABLE_NETWORKS_ENABLE_MODEM_FAIL,
+            UPDATE_AVAILABLE_NETWORKS_MULTIPLE_NETWORKS_NOT_SUPPORTED,
+            UPDATE_AVAILABLE_NETWORKS_NO_OPPORTUNISTIC_SUB_AVAILABLE,
+            UPDATE_AVAILABLE_NETWORKS_REMOTE_SERVICE_EXCEPTION,
+            UPDATE_AVAILABLE_NETWORKS_SERVICE_IS_DISABLED})
     public @interface UpdateAvailableNetworksResult {}
 
     /**
@@ -11352,6 +11371,36 @@
     public static final int UPDATE_AVAILABLE_NETWORKS_NO_CARRIER_PRIVILEGE = 4;
 
     /**
+     * Disable modem fail.
+     */
+    public static final int UPDATE_AVAILABLE_NETWORKS_DISABLE_MODEM_FAIL = 5;
+
+    /**
+     * Enable modem fail.
+     */
+    public static final int UPDATE_AVAILABLE_NETWORKS_ENABLE_MODEM_FAIL = 6;
+
+    /**
+     * Carrier app does not support multiple available networks.
+     */
+    public static final int UPDATE_AVAILABLE_NETWORKS_MULTIPLE_NETWORKS_NOT_SUPPORTED = 7;
+
+    /**
+     * The subscription is not valid. It must be an opportunistic subscription.
+     */
+    public static final int UPDATE_AVAILABLE_NETWORKS_NO_OPPORTUNISTIC_SUB_AVAILABLE = 8;
+
+    /**
+     * There is no OpportunisticNetworkService.
+     */
+    public static final int UPDATE_AVAILABLE_NETWORKS_REMOTE_SERVICE_EXCEPTION = 9;
+
+    /**
+     * OpportunisticNetworkService is disabled.
+     */
+    public static final int UPDATE_AVAILABLE_NETWORKS_SERVICE_IS_DISABLED = 10;
+
+    /**
      * Set preferred opportunistic data subscription id.
      *
      * Switch internet data to preferred opportunistic data subscription id. This api
@@ -11381,7 +11430,7 @@
                     return;
                 }
                 Binder.withCleanCallingIdentity(() -> executor.execute(() -> {
-                    callback.accept(SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION);
+                    callback.accept(SET_OPPORTUNISTIC_SUB_REMOTE_SERVICE_EXCEPTION);
                 }));
                 return;
             }
@@ -11467,9 +11516,8 @@
                     return;
                 }
                 if (iOpportunisticNetworkService == null) {
-                    /* Todo<b/130595455> passing unknown due to lack of good error codes */
                     Binder.withCleanCallingIdentity(() -> executor.execute(() -> {
-                        callback.accept(UPDATE_AVAILABLE_NETWORKS_UNKNOWN_FAILURE);
+                        callback.accept(UPDATE_AVAILABLE_NETWORKS_REMOTE_SERVICE_EXCEPTION);
                     }));
                 } else {
                     Binder.withCleanCallingIdentity(() -> executor.execute(() -> {
diff --git a/telephony/java/com/android/internal/telephony/CarrierAppUtils.java b/telephony/java/com/android/internal/telephony/CarrierAppUtils.java
index 0d4fd0f..e6bebbb 100644
--- a/telephony/java/com/android/internal/telephony/CarrierAppUtils.java
+++ b/telephony/java/com/android/internal/telephony/CarrierAppUtils.java
@@ -25,10 +25,10 @@
 import android.os.RemoteException;
 import android.permission.IPermissionManager;
 import android.provider.Settings;
+import android.telephony.Rlog;
 import android.telephony.TelephonyManager;
 import android.util.ArrayMap;
 import android.util.ArraySet;
-import android.util.Slog;
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
@@ -78,7 +78,7 @@
             IPackageManager packageManager, IPermissionManager permissionManager,
             TelephonyManager telephonyManager, ContentResolver contentResolver, int userId) {
         if (DEBUG) {
-            Slog.d(TAG, "disableCarrierAppsUntilPrivileged");
+            Rlog.d(TAG, "disableCarrierAppsUntilPrivileged");
         }
         SystemConfig config = SystemConfig.getInstance();
         ArraySet<String> systemCarrierAppsDisabledUntilUsed =
@@ -105,7 +105,7 @@
             IPackageManager packageManager, IPermissionManager permissionManager,
             ContentResolver contentResolver, int userId) {
         if (DEBUG) {
-            Slog.d(TAG, "disableCarrierAppsUntilPrivileged");
+            Rlog.d(TAG, "disableCarrierAppsUntilPrivileged");
         }
         SystemConfig config = SystemConfig.getInstance();
         ArraySet<String> systemCarrierAppsDisabledUntilUsed =
@@ -174,7 +174,7 @@
                             || ai.enabledSetting ==
                             PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
                             || (ai.flags & ApplicationInfo.FLAG_INSTALLED) == 0)) {
-                        Slog.i(TAG, "Update state(" + packageName + "): ENABLED for user "
+                        Rlog.i(TAG, "Update state(" + packageName + "): ENABLED for user "
                                 + userId);
                         packageManager.setSystemAppInstallState(
                                 packageName,
@@ -197,7 +197,7 @@
                                     PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
                                     || (associatedApp.flags
                                     & ApplicationInfo.FLAG_INSTALLED) == 0) {
-                                Slog.i(TAG, "Update associated state(" + associatedApp.packageName
+                                Rlog.i(TAG, "Update associated state(" + associatedApp.packageName
                                         + "): ENABLED for user " + userId);
                                 packageManager.setSystemAppInstallState(
                                         associatedApp.packageName,
@@ -222,7 +222,7 @@
                             && ai.enabledSetting ==
                             PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
                             && (ai.flags & ApplicationInfo.FLAG_INSTALLED) != 0) {
-                        Slog.i(TAG, "Update state(" + packageName
+                        Rlog.i(TAG, "Update state(" + packageName
                                 + "): DISABLED_UNTIL_USED for user " + userId);
                         packageManager.setSystemAppInstallState(
                                 packageName,
@@ -240,7 +240,7 @@
                                         == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
                                         && (associatedApp.flags
                                         & ApplicationInfo.FLAG_INSTALLED) != 0) {
-                                    Slog.i(TAG,
+                                    Rlog.i(TAG,
                                             "Update associated state(" + associatedApp.packageName
                                                     + "): DISABLED_UNTIL_USED for user " + userId);
                                     packageManager.setSystemAppInstallState(
@@ -268,7 +268,7 @@
                 permissionManager.grantDefaultPermissionsToEnabledCarrierApps(packageNames, userId);
             }
         } catch (RemoteException e) {
-            Slog.w(TAG, "Could not reach PackageManager", e);
+            Rlog.w(TAG, "Could not reach PackageManager", e);
         }
     }
 
@@ -390,7 +390,7 @@
                 return ai;
             }
         } catch (RemoteException e) {
-            Slog.w(TAG, "Could not reach PackageManager", e);
+            Rlog.w(TAG, "Could not reach PackageManager", e);
         }
         return null;
     }
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
index 5ce42fd..d03419d 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
@@ -30,10 +30,10 @@
 import android.telephony.CbGeoUtils.Geometry;
 import android.telephony.CbGeoUtils.LatLng;
 import android.telephony.CbGeoUtils.Polygon;
+import android.telephony.Rlog;
 import android.telephony.SmsCbLocation;
 import android.telephony.SmsCbMessage;
 import android.util.Pair;
-import android.util.Slog;
 
 import com.android.internal.R;
 import com.android.internal.telephony.GsmAlphabet;
@@ -131,7 +131,7 @@
                 } catch (Exception ex) {
                     // Catch the exception here, the message will be considered as having no WAC
                     // information which means the message will be broadcasted directly.
-                    Slog.e(TAG, "Can't parse warning area coordinates, ex = " + ex.toString());
+                    Rlog.e(TAG, "Can't parse warning area coordinates, ex = " + ex.toString());
                 }
             }
 
@@ -198,7 +198,7 @@
             }
             return new GeoFencingTriggerMessage(type, cbIdentifiers);
         } catch (Exception ex) {
-            Slog.e(TAG, "create geo-fencing trigger failed, ex = " + ex.toString());
+            Rlog.e(TAG, "create geo-fencing trigger failed, ex = " + ex.toString());
             return null;
         }
     }
diff --git a/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java
index 176c7a0..339df93 100644
--- a/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java
+++ b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java
@@ -32,7 +32,7 @@
 
 
 
-    // Code below generated by codegen v1.0.13.
+    // Code below generated by codegen v1.0.14.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
@@ -98,8 +98,8 @@
     };
 
     @DataClass.Generated(
-            time = 1573006405823L,
-            codegenVersion = "1.0.13",
+            time = 1574122837821L,
+            codegenVersion = "1.0.14",
             sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java",
             inputSignatures = "private  int mBaseData\nclass HierrarchicalDataClassBase extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genSetters=true)")
     @Deprecated
diff --git a/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java
index e348c77..69e06b2 100644
--- a/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java
+++ b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java
@@ -46,7 +46,7 @@
 
 
 
-    // Code below generated by codegen v1.0.13.
+    // Code below generated by codegen v1.0.14.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
@@ -120,8 +120,8 @@
     };
 
     @DataClass.Generated(
-            time = 1573006406833L,
-            codegenVersion = "1.0.13",
+            time = 1574122838768L,
+            codegenVersion = "1.0.14",
             sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java",
             inputSignatures = "private @android.annotation.NonNull java.lang.String mChildData\nclass HierrarchicalDataClassChild extends com.android.codegentest.HierrarchicalDataClassBase implements []\n@com.android.internal.util.DataClass(genParcelable=true, genConstructor=false, genSetters=true)")
     @Deprecated
diff --git a/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java b/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java
index 112d3df..ca128be 100644
--- a/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java
+++ b/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java
@@ -54,7 +54,7 @@
 
 
 
-    // Code below generated by codegen v1.0.13.
+    // Code below generated by codegen v1.0.14.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
@@ -291,7 +291,7 @@
 
         /** @see #setStringList */
         @DataClass.Generated.Member
-        public @NonNull Builder addStringList(String value) {
+        public @NonNull Builder addStringList(@NonNull String value) {
             // You can refine this method's name by providing item's singular name, e.g.:
             // @DataClass.PluralOf("item")) mItems = ...
 
@@ -310,7 +310,7 @@
 
         /** @see #setMap */
         @DataClass.Generated.Member
-        public @NonNull Builder addMap(String key, SampleWithCustomBuilder value) {
+        public @NonNull Builder addMap(@NonNull String key, @NonNull SampleWithCustomBuilder value) {
             // You can refine this method's name by providing item's singular name, e.g.:
             // @DataClass.PluralOf("item")) mItems = ...
 
@@ -329,7 +329,7 @@
 
         /** @see #setStringMap */
         @DataClass.Generated.Member
-        public @NonNull Builder addStringMap(String key, String value) {
+        public @NonNull Builder addStringMap(@NonNull String key, @NonNull String value) {
             // You can refine this method's name by providing item's singular name, e.g.:
             // @DataClass.PluralOf("item")) mItems = ...
 
@@ -412,8 +412,8 @@
     }
 
     @DataClass.Generated(
-            time = 1573006404728L,
-            codegenVersion = "1.0.13",
+            time = 1574122836960L,
+            codegenVersion = "1.0.14",
             sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java",
             inputSignatures = " @android.annotation.NonNull java.lang.String[] mStringArray\n @android.annotation.NonNull int[] mIntArray\n @android.annotation.NonNull java.util.List<java.lang.String> mStringList\n @android.annotation.NonNull java.util.Map<java.lang.String,com.android.codegentest.SampleWithCustomBuilder> mMap\n @android.annotation.NonNull java.util.Map<java.lang.String,java.lang.String> mStringMap\n @android.annotation.NonNull android.util.SparseArray<com.android.codegentest.SampleWithCustomBuilder> mSparseArray\n @android.annotation.NonNull android.util.SparseIntArray mSparseIntArray\n @java.lang.SuppressWarnings({\"WeakerAccess\"}) @android.annotation.Nullable java.lang.Boolean mNullableBoolean\nclass ParcelAllTheThingsDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genAidl=false, genToString=true)")
     @Deprecated
diff --git a/tests/Codegen/src/com/android/codegentest/SampleDataClass.java b/tests/Codegen/src/com/android/codegentest/SampleDataClass.java
index 0fdcf59..c850bf8 100644
--- a/tests/Codegen/src/com/android/codegentest/SampleDataClass.java
+++ b/tests/Codegen/src/com/android/codegentest/SampleDataClass.java
@@ -342,7 +342,7 @@
 
 
 
-    // Code below generated by codegen v1.0.13.
+    // Code below generated by codegen v1.0.14.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
@@ -1636,7 +1636,7 @@
 
         /** @see #setLinkAddresses2 */
         @DataClass.Generated.Member
-        public @NonNull Builder addLinkAddresses2(LinkAddress value) {
+        public @NonNull Builder addLinkAddresses2(@NonNull LinkAddress value) {
             // You can refine this method's name by providing item's singular name, e.g.:
             // @DataClass.PluralOf("item")) mItems = ...
 
@@ -1661,7 +1661,7 @@
 
         /** @see #setLinkAddresses */
         @DataClass.Generated.Member
-        public @NonNull Builder addLinkAddress(LinkAddress value) {
+        public @NonNull Builder addLinkAddress(@NonNull LinkAddress value) {
             if (mLinkAddresses == null) setLinkAddresses(new ArrayList<>());
             mLinkAddresses.add(value);
             return this;
@@ -1872,8 +1872,8 @@
     }
 
     @DataClass.Generated(
-            time = 1573006402566L,
-            codegenVersion = "1.0.13",
+            time = 1574122835009L,
+            codegenVersion = "1.0.14",
             sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleDataClass.java",
             inputSignatures = "public static final  java.lang.String STATE_NAME_UNDEFINED\npublic static final  java.lang.String STATE_NAME_ON\npublic static final  java.lang.String STATE_NAME_OFF\npublic static final  int STATE_UNDEFINED\npublic static final  int STATE_ON\npublic static final  int STATE_OFF\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_MANUAL_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_COMPATIBILITY_MODE_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_AUGMENTED_REQUEST\nprivate  int mNum\nprivate  int mNum2\nprivate  int mNum4\nprivate @android.annotation.Nullable java.lang.String mName\nprivate @android.annotation.NonNull java.lang.String mName2\nprivate @android.annotation.NonNull java.lang.String mName4\nprivate @android.annotation.Nullable android.view.accessibility.AccessibilityNodeInfo mOtherParcelable\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.codegentest.MyDateParcelling.class) @android.annotation.NonNull java.util.Date mDate\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForPattern.class) @android.annotation.NonNull java.util.regex.Pattern mPattern\nprivate @android.annotation.NonNull java.util.List<android.net.LinkAddress> mLinkAddresses2\nprivate @com.android.internal.util.DataClass.PluralOf(\"linkAddress\") @android.annotation.NonNull java.util.ArrayList<android.net.LinkAddress> mLinkAddresses\nprivate @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses4\nprivate @com.android.codegentest.SampleDataClass.StateName @android.annotation.NonNull java.lang.String mStateName\nprivate @com.android.codegentest.SampleDataClass.RequestFlags int mFlags\nprivate @com.android.codegentest.SampleDataClass.State int mState\npublic @android.annotation.NonNull java.lang.CharSequence charSeq\nprivate final @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses5\nprivate transient  android.net.LinkAddress[] mLinkAddresses6\ntransient  int[] mTmpStorage\nprivate @android.annotation.StringRes int mStringRes\nprivate @android.annotation.IntRange(from=0L, to=6L) int mDayOfWeek\nprivate @android.annotation.Size(2L) @android.annotation.NonNull @com.android.internal.util.DataClass.Each @android.annotation.FloatRange(from=0.0) float[] mCoords\nprivate static  java.lang.String defaultName4()\nprivate  int[] lazyInitTmpStorage()\npublic  android.net.LinkAddress[] getLinkAddresses4()\nprivate  boolean patternEquals(java.util.regex.Pattern)\nprivate  int patternHashCode()\nprivate  void onConstructed()\npublic  void dump(java.io.PrintWriter)\nclass SampleDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genConstructor=true, genEqualsHashCode=true, genToString=true, genForEachField=true, genSetters=true)")
     @Deprecated
diff --git a/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java b/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java
index cab477d..2de848c 100644
--- a/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java
+++ b/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java
@@ -85,7 +85,7 @@
 
 
 
-    // Code below generated by codegen v1.0.13.
+    // Code below generated by codegen v1.0.14.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
@@ -253,8 +253,8 @@
     }
 
     @DataClass.Generated(
-            time = 1573006403628L,
-            codegenVersion = "1.0.13",
+            time = 1574122835982L,
+            codegenVersion = "1.0.14",
             sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java",
             inputSignatures = "  long delayAmount\n @android.annotation.NonNull java.util.concurrent.TimeUnit delayUnit\n  long creationTimestamp\nprivate static  java.util.concurrent.TimeUnit unparcelDelayUnit(android.os.Parcel)\nprivate  void parcelDelayUnit(android.os.Parcel,int)\nclass SampleWithCustomBuilder extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genAidl=false, genToString=true)\nabstract  com.android.codegentest.SampleWithCustomBuilder.Builder setDelayAmount(long)\npublic abstract  com.android.codegentest.SampleWithCustomBuilder.Builder setDelayUnit(java.util.concurrent.TimeUnit)\npublic  com.android.codegentest.SampleWithCustomBuilder.Builder setDelay(long,java.util.concurrent.TimeUnit)\nclass BaseBuilder extends java.lang.Object implements []")
     @Deprecated
diff --git a/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java b/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java
index 6190085..0deffe4 100644
--- a/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java
+++ b/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java
@@ -36,7 +36,7 @@
 
 
 
-        // Code below generated by codegen v1.0.13.
+        // Code below generated by codegen v1.0.14.
         //
         // DO NOT MODIFY!
         // CHECKSTYLE:OFF Generated code
@@ -135,8 +135,8 @@
         };
 
         @DataClass.Generated(
-                time = 1573006408903L,
-                codegenVersion = "1.0.13",
+                time = 1574122840588L,
+                codegenVersion = "1.0.14",
                 sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java",
                 inputSignatures = " @android.annotation.NonNull java.lang.String mBar\nclass NestedDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true)")
         @Deprecated
@@ -160,7 +160,7 @@
 
 
 
-            // Code below generated by codegen v1.0.13.
+            // Code below generated by codegen v1.0.14.
             //
             // DO NOT MODIFY!
             // CHECKSTYLE:OFF Generated code
@@ -259,8 +259,8 @@
             };
 
             @DataClass.Generated(
-                    time = 1573006408912L,
-                    codegenVersion = "1.0.13",
+                    time = 1574122840597L,
+                    codegenVersion = "1.0.14",
                     sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java",
                     inputSignatures = " @android.annotation.NonNull long mBaz2\nclass NestedDataClass3 extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true)")
             @Deprecated
@@ -274,7 +274,7 @@
 
 
 
-        // Code below generated by codegen v1.0.13.
+        // Code below generated by codegen v1.0.14.
         //
         // DO NOT MODIFY!
         // CHECKSTYLE:OFF Generated code
@@ -373,8 +373,8 @@
         };
 
         @DataClass.Generated(
-                time = 1573006408917L,
-                codegenVersion = "1.0.13",
+                time = 1574122840608L,
+                codegenVersion = "1.0.14",
                 sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithNestedDataClasses.java",
                 inputSignatures = " @android.annotation.NonNull java.lang.String mBaz\nclass NestedDataClass2 extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true)")
         @Deprecated
diff --git a/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java b/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java
index 5a960d7..712722b 100644
--- a/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java
+++ b/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java
@@ -51,7 +51,7 @@
 
 
 
-    // Code below generated by codegen v1.0.13.
+    // Code below generated by codegen v1.0.14.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
@@ -65,8 +65,8 @@
 
 
     @DataClass.Generated(
-            time = 1573006407900L,
-            codegenVersion = "1.0.13",
+            time = 1574122839646L,
+            codegenVersion = "1.0.14",
             sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/StaleDataclassDetectorFalsePositivesTest.java",
             inputSignatures = "public @android.annotation.NonNull java.lang.String someMethod(int)\nclass StaleDataclassDetectorFalsePositivesTest extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=false)")
     @Deprecated
diff --git a/tools/codegen/src/com/android/codegen/ClassPrinter.kt b/tools/codegen/src/com/android/codegen/ClassPrinter.kt
index a4fd374..c7c80ba 100644
--- a/tools/codegen/src/com/android/codegen/ClassPrinter.kt
+++ b/tools/codegen/src/com/android/codegen/ClassPrinter.kt
@@ -164,7 +164,13 @@
         getSuppressedMembers(classAst)
     }
     val builderSuppressedMembers by lazy {
-        getSuppressedMembers(customBaseBuilderAst)
+        getSuppressedMembers(customBaseBuilderAst) + suppressedMembers.mapNotNull {
+            if (it.startsWith("$CANONICAL_BUILDER_CLASS.")) {
+                it.removePrefix("$CANONICAL_BUILDER_CLASS.")
+            } else {
+                null
+            }
+        }
     }
 
     private fun getSuppressedMembers(clazz: ClassOrInterfaceDeclaration?): List<String> {
diff --git a/tools/codegen/src/com/android/codegen/Generators.kt b/tools/codegen/src/com/android/codegen/Generators.kt
index dc1f4c5..8fe243f 100644
--- a/tools/codegen/src/com/android/codegen/Generators.kt
+++ b/tools/codegen/src/com/android/codegen/Generators.kt
@@ -270,7 +270,7 @@
 private fun ClassPrinter.generateBuilderMethod(
         defVisibility: String,
         name: String,
-        ParamAnnotations: String? = null,
+        paramAnnotations: String? = null,
         paramTypes: List<String>,
         paramNames: List<String> = listOf("value"),
         genJavadoc: ClassPrinter.() -> Unit,
@@ -292,8 +292,12 @@
         +GENERATED_MEMBER_HEADER
         if (providedMethod?.isAbstract == true) +"@Override"
         if (!Annotations.isNullOrEmpty()) +Annotations
-        "$visibility @$NonNull $ReturnType $name(${if_(!ParamAnnotations.isNullOrEmpty(), "$ParamAnnotations ")}${
-                paramTypes.zip(paramNames).joinToString(", ") { (Type, paramName) -> "$Type $paramName" }
+        val ParamAnnotations = if (!paramAnnotations.isNullOrEmpty()) "$paramAnnotations " else ""
+
+        "$visibility @$NonNull $ReturnType $name(${
+            paramTypes.zip(paramNames).joinToString(", ") { (Type, paramName) ->
+                "$ParamAnnotations$Type $paramName"
+            }
         })" {
             genBody()
         }
@@ -311,7 +315,7 @@
         generateBuilderMethod(
                 name = setterName,
                 defVisibility = visibility,
-                ParamAnnotations = annotationsNoInternal.joinToString(" "),
+                paramAnnotations = annotationsNoInternal.joinToString(" "),
                 paramTypes = listOf(SetterParamType),
                 genJavadoc = { generateFieldJavadoc() }) {
             +"checkNotUsed();"
@@ -333,6 +337,7 @@
             generateBuilderMethod(
                     name = adderName,
                     defVisibility = visibility,
+                    paramAnnotations = "@$NonNull",
                     paramTypes = listOf(FieldInnerType),
                     genJavadoc = { +javadocSeeSetter }) {
 
@@ -347,6 +352,7 @@
             generateBuilderMethod(
                     name = adderName,
                     defVisibility = visibility,
+                    paramAnnotations = "@$NonNull",
                     paramTypes = fieldTypeGenegicArgs,
                     paramNames = listOf("key", "value"),
                     genJavadoc = { +javadocSeeSetter }) {
diff --git a/tools/codegen/src/com/android/codegen/SharedConstants.kt b/tools/codegen/src/com/android/codegen/SharedConstants.kt
index 85c832f..74c86f4 100644
--- a/tools/codegen/src/com/android/codegen/SharedConstants.kt
+++ b/tools/codegen/src/com/android/codegen/SharedConstants.kt
@@ -1,7 +1,7 @@
 package com.android.codegen
 
 const val CODEGEN_NAME = "codegen"
-const val CODEGEN_VERSION = "1.0.13"
+const val CODEGEN_VERSION = "1.0.14"
 
 const val CANONICAL_BUILDER_CLASS = "Builder"
 const val BASE_BUILDER_CLASS = "BaseBuilder"
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
index f62fef0..18e2da3 100644
--- a/tools/stats_log_api_gen/main.cpp
+++ b/tools/stats_log_api_gen/main.cpp
@@ -1309,7 +1309,7 @@
         fprintf(out, "            write_non_chained(code");
         for (int argIndex = 1; argIndex <= argIndexMax; argIndex++) {
             if (argIndex == attributionArg) {
-                fprintf(out, ", ws.get(i), ws.getName(i)");
+                fprintf(out, ", ws.getUid(i), ws.getPackageName(i)");
             } else {
                fprintf(out, ", arg%d", argIndex);
             }
@@ -1318,7 +1318,7 @@
         fprintf(out, "        }\n"); // close for-loop
 
         // write() component.
-        fprintf(out, "        ArrayList<WorkSource.WorkChain> workChains = ws.getWorkChains();\n");
+        fprintf(out, "        List<WorkSource.WorkChain> workChains = ws.getWorkChains();\n");
         fprintf(out, "        if (workChains != null) {\n");
         fprintf(out, "            for (WorkSource.WorkChain wc : workChains) {\n");
         fprintf(out, "                write(code");
@@ -1407,7 +1407,7 @@
     fprintf(out, "\n");
     fprintf(out, "import android.os.WorkSource;\n");
     fprintf(out, "import android.util.SparseArray;\n");
-    fprintf(out, "import java.util.ArrayList;\n");
+    fprintf(out, "import java.util.List;\n");
     fprintf(out, "\n");
     fprintf(out, "\n");
     fprintf(out, "/**\n");
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 56f152e..6c2a08c 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -4327,7 +4327,7 @@
                 if (ws == null) {
                     mWorkSource = null;
                 } else {
-                    ws.clearNames();
+                    ws = ws.withoutNames();
                     if (mWorkSource == null) {
                         changed = mWorkSource != null;
                         mWorkSource = new WorkSource(ws);