Merge "Import translations. DO NOT MERGE"
diff --git a/Android.bp b/Android.bp
index 7cc2f30..21054dd 100644
--- a/Android.bp
+++ b/Android.bp
@@ -319,6 +319,7 @@
         "core/java/android/service/vr/IVrManager.aidl",
         "core/java/android/service/vr/IVrStateCallbacks.aidl",
         "core/java/android/service/watchdog/IExplicitHealthCheckService.aidl",
+        "core/java/android/service/watchdog/PackageInfo.aidl",
         "core/java/android/print/ILayoutResultCallback.aidl",
         "core/java/android/print/IPrinterDiscoveryObserver.aidl",
         "core/java/android/print/IPrintDocumentAdapter.aidl",
@@ -1049,6 +1050,35 @@
     },
 }
 
+// This library is meant for vendor code that needs to output protobuf. It links
+// against the static version of libprotobuf-cpp-lite, for which we can not guarantee
+// binary compatibility.
+cc_library {
+    name: "libplatformprotos-static",
+    defaults: ["libplatformprotos-defaults"],
+    host_supported: false,
+
+    // This is okay because this library is only built as a static library.  The C++
+    // API is not guaranteed. The proto API is guaranteed to be stable via Metrics Council,
+    // but is not authorized to be used outside of debugging.
+    vendor_available: true,
+
+    target: {
+        android: {
+            proto: {
+                type: "lite",
+            },
+            static_libs: [
+                "libprotobuf-cpp-lite",
+            ],
+            shared: {
+                enabled: false,
+            },
+        },
+    },
+}
+
+
 // This is the full proto version of libplatformprotos. It may only
 // be used by test code that is not shipped on the device.
 cc_library {
diff --git a/api/current.txt b/api/current.txt
index 0eb6447..c88ed28 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -22659,7 +22659,7 @@
     method public double getDriftNanosPerSecond();
     method @FloatRange(from=0.0f) public double getDriftUncertaintyNanosPerSecond();
     method public long getElapsedRealtimeNanos();
-    method @IntRange(from=0) public long getElapsedRealtimeUncertaintyNanos();
+    method @FloatRange(from=0.0f) public double getElapsedRealtimeUncertaintyNanos();
     method public long getFullBiasNanos();
     method public int getHardwareClockDiscontinuityCount();
     method public int getLeapSecond();
@@ -22863,7 +22863,7 @@
     method public float getBearing();
     method public float getBearingAccuracyDegrees();
     method public long getElapsedRealtimeNanos();
-    method public long getElapsedRealtimeUncertaintyNanos();
+    method public double getElapsedRealtimeUncertaintyNanos();
     method public android.os.Bundle getExtras();
     method public double getLatitude();
     method public double getLongitude();
@@ -22892,7 +22892,7 @@
     method public void setBearing(float);
     method public void setBearingAccuracyDegrees(float);
     method public void setElapsedRealtimeNanos(long);
-    method public void setElapsedRealtimeUncertaintyNanos(long);
+    method public void setElapsedRealtimeUncertaintyNanos(double);
     method public void setExtras(android.os.Bundle);
     method public void setLatitude(double);
     method public void setLongitude(double);
diff --git a/api/system-current.txt b/api/system-current.txt
index 63d1e73..8ac52f7 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -6890,12 +6890,21 @@
     method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent);
     method public abstract void onCancelHealthCheck(@NonNull String);
     method @NonNull public abstract java.util.List<java.lang.String> onGetRequestedPackages();
-    method @NonNull public abstract java.util.List<java.lang.String> onGetSupportedPackages();
+    method @NonNull public abstract java.util.List<android.service.watchdog.PackageInfo> onGetSupportedPackages();
     method public abstract void onRequestHealthCheck(@NonNull String);
     field public static final String BIND_PERMISSION = "android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE";
     field public static final String SERVICE_INTERFACE = "android.service.watchdog.ExplicitHealthCheckService";
   }
 
+  public final class PackageInfo implements android.os.Parcelable {
+    ctor public PackageInfo(@NonNull String, long);
+    method public int describeContents();
+    method public long getHealthCheckTimeoutMillis();
+    method @NonNull public String getPackageName();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.service.watchdog.PackageInfo> CREATOR;
+  }
+
 }
 
 package android.telecom {
diff --git a/api/test-current.txt b/api/test-current.txt
index c541b04..242cac3 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -954,7 +954,7 @@
     method public void setDriftNanosPerSecond(double);
     method public void setDriftUncertaintyNanosPerSecond(@FloatRange(from=0.0f) double);
     method public void setElapsedRealtimeNanos(long);
-    method public void setElapsedRealtimeUncertaintyNanos(@IntRange(from=0) long);
+    method public void setElapsedRealtimeUncertaintyNanos(@FloatRange(from=0.0f) double);
     method public void setFullBiasNanos(long);
     method public void setHardwareClockDiscontinuityCount(int);
     method public void setLeapSecond(int);
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 25e3573..e16ce24 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -937,7 +937,9 @@
         //
         // It is NOT ok to call this function from the system_server (for any of the packages it
         // loads code from) so we explicitly disallow it there.
-        if (needToSetupJitProfiles && !ActivityThread.isSystem()) {
+        //
+        // It is not ok to call this in a zygote context where mActivityThread is null.
+        if (needToSetupJitProfiles && !ActivityThread.isSystem() && mActivityThread != null) {
             setupJitProfileSupport();
         }
 
diff --git a/core/java/android/os/CoolingDevice.aidl b/core/java/android/os/CoolingDevice.aidl
new file mode 100644
index 0000000..478e4bd
--- /dev/null
+++ b/core/java/android/os/CoolingDevice.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.os;
+
+parcelable CoolingDevice;
diff --git a/core/java/android/os/CoolingDevice.java b/core/java/android/os/CoolingDevice.java
new file mode 100644
index 0000000..0e86a38
--- /dev/null
+++ b/core/java/android/os/CoolingDevice.java
@@ -0,0 +1,166 @@
+/*
+ * 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.os;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.hardware.thermal.V2_0.CoolingType;
+
+import com.android.internal.util.Preconditions;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Cooling device values used by IThermalService.
+ *
+ * @hide
+ */
+public final class CoolingDevice implements Parcelable {
+    /**
+     * Current throttle state of the cooling device. The value can any unsigned integer
+     * numbers between 0 and max_state defined in its driver, usually representing the
+     * associated device's power state. 0 means device is not in throttling, higher value
+     * means deeper throttling.
+     */
+    private final long mValue;
+    /** A cooling device type from ThermalHAL */
+    private final int mType;
+    /** Name of this cooling device */
+    private final String mName;
+
+    @IntDef(prefix = { "TYPE_" }, value = {
+            TYPE_FAN,
+            TYPE_BATTERY,
+            TYPE_CPU,
+            TYPE_GPU,
+            TYPE_MODEM,
+            TYPE_NPU,
+            TYPE_COMPONENT,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Type {}
+
+    /** Keep in sync with hardware/interfaces/thermal/2.0/types.hal */
+    /** Fan for active cooling */
+    public static final int TYPE_FAN = CoolingType.FAN;
+    /** Battery charging cooling deivice */
+    public static final int TYPE_BATTERY = CoolingType.BATTERY;
+    /** CPU cooling deivice */
+    public static final int TYPE_CPU = CoolingType.CPU;
+    /** GPU cooling deivice */
+    public static final int TYPE_GPU = CoolingType.GPU;
+    /** Modem cooling deivice */
+    public static final int TYPE_MODEM = CoolingType.MODEM;
+    /** NPU/TPU cooling deivice */
+    public static final int TYPE_NPU = CoolingType.NPU;
+    /** Generic passive cooling deivice */
+    public static final int TYPE_COMPONENT = CoolingType.COMPONENT;
+
+    /**
+     * Verify a valid cooling device type.
+     *
+     * @return true if a cooling device type is valid otherwise false.
+     */
+    public static boolean isValidType(@Type int type) {
+        return type >= TYPE_FAN && type <= TYPE_COMPONENT;
+    }
+
+    public CoolingDevice(long value, @Type int type, @NonNull String name) {
+        Preconditions.checkArgument(isValidType(type), "Invalid Type");
+        mValue = value;
+        mType = type;
+        mName = Preconditions.checkStringNotEmpty(name);
+    }
+
+    /**
+     * Return the cooling device value.
+     *
+     * @return a cooling device value in int.
+     */
+    public long getValue() {
+        return mValue;
+    }
+
+    /**
+     * Return the cooling device type.
+     *
+     * @return a cooling device type: TYPE_*
+     */
+    public @Type int getType() {
+        return mType;
+    }
+
+    /**
+     * Return the cooling device name.
+     *
+     * @return a cooling device name as String.
+     */
+    public String getName() {
+        return mName;
+    }
+
+    @Override
+    public String toString() {
+        return "CoolingDevice{mValue=" + mValue + ", mType=" + mType + ", mName=" + mName + "}";
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = mName.hashCode();
+        hash = 31 * hash + Long.hashCode(mValue);
+        hash = 31 * hash + mType;
+        return hash;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof CoolingDevice)) {
+            return false;
+        }
+        CoolingDevice other = (CoolingDevice) o;
+        return other.mValue == mValue && other.mType == mType && other.mName.equals(mName);
+    }
+
+    @Override
+    public void writeToParcel(Parcel p, int flags) {
+        p.writeLong(mValue);
+        p.writeInt(mType);
+        p.writeString(mName);
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<CoolingDevice> CREATOR =
+            new Parcelable.Creator<CoolingDevice>() {
+                @Override
+                public CoolingDevice createFromParcel(Parcel p) {
+                    long value = p.readLong();
+                    int type = p.readInt();
+                    String name = p.readString();
+                    return new CoolingDevice(value, type, name);
+                }
+
+                @Override
+                public CoolingDevice[] newArray(int size) {
+                    return new CoolingDevice[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/core/java/android/os/IThermalService.aidl b/core/java/android/os/IThermalService.aidl
index 9280cb9..8c98960 100644
--- a/core/java/android/os/IThermalService.aidl
+++ b/core/java/android/os/IThermalService.aidl
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.os.CoolingDevice;
 import android.os.IThermalEventListener;
 import android.os.IThermalStatusListener;
 import android.os.Temperature;
@@ -52,7 +53,7 @@
 
     /**
       * Get current temperature with its throttling status.
-      * @return list of android.os.Temperature
+      * @return list of {@link android.os.Temperature}.
       * {@hide}
       */
     List<Temperature> getCurrentTemperatures();
@@ -87,4 +88,19 @@
       * {@hide}
       */
     int getCurrentThermalStatus();
+
+    /**
+      * Get current cooling devices.
+      * @return list of {@link android.os.CoolingDevice}.
+      * {@hide}
+      */
+    List<CoolingDevice> getCurrentCoolingDevices();
+
+    /**
+      * Get current cooling devices on given type.
+      * @param type the cooling device type to query.
+      * @return list of {@link android.os.CoolingDevice}.
+      * {@hide}
+      */
+    List<CoolingDevice> getCurrentCoolingDevicesWithType(in int type);
 }
diff --git a/core/java/android/os/Temperature.java b/core/java/android/os/Temperature.java
index be7e824..7caffcd 100644
--- a/core/java/android/os/Temperature.java
+++ b/core/java/android/os/Temperature.java
@@ -17,9 +17,12 @@
 package android.os;
 
 import android.annotation.IntDef;
+import android.annotation.NonNull;
 import android.hardware.thermal.V2_0.TemperatureType;
 import android.hardware.thermal.V2_0.ThrottlingSeverity;
 
+import com.android.internal.util.Preconditions;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
@@ -30,13 +33,13 @@
  */
 public final class Temperature implements Parcelable {
     /** Temperature value */
-    private float mValue;
-    /** A temperature type from ThermalHAL */
-    private int mType;
-    /** Name of this temperature */
-    private String mName;
+    private final float mValue;
+    /** A Temperature type from ThermalHAL */
+    private final int mType;
+    /** Name of this Temperature */
+    private final String mName;
     /** The level of the sensor is currently in throttling */
-    private int mStatus;
+    private final int mStatus;
 
     @IntDef(prefix = { "THROTTLING_" }, value = {
             THROTTLING_NONE,
@@ -75,7 +78,7 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface Type {}
 
-    /* Keep in sync with hardware/interfaces/thermal/2.0/types.hal */
+    /** Keep in sync with hardware/interfaces/thermal/2.0/types.hal */
     public static final int TYPE_UNKNOWN = TemperatureType.UNKNOWN;
     public static final int TYPE_CPU = TemperatureType.CPU;
     public static final int TYPE_GPU = TemperatureType.GPU;
@@ -89,9 +92,9 @@
     public static final int TYPE_NPU = TemperatureType.NPU;
 
     /**
-     * Verify a valid temperature type.
+     * Verify a valid Temperature type.
      *
-     * @return true if a temperature type is valid otherwise false.
+     * @return true if a Temperature type is valid otherwise false.
      */
     public static boolean isValidType(@Type int type) {
         return type >= TYPE_UNKNOWN && type <= TYPE_NPU;
@@ -106,67 +109,75 @@
         return status >= THROTTLING_NONE && status <= THROTTLING_SHUTDOWN;
     }
 
-    public Temperature() {
-        this(Float.NaN, TYPE_UNKNOWN, "", THROTTLING_NONE);
-    }
-
-    public Temperature(float value, @Type int type, String name, @ThrottlingStatus int status) {
+    public Temperature(float value, @Type int type,
+            @NonNull String name, @ThrottlingStatus int status) {
+        Preconditions.checkArgument(isValidType(type), "Invalid Type");
+        Preconditions.checkArgument(isValidStatus(status) , "Invalid Status");
         mValue = value;
-        mType = isValidType(type) ? type : TYPE_UNKNOWN;
-        mName = name;
-        mStatus = isValidStatus(status) ? status : THROTTLING_NONE;
+        mType = type;
+        mName = Preconditions.checkStringNotEmpty(name);
+        mStatus = status;
     }
 
     /**
-     * Return the temperature value.
+     * Return the Temperature value.
      *
-     * @return a temperature value in floating point could be NaN.
+     * @return a Temperature value in floating point could be NaN.
      */
     public float getValue() {
         return mValue;
     }
 
     /**
-     * Return the temperature type.
+     * Return the Temperature type.
      *
-     * @return a temperature type: TYPE_*
+     * @return a Temperature type: TYPE_*
      */
     public @Type int getType() {
         return mType;
     }
 
     /**
-     * Return the temperature name.
+     * Return the Temperature name.
      *
-     * @return a temperature name as String.
+     * @return a Temperature name as String.
      */
     public String getName() {
         return mName;
     }
 
     /**
-     * Return the temperature throttling status.
+     * Return the Temperature throttling status.
      *
-     * @return a temperature throttling status: THROTTLING_*
+     * @return a Temperature throttling status: THROTTLING_*
      */
     public @ThrottlingStatus int getStatus() {
         return mStatus;
     }
 
-    private Temperature(Parcel p) {
-        readFromParcel(p);
+    @Override
+    public String toString() {
+        return "Temperature{mValue=" + mValue + ", mType=" + mType
+                + ", mName=" + mName + ", mStatus=" + mStatus + "}";
     }
 
-    /**
-     * Fill in Temperature members from a Parcel.
-     *
-     * @param p the parceled Temperature object.
-     */
-    public void readFromParcel(Parcel p) {
-        mValue = p.readFloat();
-        mType = p.readInt();
-        mName = p.readString();
-        mStatus = p.readInt();
+    @Override
+    public int hashCode() {
+        int hash = mName.hashCode();
+        hash = 31 * hash + Float.hashCode(mValue);
+        hash = 31 * hash + mType;
+        hash = 31 * hash + mStatus;
+        return hash;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof Temperature)) {
+            return false;
+        }
+        Temperature other = (Temperature) o;
+        return other.mValue == mValue && other.mType == mType
+                && other.mName.equals(mName) && other.mStatus == mStatus;
     }
 
     @Override
@@ -181,13 +192,18 @@
             new Parcelable.Creator<Temperature>() {
                 @Override
                 public Temperature createFromParcel(Parcel p) {
-                    return new Temperature(p);
+                    float value = p.readFloat();
+                    int type = p.readInt();
+                    String name = p.readString();
+                    int status = p.readInt();
+                    return new Temperature(value, type, name, status);
                 }
 
                 @Override
                 public Temperature[] newArray(int size) {
                     return new Temperature[size];
                 }
+
             };
 
     @Override
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 5631282..9ec7723 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -260,6 +260,13 @@
     public static final String NAMESPACE_TEXTCLASSIFIER = "textclassifier";
 
     /**
+     * Namespace for contacts provider related features.
+     *
+     * @hide
+     */
+    public static final String NAMESPACE_CONTACTS_PROVIDER = "contacts_provider";
+
+    /**
      * List of namespaces which can be read without READ_DEVICE_CONFIG permission
      *
      * @hide
diff --git a/core/java/android/service/watchdog/ExplicitHealthCheckService.java b/core/java/android/service/watchdog/ExplicitHealthCheckService.java
index 015fba1..682b872 100644
--- a/core/java/android/service/watchdog/ExplicitHealthCheckService.java
+++ b/core/java/android/service/watchdog/ExplicitHealthCheckService.java
@@ -61,7 +61,7 @@
     private static final String TAG = "ExplicitHealthCheckService";
 
     /**
-     * {@link Bundle} key for a {@link List} of {@link String} value.
+     * {@link Bundle} key for a {@link List} of {@link PackageInfo} value.
      *
      * {@hide}
      */
@@ -130,7 +130,7 @@
      *
      * @return all packages supporting explicit health checks
      */
-    @NonNull public abstract List<String> onGetSupportedPackages();
+    @NonNull public abstract List<PackageInfo> onGetSupportedPackages();
 
     /**
      * Called when the system requests for all the packages that it has currently requested
@@ -187,22 +187,26 @@
 
         @Override
         public void getSupportedPackages(RemoteCallback callback) throws RemoteException {
-            mHandler.post(() -> sendPackages(callback, EXTRA_SUPPORTED_PACKAGES,
-                    ExplicitHealthCheckService.this.onGetSupportedPackages()));
+            mHandler.post(() -> {
+                List<PackageInfo> packages =
+                        ExplicitHealthCheckService.this.onGetSupportedPackages();
+                Objects.requireNonNull(packages, "Supported package list must be non-null");
+                Bundle bundle = new Bundle();
+                bundle.putParcelableArrayList(EXTRA_SUPPORTED_PACKAGES, new ArrayList<>(packages));
+                callback.sendResult(bundle);
+            });
         }
 
         @Override
         public void getRequestedPackages(RemoteCallback callback) throws RemoteException {
-            mHandler.post(() -> sendPackages(callback, EXTRA_REQUESTED_PACKAGES,
-                    ExplicitHealthCheckService.this.onGetRequestedPackages()));
-        }
-
-        private void sendPackages(RemoteCallback callback, String key, List<String> packages) {
-            Objects.requireNonNull(packages,
-                    "Supported and requested package list must be non-null");
-            Bundle bundle = new Bundle();
-            bundle.putStringArrayList(key, new ArrayList<>(packages));
-            callback.sendResult(bundle);
+            mHandler.post(() -> {
+                List<String> packages =
+                        ExplicitHealthCheckService.this.onGetRequestedPackages();
+                Objects.requireNonNull(packages, "Requested  package list must be non-null");
+                Bundle bundle = new Bundle();
+                bundle.putStringArrayList(EXTRA_REQUESTED_PACKAGES, new ArrayList<>(packages));
+                callback.sendResult(bundle);
+            });
         }
     }
 }
diff --git a/core/java/android/service/watchdog/PackageInfo.aidl b/core/java/android/service/watchdog/PackageInfo.aidl
new file mode 100644
index 0000000..5605aec
--- /dev/null
+++ b/core/java/android/service/watchdog/PackageInfo.aidl
@@ -0,0 +1,22 @@
+/*
+ * 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.service.watchdog;
+
+/**
+ * @hide
+ */
+parcelable PackageInfo;
diff --git a/core/java/android/service/watchdog/PackageInfo.java b/core/java/android/service/watchdog/PackageInfo.java
new file mode 100644
index 0000000..cee9b6d
--- /dev/null
+++ b/core/java/android/service/watchdog/PackageInfo.java
@@ -0,0 +1,130 @@
+/*
+ * 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.service.watchdog;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A PackageInfo contains a package supporting explicit health checks and the
+ * timeout in {@link System#uptimeMillis} across reboots after which health
+ * check requests from clients are failed.
+ *
+ * @hide
+ */
+@SystemApi
+public final class PackageInfo implements Parcelable {
+    // TODO: Receive from DeviceConfig flag
+    private static final long DEFAULT_HEALTH_CHECK_TIMEOUT_MILLIS = TimeUnit.HOURS.toMillis(1);
+
+    private final String mPackageName;
+    private final long mHealthCheckTimeoutMillis;
+
+    /**
+     * Creates a new instance.
+     *
+     * @param packageName the package name
+     * @param durationMillis the duration in milliseconds, must be greater than or
+     * equal to 0. If it is 0, it will use a system default value.
+     */
+    public PackageInfo(@NonNull String packageName, long healthCheckTimeoutMillis) {
+        mPackageName = Preconditions.checkNotNull(packageName);
+        if (healthCheckTimeoutMillis == 0) {
+            mHealthCheckTimeoutMillis = DEFAULT_HEALTH_CHECK_TIMEOUT_MILLIS;
+        } else {
+            mHealthCheckTimeoutMillis = Preconditions.checkArgumentNonnegative(
+                    healthCheckTimeoutMillis);
+        }
+    }
+
+    private PackageInfo(Parcel parcel) {
+        mPackageName = parcel.readString();
+        mHealthCheckTimeoutMillis = parcel.readLong();
+    }
+
+    /**
+     * Gets the package name.
+     *
+     * @return the package name
+     */
+    public @NonNull String getPackageName() {
+        return mPackageName;
+    }
+
+    /**
+     * Gets the timeout in milliseconds to evaluate an explicit health check result after a request.
+     *
+     * @return the duration in {@link System#uptimeMillis} across reboots
+     */
+    public long getHealthCheckTimeoutMillis() {
+        return mHealthCheckTimeoutMillis;
+    }
+
+    @Override
+    public String toString() {
+        return "PackageInfo{" + mPackageName + ", " + mHealthCheckTimeoutMillis + "}";
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (other == this) {
+            return true;
+        }
+        if (!(other instanceof PackageInfo)) {
+            return false;
+        }
+
+        PackageInfo otherInfo = (PackageInfo) other;
+        return Objects.equals(otherInfo.getHealthCheckTimeoutMillis(), mHealthCheckTimeoutMillis)
+                && Objects.equals(otherInfo.getPackageName(), mPackageName);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mPackageName, mHealthCheckTimeoutMillis);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeString(mPackageName);
+        parcel.writeLong(mHealthCheckTimeoutMillis);
+    }
+
+    public static final @NonNull Creator<PackageInfo> CREATOR = new Creator<PackageInfo>() {
+            @Override
+            public PackageInfo createFromParcel(Parcel source) {
+                return new PackageInfo(source);
+            }
+
+            @Override
+            public PackageInfo[] newArray(int size) {
+                return new PackageInfo[size];
+            }
+        };
+}
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 336c2e5..04046fe 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -53,7 +53,6 @@
         DEFAULT_FLAGS.put("settings_network_and_internet_v2", "true");
         DEFAULT_FLAGS.put("settings_slice_injection", "true");
         DEFAULT_FLAGS.put("settings_systemui_theme", "true");
-        DEFAULT_FLAGS.put("settings_mainline_module", "true");
         DEFAULT_FLAGS.put(DYNAMIC_SYSTEM, "false");
         DEFAULT_FLAGS.put(SEAMLESS_TRANSFER, "false");
         DEFAULT_FLAGS.put(HEARING_AID_SETTINGS, "false");
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index afa6a6a..94be25f 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -788,7 +788,7 @@
         } else {
             ImageView fileIconView = parent.findViewById(R.id.content_preview_file_icon);
             fileIconView.setVisibility(View.VISIBLE);
-            fileIconView.setImageResource(R.drawable.ic_doc_generic);
+            fileIconView.setImageResource(R.drawable.chooser_file_generic);
         }
     }
 
@@ -837,12 +837,14 @@
             }
 
             for (Uri uri : uris) {
-                if (findPreferredContentPreview(uri, resolver) == CONTENT_PREVIEW_IMAGE) {
-                    return CONTENT_PREVIEW_IMAGE;
+                // Defaulting to file preview when there are mixed image/file types is
+                // preferable, as it shows the user the correct number of items being shared
+                if (findPreferredContentPreview(uri, resolver) == CONTENT_PREVIEW_FILE) {
+                    return CONTENT_PREVIEW_FILE;
                 }
             }
 
-            return CONTENT_PREVIEW_FILE;
+            return CONTENT_PREVIEW_IMAGE;
         }
 
         return CONTENT_PREVIEW_TEXT;
diff --git a/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java b/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java
index b47ef12..ff94264 100644
--- a/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java
+++ b/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java
@@ -78,8 +78,8 @@
         dest.writeInt(mFullscreenStackSysUiVisibility);
         dest.writeInt(mDockedStackSysUiVisibility);
         dest.writeStrongBinder(mImeToken);
-        dest.writeParcelable(mFullscreenStackBounds, flags);
-        dest.writeParcelable(mDockedStackBounds, flags);
+        dest.writeTypedObject(mFullscreenStackBounds, flags);
+        dest.writeTypedObject(mDockedStackBounds, flags);
     }
 
     /**
@@ -101,8 +101,8 @@
                     final int fullscreenStackSysUiVisibility = source.readInt();
                     final int dockedStackSysUiVisibility = source.readInt();
                     final IBinder imeToken = source.readStrongBinder();
-                    final Rect fullscreenStackBounds = Rect.CREATOR.createFromParcel(source);
-                    final Rect dockedStackBounds = Rect.CREATOR.createFromParcel(source);
+                    final Rect fullscreenStackBounds = source.readTypedObject(Rect.CREATOR);
+                    final Rect dockedStackBounds = source.readTypedObject(Rect.CREATOR);
                     return new RegisterStatusBarResult(icons, disabledFlags1, systemUiVisibility,
                             menuVisible, imeWindowVis, imeBackDisposition, showImeSwitcher,
                             disabledFlags2, fullscreenStackSysUiVisibility,
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index c7a60cf..c7d8432 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -618,6 +618,7 @@
 
     <!-- Added in Q -->
     <protected-broadcast android:name="android.content.pm.action.SESSION_UPDATED" />
+    <protected-broadcast android:name="android.settings.action.GRAYSCALE_CHANGED" />
 
     <!-- For CarIdlenessTracker -->
     <protected-broadcast android:name="com.android.server.jobscheduler.GARAGE_MODE_ON" />
diff --git a/core/res/res/drawable/chooser_file_generic.xml b/core/res/res/drawable/chooser_file_generic.xml
new file mode 100644
index 0000000..006dfba
--- /dev/null
+++ b/core/res/res/drawable/chooser_file_generic.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2015 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF737373"
+        android:pathData="M6 2c-1.1 0,-1.99.9,-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2,-.9 2,-2V8l-6,-6H6zm7 7V3.5L18.5 9H13z"/>
+</vector>
diff --git a/core/res/res/layout/chooser_grid_preview_text.xml b/core/res/res/layout/chooser_grid_preview_text.xml
index 7cfbb1b..6abf57a 100644
--- a/core/res/res/layout/chooser_grid_preview_text.xml
+++ b/core/res/res/layout/chooser_grid_preview_text.xml
@@ -51,7 +51,9 @@
         android:layout_height="24dp"
         android:gravity="center"
         android:layout_gravity="center_vertical"
-        android:background="@drawable/ic_content_copy_gm2"/>
+        android:foreground="@drawable/ic_content_copy_gm2"
+        android:clickable="true"
+        android:background="?attr/selectableItemBackgroundBorderless"/>
   </LinearLayout>
 
   <!-- Required sub-layout so we can get the nice rounded corners-->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 21f5acb..e8cc96c 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3558,6 +3558,12 @@
     -->
     <string name="config_defaultSystemCaptionsService" translatable="false"></string>
 
+    <!-- The component name for the system-wide captions manager service.
+         This service must be trusted, as the system binds to it and keeps it running.
+         Example: "com.android.captions/.SystemCaptionsManagerService"
+    -->
+    <string name="config_defaultSystemCaptionsManagerService" translatable="false"></string>
+
     <!-- The package name for the incident report approver app.
         This app is usually PermissionController or an app that replaces it.  When
         a bugreport or incident report with EXPLICT-level sharing flags is going to be
diff --git a/core/res/res/values/styles_device_defaults.xml b/core/res/res/values/styles_device_defaults.xml
index 3c7b36d..d253f00 100644
--- a/core/res/res/values/styles_device_defaults.xml
+++ b/core/res/res/values/styles_device_defaults.xml
@@ -98,7 +98,11 @@
     <style name="Widget.DeviceDefault.ActionBar.TabView" parent="Widget.Material.ActionBar.TabView"/>
     <style name="Widget.DeviceDefault.ActionBar.TabText" parent="Widget.Material.ActionBar.TabText"/>
     <style name="Widget.DeviceDefault.ActionBar.TabBar" parent="Widget.Material.ActionBar.TabBar"/>
-    <style name="Widget.DeviceDefault.ActionBar.Solid" parent="Widget.Material.ActionBar.Solid"/>
+    <style name="Widget.DeviceDefault.ActionBar.Solid" parent="Widget.Material.ActionBar.Solid">
+        <item name="background">?attr/colorPrimaryDark</item>
+        <item name="backgroundStacked">?attr/colorPrimaryDark</item>
+        <item name="backgroundSplit">?attr/colorPrimaryDark</item>
+    </style>
     <style name="Widget.DeviceDefault.Button.Borderless.Small" parent="Widget.Material.Button.Borderless.Small"/>
     <style name="Widget.DeviceDefault.AbsListView" parent="Widget.Material.AbsListView"/>
     <style name="Widget.DeviceDefault.Spinner.DropDown.ActionBar" parent="Widget.Material.Spinner.DropDown.ActionBar"/>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index fb7be77..664059a 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3409,6 +3409,7 @@
   <java-symbol type="string" name="config_defaultContentSuggestionsService" />
   <java-symbol type="string" name="config_defaultAttentionService" />
   <java-symbol type="string" name="config_defaultSystemCaptionsService" />
+  <java-symbol type="string" name="config_defaultSystemCaptionsManagerService" />
 
   <java-symbol type="string" name="notification_channel_foreground_service" />
   <java-symbol type="string" name="foreground_service_app_in_background" />
@@ -3477,6 +3478,7 @@
   <java-symbol type="layout" name="shutdown_dialog" />
   <java-symbol type="dimen" name="chooser_service_spacing" />
   <java-symbol type="bool" name="config_showSysuiShutdown" />
+  <java-symbol type="drawable" name="chooser_file_generic" />
 
   <java-symbol type="layout" name="notification_template_messaging_text_message" />
   <java-symbol type="layout" name="notification_template_messaging_image_message" />
diff --git a/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java b/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java
new file mode 100644
index 0000000..3cb1e18
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.internal.statusbar;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.graphics.Rect;
+import android.os.Binder;
+import android.os.Parcel;
+import android.os.UserHandle;
+import android.util.ArrayMap;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class RegisterStatusBarResultTest {
+
+    /**
+     * Test {@link RegisterStatusBarResult} can be stored then restored with {@link Parcel}.
+     */
+    @Test
+    public void testParcelable() {
+        final String dumyIconKey = "dummyIcon1";
+        final ArrayMap<String, StatusBarIcon> iconMap = new ArrayMap<>();
+        iconMap.put(dumyIconKey, new StatusBarIcon("com.android.internal.statusbar.test",
+                UserHandle.of(100), 123, 1, 2, "dummyIconDescription"));
+
+        final RegisterStatusBarResult original = new RegisterStatusBarResult(iconMap,
+                0x2 /* disabledFlags1 */,
+                0x4 /* systemUiVisibility */,
+                true /* menuVisible */,
+                0x8 /* imeWindowVis */,
+                0x10 /* imeBackDisposition */,
+                false /* showImeSwitcher */,
+                0x20 /* disabledFlags2 */,
+                0x40 /* fullscreenStackSysUiVisibility */,
+                0x80 /* dockedStackSysUiVisibility */,
+                new Binder() /* imeToken */,
+                new Rect(0x100, 0x200, 0x400, 0x800) /* fullscreenStackBounds */,
+                new Rect(0x1000, 0x2000, 0x4000, 0x8000) /* dockedStackBounds */);
+
+        final RegisterStatusBarResult copy = clone(original);
+
+        assertThat(copy.mIcons).hasSize(original.mIcons.size());
+        // We already test that StatusBarIcon is Parcelable.  Only check StatusBarIcon.user here.
+        assertThat(copy.mIcons.get(dumyIconKey).user)
+                .isEqualTo(original.mIcons.get(dumyIconKey).user);
+
+        assertThat(copy.mDisabledFlags1).isEqualTo(original.mDisabledFlags1);
+        assertThat(copy.mSystemUiVisibility).isEqualTo(original.mSystemUiVisibility);
+        assertThat(copy.mMenuVisible).isEqualTo(original.mMenuVisible);
+        assertThat(copy.mImeWindowVis).isEqualTo(original.mImeWindowVis);
+        assertThat(copy.mImeBackDisposition).isEqualTo(original.mImeBackDisposition);
+        assertThat(copy.mShowImeSwitcher).isEqualTo(original.mShowImeSwitcher);
+        assertThat(copy.mDisabledFlags2).isEqualTo(original.mDisabledFlags2);
+        assertThat(copy.mFullscreenStackSysUiVisibility)
+                .isEqualTo(original.mFullscreenStackSysUiVisibility);
+        assertThat(copy.mDockedStackSysUiVisibility)
+                .isEqualTo(original.mDockedStackSysUiVisibility);
+        assertThat(copy.mImeToken).isSameAs(original.mImeToken);
+        assertThat(copy.mFullscreenStackBounds).isEqualTo(original.mFullscreenStackBounds);
+        assertThat(copy.mDockedStackBounds).isEqualTo(original.mDockedStackBounds);
+    }
+
+    private RegisterStatusBarResult clone(RegisterStatusBarResult original) {
+        Parcel parcel = null;
+        try {
+            parcel = Parcel.obtain();
+            original.writeToParcel(parcel, 0);
+            parcel.setDataPosition(0);
+            return RegisterStatusBarResult.CREATOR.createFromParcel(parcel);
+        } finally {
+            if (parcel != null) {
+                parcel.recycle();
+            }
+        }
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/statusbar/StatusBarIconTest.java b/core/tests/coretests/src/com/android/internal/statusbar/StatusBarIconTest.java
new file mode 100644
index 0000000..fe552a0
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/statusbar/StatusBarIconTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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.internal.statusbar;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Parcel;
+import android.os.UserHandle;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class StatusBarIconTest {
+
+    /**
+     * Test {@link StatusBarIcon} can be stored then restored with {@link Parcel}.
+     */
+    @Test
+    public void testParcelable() {
+        final UserHandle dummyUserHandle = UserHandle.of(100);
+        final String dummyIconPackageName = "com.android.internal.statusbar.test";
+        final int dummyIconId = 123;
+        final int dummyIconLevel = 1;
+        final int dummyIconNumber = 2;
+        final CharSequence dummyIconContentDescription = "dummyIcon";
+        final StatusBarIcon original = new StatusBarIcon(dummyIconPackageName, dummyUserHandle,
+                dummyIconId, dummyIconLevel, dummyIconNumber, dummyIconContentDescription);
+
+        final StatusBarIcon copy = clone(original);
+
+        assertThat(copy.user).isEqualTo(original.user);
+        assertThat(copy.pkg).isEqualTo(original.pkg);
+        assertThat(copy.icon.sameAs(original.icon)).isTrue();
+        assertThat(copy.iconLevel).isEqualTo(original.iconLevel);
+        assertThat(copy.visible).isEqualTo(original.visible);
+        assertThat(copy.number).isEqualTo(original.number);
+        assertThat(copy.contentDescription).isEqualTo(original.contentDescription);
+    }
+
+    private StatusBarIcon clone(StatusBarIcon original) {
+        Parcel parcel = null;
+        try {
+            parcel = Parcel.obtain();
+            original.writeToParcel(parcel, 0);
+            parcel.setDataPosition(0);
+            return StatusBarIcon.CREATOR.createFromParcel(parcel);
+        } finally {
+            if (parcel != null) {
+                parcel.recycle();
+            }
+        }
+    }
+}
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp
index 9519704..1b515ad 100644
--- a/libs/androidfw/AssetManager2.cpp
+++ b/libs/androidfw/AssetManager2.cpp
@@ -1319,7 +1319,7 @@
     typedef std::map<int, int> SourceToDestinationRuntimePackageMap;
     std::map<ApkAssetsCookie, SourceToDestinationRuntimePackageMap> src_asset_cookie_id_map;
 
-    // Determine which ApkAssets are loaded in both theme AssetManagers
+    // Determine which ApkAssets are loaded in both theme AssetManagers.
     std::vector<const ApkAssets*> src_assets = o.asset_manager_->GetApkAssets();
     for (size_t i = 0; i < src_assets.size(); i++) {
       const ApkAssets* src_asset = src_assets[i];
@@ -1328,7 +1328,7 @@
       for (size_t j = 0; j < dest_assets.size(); j++) {
         const ApkAssets* dest_asset = dest_assets[j];
 
-        // Map the runtime package of the source apk asset to the destination apk asset
+        // Map the runtime package of the source apk asset to the destination apk asset.
         if (src_asset->GetPath() == dest_asset->GetPath()) {
           const std::vector<std::unique_ptr<const LoadedPackage>>& src_packages =
               src_asset->GetLoadedArsc()->GetPackages();
@@ -1353,15 +1353,14 @@
             package_map[src_package_id] = dest_package_id;
           }
 
-          src_to_dest_asset_cookies.insert(std::pair<ApkAssetsCookie, ApkAssetsCookie>(i, j));
-          src_asset_cookie_id_map.insert(
-              std::pair<ApkAssetsCookie, SourceToDestinationRuntimePackageMap>(i, package_map));
+          src_to_dest_asset_cookies.insert(std::make_pair(i, j));
+          src_asset_cookie_id_map.insert(std::make_pair(i, package_map));
           break;
         }
       }
     }
 
-    // Reset the data in the destination theme
+    // Reset the data in the destination theme.
     for (size_t p = 0; p < packages_.size(); p++) {
       if (packages_[p] != nullptr) {
         packages_[p].reset();
@@ -1387,16 +1386,17 @@
             continue;
           }
 
-          // If the attribute value represents an attribute or reference, the package id of the
-          // value needs to be rewritten to the package id of the value in the destination
-          uint32_t attribue_data = entry.value.data;
-          if ((entry.value.dataType == Res_value::TYPE_ATTRIBUTE
-              || entry.value.dataType == Res_value::TYPE_REFERENCE
-              || entry.value.dataType == Res_value::TYPE_DYNAMIC_ATTRIBUTE
-              || entry.value.dataType == Res_value::TYPE_DYNAMIC_REFERENCE)
-              && attribue_data != 0x0) {
+          bool is_reference = (entry.value.dataType == Res_value::TYPE_ATTRIBUTE
+                               || entry.value.dataType == Res_value::TYPE_REFERENCE
+                               || entry.value.dataType == Res_value::TYPE_DYNAMIC_ATTRIBUTE
+                               || entry.value.dataType == Res_value::TYPE_DYNAMIC_REFERENCE)
+                              && entry.value.data != 0x0;
 
-            // Determine the package id of the reference in the destination AssetManager
+          // If the attribute value represents an attribute or reference, the package id of the
+          // value needs to be rewritten to the package id of the value in the destination.
+          uint32_t attribute_data = entry.value.data;
+          if (is_reference) {
+            // Determine the package id of the reference in the destination AssetManager.
             auto value_package_map = src_asset_cookie_id_map.find(entry.cookie);
             if (value_package_map == src_asset_cookie_id_map.end()) {
               continue;
@@ -1408,14 +1408,28 @@
               continue;
             }
 
-            attribue_data = fix_package_id(entry.value.data, value_dest_package->second);
+            attribute_data = fix_package_id(entry.value.data, value_dest_package->second);
+          }
+
+          // Find the cookie of the value in the destination. If the source apk is not loaded in the
+          // destination, only copy resources that do not reference resources in the source.
+          ApkAssetsCookie data_dest_cookie;
+          auto value_dest_cookie = src_to_dest_asset_cookies.find(entry.cookie);
+          if (value_dest_cookie != src_to_dest_asset_cookies.end()) {
+            data_dest_cookie = value_dest_cookie->second;
+          } else {
+            if (is_reference || entry.value.dataType == Res_value::TYPE_STRING) {
+              continue;
+            } else {
+              data_dest_cookie = 0x0;
+            }
           }
 
           // The package id of the attribute needs to be rewritten to the package id of the
-          // attribute in the destination
+          // attribute in the destination.
           int attribute_dest_package_id = p;
           if (attribute_dest_package_id != 0x01) {
-            // Find the cookie of the attribute resource id
+            // Find the cookie of the attribute resource id in the source AssetManager
             FindEntryResult attribute_entry_result;
             ApkAssetsCookie attribute_cookie =
                 o.asset_manager_->FindEntry(make_resid(p, t, e), 0 /* density_override */ ,
@@ -1423,7 +1437,7 @@
                                             true /* ignore_configuration */,
                                             &attribute_entry_result);
 
-            // Determine the package id of the attribute in the destination AssetManager
+            // Determine the package id of the attribute in the destination AssetManager.
             auto attribute_package_map = src_asset_cookie_id_map.find(attribute_cookie);
             if (attribute_package_map == src_asset_cookie_id_map.end()) {
               continue;
@@ -1436,13 +1450,13 @@
             attribute_dest_package_id = attribute_dest_package->second;
           }
 
-          // Lazily instantiate the destination package
+          // Lazily instantiate the destination package.
           std::unique_ptr<Package>& dest_package = packages_[attribute_dest_package_id];
           if (dest_package == nullptr) {
             dest_package.reset(new Package());
           }
 
-          // Lazily instantiate and resize the destination type
+          // Lazily instantiate and resize the destination type.
           util::unique_cptr<ThemeType>& dest_type = dest_package->types[t];
           if (dest_type == nullptr || dest_type->entry_count < type->entry_count) {
             const size_t type_alloc_size = sizeof(ThemeType)
@@ -1450,7 +1464,7 @@
             void* dest_data = malloc(type_alloc_size);
             memset(dest_data, 0, type->entry_count * sizeof(ThemeEntry));
 
-            // Copy the existing destination type values if the type is resized
+            // Copy the existing destination type values if the type is resized.
             if (dest_type != nullptr) {
               memcpy(dest_data, type, sizeof(ThemeType)
                                       + (dest_type->entry_count * sizeof(ThemeEntry)));
@@ -1460,15 +1474,9 @@
             dest_type->entry_count = type->entry_count;
           }
 
-          // Find the cookie of the value in the destination
-          auto value_dest_cookie = src_to_dest_asset_cookies.find(entry.cookie);
-          if (value_dest_cookie == src_to_dest_asset_cookies.end()) {
-            continue;
-          }
-
-          dest_type->entries[e].cookie = value_dest_cookie->second;
+          dest_type->entries[e].cookie = data_dest_cookie;
           dest_type->entries[e].value.dataType = entry.value.dataType;
-          dest_type->entries[e].value.data = attribue_data;
+          dest_type->entries[e].value.data = attribute_data;
           dest_type->entries[e].type_spec_flags = entry.type_spec_flags;
         }
       }
diff --git a/libs/androidfw/tests/Theme_test.cpp b/libs/androidfw/tests/Theme_test.cpp
index 2c39cee..be5ecd9 100644
--- a/libs/androidfw/tests/Theme_test.cpp
+++ b/libs/androidfw/tests/Theme_test.cpp
@@ -282,48 +282,81 @@
 }
 
 TEST_F(ThemeTest, OnlyCopySameAssetsThemeWhenAssetManagersDiffer) {
-  AssetManager2 assetmanager_one;
-  assetmanager_one.SetApkAssets({system_assets_.get(), lib_one_assets_.get(), style_assets_.get(),
+  AssetManager2 assetmanager_dst;
+  assetmanager_dst.SetApkAssets({system_assets_.get(), lib_one_assets_.get(), style_assets_.get(),
                                  libclient_assets_.get()});
 
-  AssetManager2 assetmanager_two;
-  assetmanager_two.SetApkAssets({system_assets_.get(), lib_two_assets_.get(), lib_one_assets_.get(),
+  AssetManager2 assetmanager_src;
+  assetmanager_src.SetApkAssets({system_assets_.get(), lib_two_assets_.get(), lib_one_assets_.get(),
                                  style_assets_.get()});
 
-  auto theme_one = assetmanager_one.NewTheme();
-  ASSERT_TRUE(theme_one->ApplyStyle(app::R::style::StyleOne));
+  auto theme_dst = assetmanager_dst.NewTheme();
+  ASSERT_TRUE(theme_dst->ApplyStyle(app::R::style::StyleOne));
 
-  auto theme_two = assetmanager_two.NewTheme();
-  ASSERT_TRUE(theme_two->ApplyStyle(R::style::Theme_One));
-  ASSERT_TRUE(theme_two->ApplyStyle(app::R::style::StyleTwo));
-  ASSERT_TRUE(theme_two->ApplyStyle(fix_package_id(lib_one::R::style::Theme, 0x03),
+  auto theme_src = assetmanager_src.NewTheme();
+  ASSERT_TRUE(theme_src->ApplyStyle(R::style::Theme_One));
+  ASSERT_TRUE(theme_src->ApplyStyle(app::R::style::StyleTwo));
+  ASSERT_TRUE(theme_src->ApplyStyle(fix_package_id(lib_one::R::style::Theme, 0x03),
                                     false /*force*/));
-  ASSERT_TRUE(theme_two->ApplyStyle(fix_package_id(lib_two::R::style::Theme, 0x02),
+  ASSERT_TRUE(theme_src->ApplyStyle(fix_package_id(lib_two::R::style::Theme, 0x02),
                                     false /*force*/));
 
-  theme_one->SetTo(*theme_two);
+  theme_dst->SetTo(*theme_src);
 
   Res_value value;
   uint32_t flags;
 
-  // System resources (present in destination asset manager)
-  EXPECT_EQ(0, theme_one->GetAttribute(R::attr::foreground, &value, &flags));
+  // System resources (present in destination asset manager).
+  EXPECT_EQ(0, theme_dst->GetAttribute(R::attr::foreground, &value, &flags));
 
   // The cookie of the style asset is 3 in the source and 2 in the destination.
-  // Check that the cookie has been rewritten to the destination values
-  EXPECT_EQ(2, theme_one->GetAttribute(app::R::attr::attr_one, &value, &flags));
+  // Check that the cookie has been rewritten to the destination values.
+  EXPECT_EQ(2, theme_dst->GetAttribute(app::R::attr::attr_one, &value, &flags));
 
   // The cookie of the lib_one asset is 2 in the source and 1 in the destination.
   // The package id of the lib_one package is 0x03 in the source and 0x02 in the destination
-  // Check that the cookie and packages have been rewritten to the destination values
-  EXPECT_EQ(1, theme_one->GetAttribute(fix_package_id(lib_one::R::attr::attr1, 0x02), &value,
+  // Check that the cookie and packages have been rewritten to the destination values.
+  EXPECT_EQ(1, theme_dst->GetAttribute(fix_package_id(lib_one::R::attr::attr1, 0x02), &value,
                                        &flags));
-  EXPECT_EQ(1, theme_one->GetAttribute(fix_package_id(lib_one::R::attr::attr2, 0x02), &value,
+  EXPECT_EQ(1, theme_dst->GetAttribute(fix_package_id(lib_one::R::attr::attr2, 0x02), &value,
                                        &flags));
 
   // attr2 references an attribute in lib_one. Check that the resolution of the attribute value is
-  // correct after the value of attr2 had its package id rewritten to the destination package id
+  // correct after the value of attr2 had its package id rewritten to the destination package id.
   EXPECT_EQ(700, value.data);
 }
 
+TEST_F(ThemeTest, CopyNonReferencesWhenPackagesDiffer) {
+  AssetManager2 assetmanager_dst;
+  assetmanager_dst.SetApkAssets({system_assets_.get()});
+
+  AssetManager2 assetmanager_src;
+  assetmanager_src.SetApkAssets({system_assets_.get(), style_assets_.get()});
+
+  auto theme_dst = assetmanager_dst.NewTheme();
+  auto theme_src = assetmanager_src.NewTheme();
+  ASSERT_TRUE(theme_src->ApplyStyle(app::R::style::StyleSeven));
+  theme_dst->SetTo(*theme_src);
+
+  Res_value value;
+  uint32_t flags;
+
+  // Allow inline resource values to be copied even if the source apk asset is not present in the
+  // destination.
+  EXPECT_EQ(0, theme_dst->GetAttribute(0x0101021b /* android:versionCode */, &value, &flags));
+
+  // Do not copy strings since the data is an index into the values string pool of the source apk
+  // asset.
+  EXPECT_EQ(-1, theme_dst->GetAttribute(0x01010001 /* android:label */, &value, &flags));
+
+  // Do not copy values that reference another resource if the resource is not present in the
+  // destination.
+  EXPECT_EQ(-1, theme_dst->GetAttribute(0x01010002 /* android:icon */, &value, &flags));
+  EXPECT_EQ(-1, theme_dst->GetAttribute(0x010100d1 /* android:tag */, &value, &flags));
+
+  // Allow @empty to and @null to be copied.
+  EXPECT_EQ(0, theme_dst->GetAttribute(0x010100d0 /* android:id */, &value, &flags));
+  EXPECT_EQ(0, theme_dst->GetAttribute(0x01010000 /* android:theme */, &value, &flags));
+}
+
 }  // namespace android
diff --git a/libs/androidfw/tests/data/styles/R.h b/libs/androidfw/tests/data/styles/R.h
index 538a847..f11486f 100644
--- a/libs/androidfw/tests/data/styles/R.h
+++ b/libs/androidfw/tests/data/styles/R.h
@@ -51,6 +51,7 @@
       StyleFour = 0x7f020003u,
       StyleFive = 0x7f020004u,
       StyleSix = 0x7f020005u,
+      StyleSeven = 0x7f020006u,
     };
   };
 };
diff --git a/libs/androidfw/tests/data/styles/build b/libs/androidfw/tests/data/styles/build
index 1ef8e6e..7b7c1f7 100755
--- a/libs/androidfw/tests/data/styles/build
+++ b/libs/androidfw/tests/data/styles/build
@@ -2,5 +2,7 @@
 
 set -e
 
+PATH_TO_FRAMEWORK_RES=${ANDROID_BUILD_TOP}/prebuilts/sdk/current/public/android.jar
+
 aapt2 compile -o compiled.flata --dir res
-aapt2 link -o styles.apk --manifest AndroidManifest.xml compiled.flata
+aapt2 link -o styles.apk --manifest AndroidManifest.xml -I $PATH_TO_FRAMEWORK_RES compiled.flata
diff --git a/libs/androidfw/tests/data/styles/res/values/styles.xml b/libs/androidfw/tests/data/styles/res/values/styles.xml
index 1a23176..06774a8 100644
--- a/libs/androidfw/tests/data/styles/res/values/styles.xml
+++ b/libs/androidfw/tests/data/styles/res/values/styles.xml
@@ -79,4 +79,14 @@
         <item name="attr_three">3</item>
     </style>
 
+    <public type="style" name="StyleSeven" id="0x7f020006" />
+    <style name="StyleSeven" >
+        <item name="android:versionCode">3</item>
+        <item name="android:label">"string"</item>
+        <item name="android:icon">?attr/attr_one</item>
+        <item name="android:tag">@string/string_one</item>
+        <item name="android:id">@null</item>
+        <item name="android:theme">@empty</item>
+    </style>
+
 </resources>
diff --git a/libs/androidfw/tests/data/styles/styles.apk b/libs/androidfw/tests/data/styles/styles.apk
index cd5c7a1..92e9bf9 100644
--- a/libs/androidfw/tests/data/styles/styles.apk
+++ b/libs/androidfw/tests/data/styles/styles.apk
Binary files differ
diff --git a/libs/protoutil/src/ProtoFileReader.cpp b/libs/protoutil/src/ProtoFileReader.cpp
index 074170a..4017979 100644
--- a/libs/protoutil/src/ProtoFileReader.cpp
+++ b/libs/protoutil/src/ProtoFileReader.cpp
@@ -55,6 +55,7 @@
          mSize(get_file_size(fd)),
          mPos(0),
          mOffset(0),
+         mMaxOffset(0),
          mChunkSize(sizeof(mBuffer)) {
 }
 
diff --git a/location/java/android/location/GnssClock.java b/location/java/android/location/GnssClock.java
index 5384061..8a7878b 100644
--- a/location/java/android/location/GnssClock.java
+++ b/location/java/android/location/GnssClock.java
@@ -17,7 +17,6 @@
 package android.location;
 
 import android.annotation.FloatRange;
-import android.annotation.IntRange;
 import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -54,7 +53,7 @@
     private double mDriftUncertaintyNanosPerSecond;
     private int mHardwareClockDiscontinuityCount;
     private long mElapsedRealtimeNanos;
-    private long mElapsedRealtimeUncertaintyNanos;
+    private double mElapsedRealtimeUncertaintyNanos;
 
     /**
      * @hide
@@ -469,8 +468,8 @@
      * <p>The value is only available if {@link #hasElapsedRealtimeUncertaintyNanos()} is
      * {@code true}.
      */
-    @IntRange(from = 0)
-    public long getElapsedRealtimeUncertaintyNanos() {
+    @FloatRange(from = 0.0f)
+    public double getElapsedRealtimeUncertaintyNanos() {
         return mElapsedRealtimeUncertaintyNanos;
     }
 
@@ -482,7 +481,7 @@
      */
     @TestApi
     public void setElapsedRealtimeUncertaintyNanos(
-            @IntRange(from = 0) long elapsedRealtimeUncertaintyNanos) {
+            @FloatRange(from = 0.0f) double elapsedRealtimeUncertaintyNanos) {
         setFlag(HAS_ELAPSED_REALTIME_UNCERTAINTY_NANOS);
         mElapsedRealtimeUncertaintyNanos = elapsedRealtimeUncertaintyNanos;
     }
@@ -496,7 +495,7 @@
     @TestApi
     public void resetElapsedRealtimeUncertaintyNanos() {
         resetFlag(HAS_ELAPSED_REALTIME_UNCERTAINTY_NANOS);
-        mElapsedRealtimeUncertaintyNanos = Long.MAX_VALUE;
+        mElapsedRealtimeUncertaintyNanos = Double.NaN;
     }
 
     /**
@@ -543,7 +542,7 @@
             gpsClock.mDriftUncertaintyNanosPerSecond = parcel.readDouble();
             gpsClock.mHardwareClockDiscontinuityCount = parcel.readInt();
             gpsClock.mElapsedRealtimeNanos = parcel.readLong();
-            gpsClock.mElapsedRealtimeUncertaintyNanos = parcel.readLong();
+            gpsClock.mElapsedRealtimeUncertaintyNanos = parcel.readDouble();
 
             return gpsClock;
         }
@@ -567,7 +566,7 @@
         parcel.writeDouble(mDriftUncertaintyNanosPerSecond);
         parcel.writeInt(mHardwareClockDiscontinuityCount);
         parcel.writeLong(mElapsedRealtimeNanos);
-        parcel.writeLong(mElapsedRealtimeUncertaintyNanos);
+        parcel.writeDouble(mElapsedRealtimeUncertaintyNanos);
     }
 
     @Override
diff --git a/location/java/android/location/Location.java b/location/java/android/location/Location.java
index 673b411..9c36d76 100644
--- a/location/java/android/location/Location.java
+++ b/location/java/android/location/Location.java
@@ -136,7 +136,7 @@
     private long mElapsedRealtimeNanos = 0;
     // Estimate of the relative precision of the alignment of this SystemClock
     // timestamp, with the reported measurements in nanoseconds (68% confidence).
-    private long mElapsedRealtimeUncertaintyNanos = 0;
+    private double mElapsedRealtimeUncertaintyNanos = 0.0f;
     private double mLatitude = 0.0;
     private double mLongitude = 0.0;
     private double mAltitude = 0.0f;
@@ -199,7 +199,7 @@
         mProvider = null;
         mTime = 0;
         mElapsedRealtimeNanos = 0;
-        mElapsedRealtimeUncertaintyNanos = 0;
+        mElapsedRealtimeUncertaintyNanos = 0.0;
         mFieldsMask = 0;
         mLatitude = 0;
         mLongitude = 0;
@@ -599,9 +599,17 @@
      * ElapsedRealtimeNanos timestamp, with the reported measurements in
      * nanoseconds (68% confidence).
      *
+     * This means that we have 68% confidence that the true timestamp of the
+     * event is within ElapsedReatimeNanos +/- uncertainty.
+     *
+     * Example :
+     *   - getElapsedRealtimeNanos() returns 10000000
+     *   - getElapsedRealtimeUncertaintyNanos() returns 1000000 (equivalent to 1millisecond)
+     *   This means that the event most likely happened between 9000000 and 11000000.
+     *
      * @return uncertainty of elapsed real-time of fix, in nanoseconds.
      */
-    public long getElapsedRealtimeUncertaintyNanos() {
+    public double getElapsedRealtimeUncertaintyNanos() {
         return mElapsedRealtimeUncertaintyNanos;
     }
 
@@ -612,7 +620,7 @@
      *
      * @param time uncertainty of the elapsed real-time of fix, in nanoseconds.
      */
-    public void setElapsedRealtimeUncertaintyNanos(long time) {
+    public void setElapsedRealtimeUncertaintyNanos(double time) {
         mElapsedRealtimeUncertaintyNanos = time;
         mFieldsMask |= HAS_ELAPSED_REALTIME_UNCERTAINTY_MASK;
     }
@@ -1104,7 +1112,7 @@
         }
         if (hasElapsedRealtimeUncertaintyNanos()) {
             s.append(" etAcc=");
-            TimeUtils.formatDuration(mElapsedRealtimeUncertaintyNanos / 1000000L, s);
+            TimeUtils.formatDuration((long) (mElapsedRealtimeUncertaintyNanos / 1000000), s);
         }
         if (hasAltitude()) s.append(" alt=").append(mAltitude);
         if (hasSpeed()) s.append(" vel=").append(mSpeed);
@@ -1136,7 +1144,7 @@
             Location l = new Location(provider);
             l.mTime = in.readLong();
             l.mElapsedRealtimeNanos = in.readLong();
-            l.mElapsedRealtimeUncertaintyNanos = in.readLong();
+            l.mElapsedRealtimeUncertaintyNanos = in.readDouble();
             l.mFieldsMask = in.readInt();
             l.mLatitude = in.readDouble();
             l.mLongitude = in.readDouble();
@@ -1167,7 +1175,7 @@
         parcel.writeString(mProvider);
         parcel.writeLong(mTime);
         parcel.writeLong(mElapsedRealtimeNanos);
-        parcel.writeLong(mElapsedRealtimeUncertaintyNanos);
+        parcel.writeDouble(mElapsedRealtimeUncertaintyNanos);
         parcel.writeInt(mFieldsMask);
         parcel.writeDouble(mLatitude);
         parcel.writeDouble(mLongitude);
diff --git a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
index 512210b..267d9f5 100644
--- a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
+++ b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
@@ -112,17 +112,22 @@
                     // zoneId
                     VolumeItem volumeItem = mAvailableVolumeItems.get(groupId);
                     int value = getSeekbarValue(mCarAudioManager, groupId);
+                    // find if the group id for which the volume changed is currently being
+                    // displayed.
+                    boolean isShowing = mCarVolumeLineItems.stream().anyMatch(
+                            item -> item.getGroupId() == groupId);
                     // Do not update the progress if it is the same as before. When car audio
                     // manager sets
                     // its group volume caused by the seekbar progress changed, it also triggers
                     // this
                     // callback. Updating the seekbar at the same time could block the continuous
                     // seeking.
-                    if (value != volumeItem.progress) {
+                    if (value != volumeItem.progress && isShowing) {
                         volumeItem.carVolumeItem.setProgress(value);
                         volumeItem.progress = value;
                     }
                     if ((flags & AudioManager.FLAG_SHOW_UI) != 0) {
+                        mCurrentlyDisplayingGroupId = groupId;
                         mHandler.obtainMessage(H.SHOW,
                                 Events.SHOW_REASON_VOLUME_CHANGED).sendToTarget();
                     }
@@ -134,10 +139,10 @@
                 }
             };
     private boolean mHovering;
+    private int mCurrentlyDisplayingGroupId;
     private boolean mShowing;
     private boolean mExpanded;
     private View mExpandIcon;
-    private VolumeItem mDefaultVolumeItem;
     private final ServiceConnection mServiceConnection = new ServiceConnection() {
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
@@ -152,8 +157,7 @@
                     mAvailableVolumeItems.add(volumeItem);
                     // The first one is the default item.
                     if (groupId == 0) {
-                        mDefaultVolumeItem = volumeItem;
-                        setupDefaultCarVolumeItem();
+                        setuptListItem(0);
                     }
                 }
 
@@ -177,9 +181,11 @@
         }
     };
 
-    private void setupDefaultCarVolumeItem() {
-        mDefaultVolumeItem.defaultItem = true;
-        addCarVolumeListItem(mDefaultVolumeItem, /* volumeGroupId = */0,
+    private void setuptListItem(int groupId) {
+        mCarVolumeLineItems.clear();
+        VolumeItem volumeItem = mAvailableVolumeItems.get(groupId);
+        volumeItem.defaultItem = true;
+        addCarVolumeListItem(volumeItem, /* volumeGroupId = */ groupId,
                 R.drawable.car_ic_keyboard_arrow_down, new ExpandIconListener()
         );
     }
@@ -299,9 +305,7 @@
             return;
         }
         mShowing = true;
-        if (mCarVolumeLineItems.isEmpty()) {
-            setupDefaultCarVolumeItem();
-        }
+        setuptListItem(mCurrentlyDisplayingGroupId);
         mDialog.show();
         Events.writeEvent(mContext, Events.EVENT_SHOW_DIALOG, reason, mKeyguard.isKeyguardLocked());
     }
@@ -437,7 +441,7 @@
             carVolumeItem.setSupplementalIcon(/* drawable= */ null,
                     /* showSupplementalIconDivider= */ false);
         }
-
+        carVolumeItem.setGroupId(volumeGroupId);
         mCarVolumeLineItems.add(carVolumeItem);
         volumeItem.carVolumeItem = carVolumeItem;
         volumeItem.progress = progress;
@@ -545,11 +549,8 @@
         Animator inAnimator;
         if (mExpanded) {
             for (int groupId = 0; groupId < mAvailableVolumeItems.size(); ++groupId) {
-                // Adding the items which are not coming from the default item.
-                VolumeItem volumeItem = mAvailableVolumeItems.get(groupId);
-                if (volumeItem.defaultItem) {
-                    updateDefaultVolumeItem(volumeItem.carVolumeItem);
-                } else {
+                if (groupId != mCurrentlyDisplayingGroupId) {
+                    VolumeItem volumeItem = mAvailableVolumeItems.get(groupId);
                     addCarVolumeListItem(volumeItem, groupId, 0, null);
                 }
             }
@@ -561,11 +562,8 @@
             Iterator itr = mCarVolumeLineItems.iterator();
             while (itr.hasNext()) {
                 CarVolumeItem carVolumeItem = (CarVolumeItem) itr.next();
-                VolumeItem volumeItem = findVolumeItem(carVolumeItem);
-                if (!volumeItem.defaultItem) {
+                if (carVolumeItem.getGroupId() != mCurrentlyDisplayingGroupId) {
                     itr.remove();
-                } else {
-                    updateDefaultVolumeItem(carVolumeItem);
                 }
             }
             inAnimator = AnimatorInflater.loadAnimator(
@@ -587,21 +585,6 @@
         mVolumeItemsAdapter.notifyDataSetChanged();
     }
 
-    private void updateDefaultVolumeItem(CarVolumeItem carVolumeItem) {
-        VolumeItem volumeItem = findVolumeItem(carVolumeItem);
-
-        // When volume dialog is expanded or collapsed the default list item is never
-        // reset. Whereas all other list items are removed when the dialog is collapsed and then
-        // added when the dialog is expanded using {@link CarVolumeDialogImpl#addCarVolumeListItem}.
-        // This sets the progressbar and the tint color of icons for all items other than default
-        // if they were changed. For default list item it should be done manually here.
-        int color = mContext.getResources().getColor(R.color.car_volume_dialog_tint);
-        Drawable primaryIcon = mContext.getResources().getDrawable(volumeItem.icon);
-        primaryIcon.mutate().setTint(color);
-        volumeItem.carVolumeItem.setPrimaryIcon(primaryIcon);
-        volumeItem.carVolumeItem.setProgress(volumeItem.progress);
-    }
-
     private final class VolumeSeekBarChangeListener implements OnSeekBarChangeListener {
 
         private final int mVolumeGroupId;
diff --git a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeItem.java b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeItem.java
index 9613de1..e1ea6f6 100644
--- a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeItem.java
+++ b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeItem.java
@@ -35,6 +35,7 @@
     private Drawable mSupplementalIcon;
     private View.OnClickListener mSupplementalIconOnClickListener;
     private boolean mShowSupplementalIconDivider;
+    private int mGroupId;
 
     private int mMax;
     private int mProgress;
@@ -85,6 +86,20 @@
         mIsDirty = true;
     }
 
+    /**
+     * Gets the group id associated.
+     */
+    public int getGroupId() {
+        return mGroupId;
+    }
+
+    /**
+     * Sets the group id associated.
+     */
+    public void setGroupId(int groupId) {
+        this.mGroupId = groupId;
+    }
+
     /** Sets {@code OnClickListener} for the supplemental icon. */
     public void setSupplementalIconListener(View.OnClickListener listener) {
         mSupplementalIconOnClickListener = listener;
diff --git a/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImpl.java b/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImpl.java
index 040e2ab..52e54f9 100644
--- a/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImpl.java
+++ b/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImpl.java
@@ -19,6 +19,7 @@
 import android.content.ComponentName;
 import android.content.Intent;
 import android.service.watchdog.ExplicitHealthCheckService;
+import android.service.watchdog.PackageInfo;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -67,8 +68,12 @@
     }
 
     @Override
-    public List<String> onGetSupportedPackages() {
-        return new ArrayList<>(mSupportedCheckers.keySet());
+    public List<PackageInfo> onGetSupportedPackages() {
+        List<PackageInfo> packages = new ArrayList<>();
+        for (ExplicitHealthChecker checker : mSupportedCheckers.values()) {
+            packages.add(checker.getSupportedPackage());
+        }
+        return packages;
     }
 
     @Override
@@ -82,7 +87,7 @@
         while (it.hasNext()) {
             ExplicitHealthChecker checker = it.next();
             if (checker.isPending()) {
-                packages.add(checker.getPackageName());
+                packages.add(checker.getSupportedPackage().getPackageName());
             }
         }
         return packages;
diff --git a/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthChecker.java b/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthChecker.java
index 650878e..c51be88 100644
--- a/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthChecker.java
+++ b/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthChecker.java
@@ -16,6 +16,8 @@
 
 package android.ext.services.watchdog;
 
+import android.service.watchdog.PackageInfo;
+
 /**
  * A type of explicit health check that can be performed on a device, e.g network health check
  */
@@ -38,7 +40,7 @@
     boolean isPending();
 
     /**
-     * Returns the package name this checker can make requests for.
+     * Returns the {@link PackageInfo} object this checker can make requests for.
      */
-    String getPackageName();
+    PackageInfo getSupportedPackage();
 }
diff --git a/packages/ExtServices/src/android/ext/services/watchdog/NetworkChecker.java b/packages/ExtServices/src/android/ext/services/watchdog/NetworkChecker.java
index 32375e6..09b319e 100644
--- a/packages/ExtServices/src/android/ext/services/watchdog/NetworkChecker.java
+++ b/packages/ExtServices/src/android/ext/services/watchdog/NetworkChecker.java
@@ -21,6 +21,7 @@
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
 import android.service.watchdog.ExplicitHealthCheckService;
+import android.service.watchdog.PackageInfo;
 
 import com.android.internal.annotations.GuardedBy;
 
@@ -34,6 +35,8 @@
     private final Object mLock = new Object();
     private final ExplicitHealthCheckService mService;
     private final String mPackageName;
+    // TODO: Receive from DeviceConfig flag
+    private final long mRequestDurationMillis = 0;
     @GuardedBy("mLock")
     private boolean mIsPending;
 
@@ -73,8 +76,8 @@
     }
 
     @Override
-    public String getPackageName() {
-        return mPackageName;
+    public PackageInfo getSupportedPackage() {
+        return new PackageInfo(mPackageName, mRequestDurationMillis);
     }
 
     // TODO(b/120598832): Also monitor NetworkCallback#onAvailable to see if we have any
diff --git a/packages/SystemUI/res/layout/bubble_expanded_view.xml b/packages/SystemUI/res/layout/bubble_expanded_view.xml
index bdc4ebd..65ede3d 100644
--- a/packages/SystemUI/res/layout/bubble_expanded_view.xml
+++ b/packages/SystemUI/res/layout/bubble_expanded_view.xml
@@ -28,7 +28,7 @@
     />
 
     <FrameLayout
-        android:id="@+id/header_permission_wrapper"
+        android:id="@+id/permission_or_settings"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:animateLayoutChanges="true">
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index 56b231b..a4870d4 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -222,14 +222,14 @@
     @Override
     public void onUiModeChanged() {
         if (mStackView != null) {
-            mStackView.onConfigChanged();
+            mStackView.onThemeChanged();
         }
     }
 
     @Override
     public void onOverlayChanged() {
         if (mStackView != null) {
-            mStackView.onConfigChanged();
+            mStackView.onThemeChanged();
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
index e8b1122..6b21526 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -69,7 +69,7 @@
 import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
 
 /**
- * Container for the expanded bubble view, handles rendering the caret and header of the view.
+ * Container for the expanded bubble view, handles rendering the caret and settings icon.
  */
 public class BubbleExpandedView extends LinearLayout implements View.OnClickListener {
     private static final String TAG = "BubbleExpandedView";
@@ -82,6 +82,7 @@
 
     // Permission view
     private View mPermissionView;
+    private TextView mPermissionPrompt;
 
     // Views for expanded state
     private ExpandableNotificationRow mNotifRow;
@@ -94,9 +95,13 @@
     private boolean mNeedsNewHeight;
 
     private int mMinHeight;
-    private int mHeaderHeight;
+    private int mSettingsIconHeight;
     private int mBubbleHeight;
     private int mPermissionHeight;
+    private int mIconInset;
+    private Drawable mSettingsIconDrawable;
+    private int mPointerWidth;
+    private int mPointerHeight;
 
     private NotificationEntry mEntry;
     private PackageManager mPm;
@@ -173,20 +178,21 @@
 
         Resources res = getResources();
         mPointerView = findViewById(R.id.pointer_view);
-        int width = res.getDimensionPixelSize(R.dimen.bubble_pointer_width);
-        int height = res.getDimensionPixelSize(R.dimen.bubble_pointer_height);
+        mPointerWidth = res.getDimensionPixelSize(R.dimen.bubble_pointer_width);
+        mPointerHeight = res.getDimensionPixelSize(R.dimen.bubble_pointer_height);
 
         TypedArray ta = getContext().obtainStyledAttributes(
                 new int[] {android.R.attr.colorBackgroundFloating});
         int bgColor = ta.getColor(0, Color.WHITE);
         ta.recycle();
 
-        ShapeDrawable triangleDrawable = new ShapeDrawable(
-                TriangleShape.create(width, height, false /* pointUp */));
+        ShapeDrawable triangleDrawable = new ShapeDrawable(TriangleShape.create(
+                mPointerWidth, mPointerHeight, false /* pointUp */));
+
         triangleDrawable.setTint(bgColor);
         mPointerView.setBackground(triangleDrawable);
 
-        FrameLayout viewWrapper = findViewById(R.id.header_permission_wrapper);
+        FrameLayout permissionOrSettings = findViewById(R.id.permission_or_settings);
 
         LayoutTransition transition = new LayoutTransition();
         transition.setDuration(200);
@@ -200,18 +206,21 @@
         transition.setInterpolator(LayoutTransition.DISAPPEARING, Interpolators.ALPHA_OUT);
 
         transition.setAnimateParentHierarchy(false);
-        viewWrapper.setLayoutTransition(transition);
-        viewWrapper.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
+        permissionOrSettings.setLayoutTransition(transition);
+        permissionOrSettings.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
 
-        mHeaderHeight = getContext().getResources().getDimensionPixelSize(
+        mSettingsIconHeight = getContext().getResources().getDimensionPixelSize(
                 R.dimen.bubble_expanded_header_height);
+        mSettingsIcon = findViewById(R.id.settings_button);
+        mIconInset = getResources().getDimensionPixelSize(R.dimen.bubble_icon_inset);
+        mSettingsIcon.setOnClickListener(this);
+        // Save initial drawable to create adaptive icons that will take its place.
+        mSettingsIconDrawable = mSettingsIcon.getDrawable();
+
         mPermissionHeight = getContext().getResources().getDimensionPixelSize(
                 R.dimen.bubble_permission_height);
-
         mPermissionView = findViewById(R.id.permission_layout);
-        mSettingsIcon = findViewById(R.id.settings_button);
-        mSettingsIcon.setOnClickListener(this);
-        updateHeaderColor();
+        mPermissionPrompt = mPermissionView.findViewById(R.id.prompt);
 
         findViewById(R.id.no_bubbles_button).setOnClickListener(this);
         findViewById(R.id.yes_bubbles_button).setOnClickListener(this);
@@ -264,7 +273,7 @@
     /**
      * Creates a background with corners rounded based on how the view is configured to display
      */
-    private Drawable createHeaderPermissionBackground(int bgColor) {
+    private Drawable createPermissionBackground(int bgColor) {
         TypedArray ta2 = getContext().obtainStyledAttributes(
                 new int[] {android.R.attr.dialogCornerRadius});
         final float cr = ta2.getDimension(0, 0f);
@@ -311,8 +320,8 @@
         if (mAppIcon == null) {
             mAppIcon = mPm.getDefaultActivityIcon();
         }
-        updateHeaderView();
-        updatePermissionView();
+        updateTheme();
+        togglePermissionOrSettings();
         updateExpandedView();
     }
 
@@ -338,12 +347,12 @@
 
     /**
      * Updates the entry backing this view. This will not re-populate ActivityView, it will
-     * only update the deep-links in the header, the title, and the height of the view.
+     * only update the deep-links in the title, and the height of the view.
      */
     public void update(NotificationEntry entry) {
         if (entry.key.equals(mEntry.key)) {
             mEntry = entry;
-            updateHeaderView();
+            updateSettingsContentDescription();
             updateHeight();
         } else {
             Log.w(TAG, "Trying to update entry with different key, new entry: "
@@ -351,35 +360,36 @@
         }
     }
 
-    /**
-     * Update header color and icon shape when theme changes.
-     */
-    void updateHeaderColor() {
+    void updateTheme() {
+        // Get new colors.
         TypedArray ta = mContext.obtainStyledAttributes(
-                new int[] {android.R.attr.colorBackgroundFloating, android.R.attr.colorForeground});
+                new int[]{android.R.attr.colorBackgroundFloating, android.R.attr.colorForeground});
         int backgroundColor = ta.getColor(0, Color.WHITE /* default */);
         int foregroundColor = ta.getColor(1, Color.BLACK /* default */);
         ta.recycle();
 
-        mPermissionView.setBackground(createHeaderPermissionBackground(backgroundColor));
+        // Must clear tint first - otherwise tint updates inconsistently.
+        mSettingsIconDrawable.setTintList(null);
+        mSettingsIconDrawable.setTint(foregroundColor);
 
-        Drawable settingsIcon =  mSettingsIcon.getDrawable();
-        settingsIcon.setTint(foregroundColor);
-
-        int mIconInset = getResources().getDimensionPixelSize(R.dimen.bubble_icon_inset);
-        InsetDrawable foreground = new InsetDrawable(settingsIcon, mIconInset);
+        InsetDrawable foreground = new InsetDrawable(mSettingsIconDrawable, mIconInset);
         ColorDrawable background = new ColorDrawable(backgroundColor);
         AdaptiveIconDrawable adaptiveIcon = new AdaptiveIconDrawable(background,
                 foreground);
         mSettingsIcon.setImageDrawable(adaptiveIcon);
+
+        // Update permission prompt color.
+        mPermissionView.setBackground(createPermissionBackground(backgroundColor));
+        mPermissionPrompt.setTextColor(foregroundColor);
+
+        // Update triangle color.
+        ShapeDrawable triangleDrawable = new ShapeDrawable(
+                TriangleShape.create(mPointerWidth, mPointerHeight, false /* pointUp */));
+        triangleDrawable.setTint(backgroundColor);
+        mPointerView.setBackground(triangleDrawable);
     }
 
-    private void updateHeaderView() {
-        mSettingsIcon.setContentDescription(getResources().getString(
-                R.string.bubbles_settings_button_description, mAppName));
-    }
-
-    private void updatePermissionView() {
+    void togglePermissionOrSettings() {
         boolean hasUserApprovedBubblesForPackage = false;
         try {
             hasUserApprovedBubblesForPackage =
@@ -392,12 +402,6 @@
             showSettingsIcon();
         } else {
             showPermissionView();
-            ((ImageView) mPermissionView.findViewById(R.id.pkgicon)).setImageDrawable(mAppIcon);
-            ((TextView) mPermissionView.findViewById(R.id.pkgname)).setText(mAppName);
-            ((TextView) mPermissionView.findViewById(R.id.prompt)).setText(
-                    getResources().getString(R.string.bubbles_prompt, mAppName));
-            logBubbleClickEvent(mEntry,
-                    StatsLog.BUBBLE_UICHANGED__ACTION__PERMISSION_DIALOG_SHOWN);
         }
     }
 
@@ -432,7 +436,7 @@
      */
     int getExpandedSize() {
         int chromeHeight = mPermissionView.getVisibility() != View.VISIBLE
-                ? mHeaderHeight
+                ? mSettingsIconHeight
                 : mPermissionHeight;
         return mBubbleHeight + mPointerView.getHeight() + mPointerMargin
                 + chromeHeight;
@@ -460,7 +464,7 @@
                 desiredHeight = desiredPx > 0 ? desiredPx : mMinHeight;
             }
             int chromeHeight = mPermissionView.getVisibility() != View.VISIBLE
-                    ? mHeaderHeight
+                    ? mSettingsIconHeight
                     : mPermissionHeight;
             int max = mStackView.getMaxExpandedHeight() - chromeHeight - mPointerView.getHeight()
                     - mPointerMargin;
@@ -523,15 +527,28 @@
         }
     }
 
+    private void updateSettingsContentDescription() {
+        mSettingsIcon.setContentDescription(getResources().getString(
+                R.string.bubbles_settings_button_description, mAppName));
+    }
+
     void showSettingsIcon() {
+        updateSettingsContentDescription();
+
         mPermissionView.setVisibility(GONE);
         mSettingsIcon.setVisibility(VISIBLE);
     }
 
     void showPermissionView() {
+        ((ImageView) mPermissionView.findViewById(R.id.pkgicon)).setImageDrawable(mAppIcon);
+        ((TextView) mPermissionView.findViewById(R.id.pkgname)).setText(mAppName);
+        mPermissionPrompt.setText(
+                getResources().getString(R.string.bubbles_prompt, mAppName));
+        logBubbleClickEvent(mEntry,
+                StatsLog.BUBBLE_UICHANGED__ACTION__PERMISSION_DIALOG_SHOWN);
+
         mSettingsIcon.setVisibility(GONE);
         mPermissionView.setVisibility(VISIBLE);
-
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index 00b1c9e..a4e1ad7 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -309,12 +309,12 @@
     }
 
     /**
-     * Handle config changes.
+     * Handle theme changes.
      */
-    public void onConfigChanged() {
+    public void onThemeChanged() {
         for (Bubble b: mBubbleData.getBubbles()) {
             b.iconView.updateViews();
-            b.expandedView.updateHeaderColor();
+            b.expandedView.updateTheme();
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java
index 0f659c3..4606526 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java
@@ -202,13 +202,21 @@
             // add a multiple property end listener to the layout that will call the end action
             // provided to startAll() once all animations on the animated properties complete.
             return (endActions) -> {
+                final Runnable runAllEndActions = () -> {
+                    for (Runnable action : endActions) {
+                        action.run();
+                    }
+                };
+
+                // If there aren't any children to animate, just run the end actions.
+                if (mLayout.getChildCount() == 0) {
+                    runAllEndActions.run();
+                    return;
+                }
+
                 if (endActions != null) {
                     mLayout.setEndActionForMultipleProperties(
-                            () -> {
-                                for (Runnable action : endActions) {
-                                    action.run();
-                                }
-                            },
+                            runAllEndActions,
                             allAnimatedProperties.toArray(
                                     new DynamicAnimation.ViewProperty[0]));
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index cff3855..0e9264b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -477,6 +477,15 @@
         }
         mThemeResId = themeResId;
 
+        reInflateViews();
+    }
+
+    @Override
+    public void onOverlayChanged() {
+        reInflateViews();
+    }
+
+    private void reInflateViews() {
         updateShowEmptyShadeView();
 
         // Re-inflate the status view group.
@@ -484,9 +493,9 @@
         removeView(mKeyguardStatusView);
         mKeyguardStatusView = (KeyguardStatusView) mInjectionInflationController
                 .injectable(LayoutInflater.from(mContext)).inflate(
-                    R.layout.keyguard_status_view,
-                    this,
-                    false);
+                        R.layout.keyguard_status_view,
+                        this,
+                        false);
         addView(mKeyguardStatusView, index);
 
         // Re-associate the clock container with the keyguard clock switch.
@@ -500,9 +509,9 @@
         KeyguardBottomAreaView oldBottomArea = mKeyguardBottomArea;
         mKeyguardBottomArea = (KeyguardBottomAreaView) mInjectionInflationController
                 .injectable(LayoutInflater.from(mContext)).inflate(
-                    R.layout.keyguard_bottom_area,
-                    this,
-                    false);
+                        R.layout.keyguard_bottom_area,
+                        this,
+                        false);
         mKeyguardBottomArea.initFrom(oldBottomArea);
         addView(mKeyguardBottomArea, index);
         initBottomArea();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTest.java
index 38a90f7..eef6ddc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTest.java
@@ -25,6 +25,7 @@
 import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
 
 import android.os.SystemClock;
 import android.testing.AndroidTestingRunner;
@@ -449,6 +450,18 @@
         Mockito.verify(allEnd, times(1)).run();
     }
 
+    @Test
+    public void testAnimationsForChildrenFromIndex_noChildren() {
+        mLayout.setController(mTestableController);
+
+        final Runnable after = Mockito.mock(Runnable.class);
+        mTestableController
+                .animationsForChildrenFromIndex(0, (index, animation) -> { })
+                .startAll(after);
+
+        verify(after, Mockito.times(1)).run();
+    }
+
     /**
      * Animation controller with configuration methods whose return values can be set by individual
      * tests.
diff --git a/packages/overlays/AccentColorBlackOverlay/res/values/colors_device_defaults.xml b/packages/overlays/AccentColorBlackOverlay/res/values/colors_device_defaults.xml
index 5648f91..c73cbba 100644
--- a/packages/overlays/AccentColorBlackOverlay/res/values/colors_device_defaults.xml
+++ b/packages/overlays/AccentColorBlackOverlay/res/values/colors_device_defaults.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 /**
- * Copyright (c) 2018, The Android Open Source Project
+ * 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.
@@ -18,5 +18,5 @@
 -->
 <resources>
     <color name="accent_device_default_light">#202020</color>
-    <color name="accent_device_default_dark">#FFFFFF</color>
+    <color name="accent_device_default_dark">#D7DEE6</color>
 </resources>
diff --git a/packages/overlays/AccentColorCinnamonOverlay/Android.mk b/packages/overlays/AccentColorCinnamonOverlay/Android.mk
new file mode 100644
index 0000000..d53c114
--- /dev/null
+++ b/packages/overlays/AccentColorCinnamonOverlay/Android.mk
@@ -0,0 +1,31 @@
+#
+#  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.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_RRO_THEME := AccentColorCinnamon
+LOCAL_CERTIFICATE := platform
+LOCAL_PRODUCT_MODULE := true
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := AccentColorCinnamonOverlay
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_RRO_PACKAGE)
diff --git a/packages/overlays/AccentColorCinnamonOverlay/AndroidManifest.xml b/packages/overlays/AccentColorCinnamonOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..bcb6c4f
--- /dev/null
+++ b/packages/overlays/AccentColorCinnamonOverlay/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<!--
+/**
+ * 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.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.theme.color.cinnamon"
+    android:versionCode="1"
+    android:versionName="1.0">
+    <overlay android:targetPackage="android" android:category="android.theme.customization.accent_color" android:priority="1"/>
+
+    <application android:label="@string/accent_color_cinnamon_overlay" android:hasCode="false"/>
+</manifest>
diff --git a/packages/overlays/AccentColorCinnamonOverlay/res/values/colors_device_defaults.xml b/packages/overlays/AccentColorCinnamonOverlay/res/values/colors_device_defaults.xml
new file mode 100644
index 0000000..c420ab6
--- /dev/null
+++ b/packages/overlays/AccentColorCinnamonOverlay/res/values/colors_device_defaults.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * 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.
+ */
+-->
+<resources>
+    <color name="accent_device_default_light">#AF6050</color>
+    <color name="accent_device_default_dark">#9D6962</color>
+</resources>
diff --git a/packages/overlays/AccentColorCinnamonOverlay/res/values/strings.xml b/packages/overlays/AccentColorCinnamonOverlay/res/values/strings.xml
new file mode 100644
index 0000000..ac8ca7d
--- /dev/null
+++ b/packages/overlays/AccentColorCinnamonOverlay/res/values/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * 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.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Cinnamon accent color name application label. [CHAR LIMIT=50] -->
+    <string name="accent_color_cinnamon_overlay" translatable="false">Cinnamon</string>
+</resources>
+
diff --git a/packages/overlays/AccentColorOceanOverlay/Android.mk b/packages/overlays/AccentColorOceanOverlay/Android.mk
new file mode 100644
index 0000000..a28fc72
--- /dev/null
+++ b/packages/overlays/AccentColorOceanOverlay/Android.mk
@@ -0,0 +1,31 @@
+#
+#  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.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_RRO_THEME := AccentColorOcean
+LOCAL_CERTIFICATE := platform
+LOCAL_PRODUCT_MODULE := true
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := AccentColorOceanOverlay
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_RRO_PACKAGE)
diff --git a/packages/overlays/AccentColorOceanOverlay/AndroidManifest.xml b/packages/overlays/AccentColorOceanOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..bbee10d
--- /dev/null
+++ b/packages/overlays/AccentColorOceanOverlay/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<!--
+/**
+ * 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.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.theme.color.ocean"
+    android:versionCode="1"
+    android:versionName="1.0">
+    <overlay android:targetPackage="android" android:category="android.theme.customization.accent_color" android:priority="1"/>
+
+    <application android:label="@string/accent_color_ocean_overlay" android:hasCode="false"/>
+</manifest>
diff --git a/packages/overlays/AccentColorOceanOverlay/res/values/colors_device_defaults.xml b/packages/overlays/AccentColorOceanOverlay/res/values/colors_device_defaults.xml
new file mode 100644
index 0000000..6aec805
--- /dev/null
+++ b/packages/overlays/AccentColorOceanOverlay/res/values/colors_device_defaults.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * 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.
+ */
+-->
+<resources>
+    <color name="accent_device_default_light">#0C80A7</color>
+    <color name="accent_device_default_dark">#347D98</color>
+</resources>
diff --git a/packages/overlays/AccentColorOceanOverlay/res/values/strings.xml b/packages/overlays/AccentColorOceanOverlay/res/values/strings.xml
new file mode 100644
index 0000000..9342d48
--- /dev/null
+++ b/packages/overlays/AccentColorOceanOverlay/res/values/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * 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.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Ocean accent color name application label. [CHAR LIMIT=50] -->
+    <string name="accent_color_ocean_overlay" translatable="false">Ocean</string>
+</resources>
+
diff --git a/packages/overlays/AccentColorOrchidOverlay/Android.mk b/packages/overlays/AccentColorOrchidOverlay/Android.mk
new file mode 100644
index 0000000..c635890
--- /dev/null
+++ b/packages/overlays/AccentColorOrchidOverlay/Android.mk
@@ -0,0 +1,31 @@
+#
+#  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.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_RRO_THEME := AccentColorOrchid
+LOCAL_CERTIFICATE := platform
+LOCAL_PRODUCT_MODULE := true
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := AccentColorOrchidOverlay
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_RRO_PACKAGE)
diff --git a/packages/overlays/AccentColorOrchidOverlay/AndroidManifest.xml b/packages/overlays/AccentColorOrchidOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..0290b68
--- /dev/null
+++ b/packages/overlays/AccentColorOrchidOverlay/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<!--
+/**
+ * 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.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.theme.color.orchid"
+    android:versionCode="1"
+    android:versionName="1.0">
+    <overlay android:targetPackage="android" android:category="android.theme.customization.accent_color" android:priority="1"/>
+
+    <application android:label="@string/accent_color_orchid_overlay" android:hasCode="false"/>
+</manifest>
diff --git a/packages/overlays/AccentColorOrchidOverlay/res/values/colors_device_defaults.xml b/packages/overlays/AccentColorOrchidOverlay/res/values/colors_device_defaults.xml
new file mode 100644
index 0000000..049f8b8
--- /dev/null
+++ b/packages/overlays/AccentColorOrchidOverlay/res/values/colors_device_defaults.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * 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.
+ */
+-->
+<resources>
+    <color name="accent_device_default_light">#C42CC9</color>
+    <color name="accent_device_default_dark">#C42CC9</color>
+</resources>
diff --git a/packages/overlays/AccentColorOrchidOverlay/res/values/strings.xml b/packages/overlays/AccentColorOrchidOverlay/res/values/strings.xml
new file mode 100644
index 0000000..4e7ec48
--- /dev/null
+++ b/packages/overlays/AccentColorOrchidOverlay/res/values/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * 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.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Orchid accent color name application label. [CHAR LIMIT=50] -->
+    <string name="accent_color_orchid_overlay" translatable="false">Orchid</string>
+</resources>
+
diff --git a/packages/overlays/AccentColorSpaceOverlay/Android.mk b/packages/overlays/AccentColorSpaceOverlay/Android.mk
new file mode 100644
index 0000000..a0edb96
--- /dev/null
+++ b/packages/overlays/AccentColorSpaceOverlay/Android.mk
@@ -0,0 +1,31 @@
+#
+#  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.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_RRO_THEME := AccentColorSpace
+LOCAL_CERTIFICATE := platform
+LOCAL_PRODUCT_MODULE := true
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := AccentColorSpaceOverlay
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_RRO_PACKAGE)
diff --git a/packages/overlays/AccentColorSpaceOverlay/AndroidManifest.xml b/packages/overlays/AccentColorSpaceOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..b9f1fa9
--- /dev/null
+++ b/packages/overlays/AccentColorSpaceOverlay/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<!--
+/**
+ * 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.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.theme.color.space"
+    android:versionCode="1"
+    android:versionName="1.0">
+    <overlay android:targetPackage="android" android:category="android.theme.customization.accent_color" android:priority="1"/>
+
+    <application android:label="@string/accent_color_space_overlay" android:hasCode="false"/>
+</manifest>
diff --git a/packages/overlays/AccentColorSpaceOverlay/res/values/colors_device_defaults.xml b/packages/overlays/AccentColorSpaceOverlay/res/values/colors_device_defaults.xml
new file mode 100644
index 0000000..b6f757c
--- /dev/null
+++ b/packages/overlays/AccentColorSpaceOverlay/res/values/colors_device_defaults.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * 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.
+ */
+-->
+<resources>
+    <color name="accent_device_default_light">#47618A</color>
+    <color name="accent_device_default_dark">#5D7A92</color>
+</resources>
diff --git a/packages/overlays/AccentColorSpaceOverlay/res/values/strings.xml b/packages/overlays/AccentColorSpaceOverlay/res/values/strings.xml
new file mode 100644
index 0000000..55cd5ae
--- /dev/null
+++ b/packages/overlays/AccentColorSpaceOverlay/res/values/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * 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.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Space accent color name application label. [CHAR LIMIT=50] -->
+    <string name="accent_color_space_overlay" translatable="false">Space</string>
+</resources>
+
diff --git a/packages/overlays/IconShapeSquareOverlay/res/values/config.xml b/packages/overlays/IconShapeSquareOverlay/res/values/config.xml
index 54623f5..7b65555 100644
--- a/packages/overlays/IconShapeSquareOverlay/res/values/config.xml
+++ b/packages/overlays/IconShapeSquareOverlay/res/values/config.xml
@@ -21,6 +21,8 @@
     <string name="config_icon_mask" translatable="false">"M50,0L100,0 100,100 0,100 0,0z"</string>
     <!-- Flag indicating whether round icons should be parsed from the application manifest. -->
     <bool name="config_useRoundIcon">false</bool>
+    <!-- Corner radius of system dialogs -->
+    <dimen name="config_dialogCornerRadius">0dp</dimen>
 
 </resources>
 
diff --git a/services/Android.bp b/services/Android.bp
index 567efac..b08d1a8 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -31,6 +31,7 @@
         "services.print",
         "services.restrictions",
         "services.startop",
+        "services.systemcaptions",
         "services.usage",
         "services.usb",
         "services.voiceinteraction",
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
index 9b02c4e..757c2dc 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
@@ -129,7 +129,8 @@
     public ContentCaptureManagerService(@NonNull Context context) {
         super(context, new FrameworkResourcesServiceNameResolver(context,
                 com.android.internal.R.string.config_defaultContentCaptureService),
-                UserManager.DISALLOW_CONTENT_CAPTURE, /* refreshServiceOnPackageUpdate= */ false);
+                UserManager.DISALLOW_CONTENT_CAPTURE,
+                /*packageUpdatePolicy=*/ PACKAGE_UPDATE_POLICY_NO_REFRESH);
         DeviceConfig.addOnPropertyChangedListener(DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
                 ActivityThread.currentApplication().getMainExecutor(),
                 (namespace, key, value) -> onDeviceConfigChange(key, value));
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 0f39029..47c85683 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -1697,6 +1697,8 @@
             return;
         }
 
+        type = fixTypeIfAuto(type);
+
         // Sanity check the window length.  This will catch people mistakenly
         // trying to pass an end-of-window timestamp rather than a duration.
         if (windowLength > AlarmManager.INTERVAL_HALF_DAY) {
@@ -1812,6 +1814,21 @@
     }
 
     /**
+     * In case of cars, we need to avoid scheduling wakeup alarms, since we don't want the system
+     * to wake up from suspend arbitrarily to perform app work.
+     */
+    private int fixTypeIfAuto(int type) {
+        if (mInjector.isAutomotive()) {
+            if (type == AlarmManager.ELAPSED_REALTIME_WAKEUP) {
+                type = AlarmManager.ELAPSED_REALTIME;
+            } else if (type == AlarmManager.RTC_WAKEUP) {
+                type = AlarmManager.RTC;
+            }
+        }
+        return type;
+    }
+
+    /**
      * Return the minimum time that should elapse before an app in the specified bucket
      * can receive alarms again
      */
@@ -2214,6 +2231,7 @@
             pw.print("  mLastTickSet="); pw.println(sdf.format(new Date(mLastTickSet)));
             pw.print("  mLastTickAdded="); pw.println(sdf.format(new Date(mLastTickAdded)));
             pw.print("  mLastTickRemoved="); pw.println(sdf.format(new Date(mLastTickRemoved)));
+            pw.print("  mIsAutomotive="); pw.println(mInjector.isAutomotive());
 
             if (RECORD_ALARMS_IN_HISTORY) {
                 pw.println();
@@ -3838,9 +3856,12 @@
     static class Injector {
         private long mNativeData;
         private Context mContext;
+        private final boolean mIsAutomotive;
 
         Injector(Context context) {
             mContext = context;
+            mIsAutomotive = context.getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_AUTOMOTIVE);
         }
 
         void init() {
@@ -3929,6 +3950,10 @@
         ClockReceiver getClockReceiver(AlarmManagerService service) {
             return service.new ClockReceiver();
         }
+
+        boolean isAutomotive() {
+            return mIsAutomotive;
+        }
     }
 
     private class AlarmThread extends Thread
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 3079192..0786b18 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -929,20 +929,13 @@
     private void initIfBootedAndConnected() {
         Slog.d(TAG, "Thinking about init, mBootCompleted=" + mBootCompleted
                 + ", mDaemonConnected=" + mDaemonConnected);
-        if (mBootCompleted && mDaemonConnected) {
-            // Tell vold to lock or unlock the user directories based on the
-            // current file-based encryption status.
-            final boolean initLocked;
-            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
-                // For native FBE this is a no-op after reboot, but this is
-                // still needed in case of framework restarts.
-                Slog.d(TAG, "FBE is enabled; ensuring all user directories are locked.");
-                initLocked = true;
-            } else {
-                // This is in case FBE emulation was turned off.
-                Slog.d(TAG, "FBE is disabled; ensuring the FBE emulation state is cleared.");
-                initLocked = false;
-            }
+        if (mBootCompleted && mDaemonConnected
+                && !StorageManager.isFileEncryptedNativeOnly()) {
+            // When booting a device without native support, make sure that our
+            // user directories are locked or unlocked based on the current
+            // emulation status.
+            final boolean initLocked = StorageManager.isFileEncryptedEmulatedOnly();
+            Slog.d(TAG, "Setting up emulation state, initlocked=" + initLocked);
             final List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
             for (UserInfo user : users) {
                 try {
diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java
index d67853a..aa52621 100644
--- a/services/core/java/com/android/server/biometrics/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/face/FaceService.java
@@ -44,6 +44,7 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.SELinux;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.service.restricted_image.RestrictedImageProto;
@@ -1091,6 +1092,13 @@
             return;
         }
 
+        // Additionally, this flag allows turning off face for a device
+        // (either permanently through the build or on an individual device).
+        if (SystemProperties.getBoolean("ro.face.disable_debug_data", false)
+                || SystemProperties.getBoolean("persist.face.disable_debug_data", false)) {
+            return;
+        }
+
         final ProtoOutputStream proto = new ProtoOutputStream(fd);
 
         final long setToken = proto.start(RestrictedImagesDumpProto.SETS);
diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
index 098b0e9..9782f30 100644
--- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
+++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
@@ -15,6 +15,7 @@
  */
 package com.android.server.infra;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
@@ -45,6 +46,8 @@
 import com.android.server.SystemService;
 
 import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.List;
 
 /**
@@ -75,6 +78,30 @@
 public abstract class AbstractMasterSystemService<M extends AbstractMasterSystemService<M, S>,
         S extends AbstractPerUserSystemService<S, M>> extends SystemService {
 
+    /** On a package update, does not refresh the per-user service in the cache. */
+    public static final int PACKAGE_UPDATE_POLICY_NO_REFRESH = 0;
+
+    /**
+     * On a package update, removes any existing per-user services in the cache.
+     *
+     * <p>This does not immediately recreate these services. It is assumed they will be recreated
+     * for the next user request.
+     */
+    public static final int PACKAGE_UPDATE_POLICY_REFRESH_LAZY = 1;
+
+    /**
+     * On a package update, removes and recreates any existing per-user services in the cache.
+     */
+    public static final int PACKAGE_UPDATE_POLICY_REFRESH_EAGER = 2;
+
+    @IntDef(flag = true, prefix = { "PACKAGE_UPDATE_POLICY_" }, value = {
+            PACKAGE_UPDATE_POLICY_NO_REFRESH,
+            PACKAGE_UPDATE_POLICY_REFRESH_LAZY,
+            PACKAGE_UPDATE_POLICY_REFRESH_EAGER
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PackageUpdatePolicy {}
+
     /**
      * Log tag
      */
@@ -127,8 +154,11 @@
 
     /**
      * Whether the per-user service should be removed from the cache when its apk is updated.
+     *
+     * <p>One of {@link #PACKAGE_UPDATE_POLICY_NO_REFRESH},
+     * {@link #PACKAGE_UPDATE_POLICY_REFRESH_LAZY} or {@link #PACKAGE_UPDATE_POLICY_REFRESH_EAGER}.
      */
-    private final boolean mRefreshServiceOnPackageUpdate;
+    private final @PackageUpdatePolicy int mPackageUpdatePolicy;
 
     /**
      * Name of the service packages whose APK are being updated, keyed by user id.
@@ -154,7 +184,7 @@
             @Nullable ServiceNameResolver serviceNameResolver,
             @Nullable String disallowProperty) {
         this(context, serviceNameResolver, disallowProperty,
-                /* refreshServiceOnPackageUpdate=*/ true);
+                /*packageUpdatePolicy=*/ PACKAGE_UPDATE_POLICY_REFRESH_LAZY);
     }
 
     /**
@@ -167,17 +197,19 @@
      * @param disallowProperty when not {@code null}, defines a {@link UserManager} restriction that
      *        disables the service. <b>NOTE: </b> you'll also need to add it to
      *        {@code UserRestrictionsUtils.USER_RESTRICTIONS}.
-     * @param refreshServiceOnPackageUpdate when {@code true}, the
-     *        {@link AbstractPerUserSystemService} is removed from the cache (and re-added) when the
-     *        service package is updated; when {@code false}, the service is untouched during the
-     *        update.
+     * @param packageUpdatePolicy when {@link #PACKAGE_UPDATE_POLICY_REFRESH_LAZY}, the
+     *        {@link AbstractPerUserSystemService} is removed from the cache when the service
+     *        package is updated; when {@link #PACKAGE_UPDATE_POLICY_REFRESH_EAGER}, the
+     *        {@link AbstractPerUserSystemService} is removed from the cache and immediately
+     *        re-added when the service package is updated; when
+     *        {@link #PACKAGE_UPDATE_POLICY_NO_REFRESH}, the service is untouched during the update.
      */
     protected AbstractMasterSystemService(@NonNull Context context,
             @Nullable ServiceNameResolver serviceNameResolver,
-            @Nullable String disallowProperty, boolean refreshServiceOnPackageUpdate) {
+            @Nullable String disallowProperty, @PackageUpdatePolicy int packageUpdatePolicy) {
         super(context);
 
-        mRefreshServiceOnPackageUpdate = refreshServiceOnPackageUpdate;
+        mPackageUpdatePolicy = packageUpdatePolicy;
 
         mServiceNameResolver = serviceNameResolver;
         if (mServiceNameResolver != null) {
@@ -645,7 +677,7 @@
             final int size = mServicesCache.size();
             pw.print(prefix); pw.print("Debug: "); pw.print(realDebug);
             pw.print(" Verbose: "); pw.println(realVerbose);
-            pw.print("Refresh on package update: "); pw.println(mRefreshServiceOnPackageUpdate);
+            pw.print("Refresh on package update: "); pw.println(mPackageUpdatePolicy);
             if (mUpdatingPackageNames != null) {
                 pw.print("Packages being updated: "); pw.println(mUpdatingPackageNames);
             }
@@ -701,12 +733,21 @@
                     }
                     mUpdatingPackageNames.put(userId, packageName);
                     onServicePackageUpdatingLocked(userId);
-                    if (mRefreshServiceOnPackageUpdate) {
+                    if (mPackageUpdatePolicy != PACKAGE_UPDATE_POLICY_NO_REFRESH) {
                         if (debug) {
-                            Slog.d(mTag, "Removing service for user " + userId + " because package "
-                                    + activePackageName + " is being updated");
+                            Slog.d(mTag, "Removing service for user " + userId
+                                    + " because package " + activePackageName
+                                    + " is being updated");
                         }
                         removeCachedServiceLocked(userId);
+
+                        if (mPackageUpdatePolicy == PACKAGE_UPDATE_POLICY_REFRESH_EAGER) {
+                            if (debug) {
+                                Slog.d(mTag, "Eagerly recreating service for user "
+                                        + userId);
+                            }
+                            getServiceForUserLocked(userId);
+                        }
                     } else {
                         if (debug) {
                             Slog.d(mTag, "Holding service for user " + userId + " while package "
diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java
index 06db8b8..48f21e4 100644
--- a/services/core/java/com/android/server/job/controllers/JobStatus.java
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -104,6 +104,9 @@
             | CONSTRAINT_TIMING_DELAY
             | CONSTRAINT_WITHIN_QUOTA;
 
+    // TODO(b/129954980)
+    private static final boolean STATS_LOG_ENABLED = false;
+
     // Soft override: ignore constraints like time that don't affect API availability
     public static final int OVERRIDE_SOFT = 1;
     // Full override: ignore all constraints including API-affecting like connectivity
@@ -1000,7 +1003,7 @@
         }
         satisfiedConstraints = (satisfiedConstraints&~constraint) | (state ? constraint : 0);
         mSatisfiedConstraintsOfInterest = satisfiedConstraints & CONSTRAINTS_OF_INTEREST;
-        if ((STATSD_CONSTRAINTS_TO_LOG & constraint) != 0) {
+        if (STATS_LOG_ENABLED && (STATSD_CONSTRAINTS_TO_LOG & constraint) != 0) {
             StatsLog.write_non_chained(StatsLog.SCHEDULED_JOB_CONSTRAINT_CHANGED,
                     sourceUid, null, getBatteryName(), getProtoConstraint(constraint),
                     state ? StatsLog.SCHEDULED_JOB_CONSTRAINT_CHANGED__STATE__SATISFIED
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 4504b2e..e28f89c 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -786,7 +786,7 @@
                 | (location.hasElapsedRealtimeUncertaintyNanos()
                         ? ELAPSED_REALTIME_HAS_TIME_UNCERTAINTY_NS : 0);
         long elapsedRealtimeNanos = location.getElapsedRealtimeNanos();
-        long elapsedRealtimeUncertaintyNanos = location.getElapsedRealtimeUncertaintyNanos();
+        double elapsedRealtimeUncertaintyNanos = location.getElapsedRealtimeUncertaintyNanos();
 
         native_inject_best_location(
                 gnssLocationFlags, latitudeDegrees, longitudeDegrees,
@@ -2215,7 +2215,7 @@
             float horizontalAccuracyMeters, float verticalAccuracyMeters,
             float speedAccuracyMetersPerSecond, float bearingAccuracyDegrees,
             long timestamp, int elapsedRealtimeFlags, long elapsedRealtimeNanos,
-            long elapsedRealtimeUncertaintyNanos);
+            double elapsedRealtimeUncertaintyNanos);
 
     private native void native_inject_location(double latitude, double longitude, float accuracy);
 
diff --git a/services/core/java/com/android/server/power/ThermalManagerService.java b/services/core/java/com/android/server/power/ThermalManagerService.java
index 16d11ef..0381445 100644
--- a/services/core/java/com/android/server/power/ThermalManagerService.java
+++ b/services/core/java/com/android/server/power/ThermalManagerService.java
@@ -24,6 +24,7 @@
 import android.hardware.thermal.V2_0.IThermalChangedCallback;
 import android.hardware.thermal.V2_0.ThrottlingSeverity;
 import android.os.Binder;
+import android.os.CoolingDevice;
 import android.os.HwBinder;
 import android.os.IThermalEventListener;
 import android.os.IThermalService;
@@ -49,8 +50,10 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Iterator;
 import java.util.List;
 import java.util.NoSuchElementException;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
  * This is a system service that listens to HAL thermal events and dispatch those to listeners.
@@ -93,8 +96,7 @@
     private ThermalHalWrapper mHalWrapper;
 
     /** Hal ready. */
-    @GuardedBy("mLock")
-    private boolean mHalReady;
+    private final AtomicBoolean mHalReady = new AtomicBoolean();
 
     /** Invalid throttling status */
     private static final int INVALID_THROTTLING = Integer.MIN_VALUE;
@@ -150,7 +152,7 @@
                 onTemperatureChanged(temperatures.get(i), false);
             }
             onTemperatureMapChangedLocked();
-            mHalReady = halConnected /* true */;
+            mHalReady.set(true);
         }
     }
 
@@ -298,20 +300,6 @@
         }
     }
 
-    private void dumpTemperaturesLocked(PrintWriter pw, String prefix,
-            Collection<Temperature> temperatures) {
-        for (Temperature t : temperatures) {
-            pw.print(prefix);
-            String out = String.format("Name: %s, Type: %d, Status: %d, Value: %f",
-                    t.getName(),
-                    t.getType(),
-                    t.getStatus(),
-                    t.getValue()
-            );
-            pw.println(out);
-        }
-    }
-
     @VisibleForTesting
     final IThermalService.Stub mService = new IThermalService.Stub() {
         @Override
@@ -324,7 +312,7 @@
                     if (!mThermalEventListeners.register(listener, null)) {
                         return false;
                     }
-                    if (mHalReady) {
+                    if (mHalReady.get()) {
                         // Notify its callback after new client registered.
                         postEventListenerCurrentTemperatures(listener, null);
                     }
@@ -346,7 +334,7 @@
                     if (!mThermalEventListeners.register(listener, new Integer(type))) {
                         return false;
                     }
-                    if (mHalReady) {
+                    if (mHalReady.get()) {
                         // Notify its callback after new client registered.
                         postEventListenerCurrentTemperatures(listener, new Integer(type));
                     }
@@ -377,7 +365,7 @@
                     android.Manifest.permission.DEVICE_POWER, null);
             final long token = Binder.clearCallingIdentity();
             try {
-                if (!mHalReady) {
+                if (!mHalReady.get()) {
                     return new ArrayList<>();
                 }
                 return mHalWrapper.getCurrentTemperatures(false, 0 /* not used */);
@@ -392,7 +380,7 @@
                     android.Manifest.permission.DEVICE_POWER, null);
             final long token = Binder.clearCallingIdentity();
             try {
-                if (!mHalReady) {
+                if (!mHalReady.get()) {
                     return new ArrayList<>();
                 }
                 return mHalWrapper.getCurrentTemperatures(true, type);
@@ -410,7 +398,7 @@
                     if (!mThermalStatusListeners.register(listener)) {
                         return false;
                     }
-                    if (mHalReady) {
+                    if (mHalReady.get()) {
                         // Notify its callback after new client registered.
                         postStatusListener(listener);
                     }
@@ -447,6 +435,43 @@
         }
 
         @Override
+        public List<CoolingDevice> getCurrentCoolingDevices() {
+            getContext().enforceCallingOrSelfPermission(
+                    android.Manifest.permission.DEVICE_POWER, null);
+            final long token = Binder.clearCallingIdentity();
+            try {
+                if (!mHalReady.get()) {
+                    return new ArrayList<>();
+                }
+                return mHalWrapper.getCurrentCoolingDevices(false, 0);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public List<CoolingDevice> getCurrentCoolingDevicesWithType(int type) {
+            getContext().enforceCallingOrSelfPermission(
+                    android.Manifest.permission.DEVICE_POWER, null);
+            final long token = Binder.clearCallingIdentity();
+            try {
+                if (!mHalReady.get()) {
+                    return new ArrayList<>();
+                }
+                return mHalWrapper.getCurrentCoolingDevices(true, type);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        private void dumpItemsLocked(PrintWriter pw, String prefix,
+                Collection<?> items) {
+            for (Iterator iterator = items.iterator(); iterator.hasNext();) {
+                pw.println(prefix + iterator.next().toString());
+            }
+        }
+
+        @Override
         public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
             if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) {
                 return;
@@ -461,17 +486,19 @@
                     mThermalStatusListeners.dump(pw, "\t");
                     pw.println("Thermal Status: " + mStatus);
                     pw.println("Cached temperatures:");
-                    dumpTemperaturesLocked(pw, "\t", mTemperatureMap.values());
-                    pw.println("HAL Ready: " + mHalReady);
-                    if (mHalReady) {
+                    dumpItemsLocked(pw, "\t", mTemperatureMap.values());
+                    pw.println("HAL Ready: " + mHalReady.get());
+                    if (mHalReady.get()) {
                         pw.println("HAL connection:");
                         mHalWrapper.dump(pw, "\t");
                         pw.println("Current temperatures from HAL:");
-                        dumpTemperaturesLocked(pw, "\t",
+                        dumpItemsLocked(pw, "\t",
                                 mHalWrapper.getCurrentTemperatures(false, 0));
+                        pw.println("Current cooling devices from HAL:");
+                        dumpItemsLocked(pw, "\t",
+                                mHalWrapper.getCurrentCoolingDevices(false, 0));
                     }
                 }
-
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
@@ -588,6 +615,9 @@
         protected abstract List<Temperature> getCurrentTemperatures(boolean shouldFilter,
                 int type);
 
+        protected abstract List<CoolingDevice> getCurrentCoolingDevices(boolean shouldFilter,
+                int type);
+
         protected abstract boolean connectToHal();
 
         protected abstract void dump(PrintWriter pw, String prefix);
@@ -664,6 +694,42 @@
         }
 
         @Override
+        protected List<CoolingDevice> getCurrentCoolingDevices(boolean shouldFilter,
+                int type) {
+            synchronized (mHalLock) {
+                List<CoolingDevice> ret = new ArrayList<>();
+                if (mThermalHal10 == null) {
+                    return ret;
+                }
+                try {
+                    mThermalHal10.getCoolingDevices((status, coolingDevices) -> {
+                        if (ThermalStatusCode.SUCCESS == status.code) {
+                            for (android.hardware.thermal.V1_0.CoolingDevice
+                                    coolingDevice : coolingDevices) {
+                                if (shouldFilter && type != coolingDevice.type) {
+                                    continue;
+                                }
+                                ret.add(new CoolingDevice(
+                                        (long) coolingDevice.currentValue,
+                                        coolingDevice.type,
+                                        coolingDevice.name));
+                            }
+                        } else {
+                            Slog.e(TAG,
+                                    "Couldn't get cooling device because of HAL error: "
+                                            + status.debugMessage);
+                        }
+
+                    });
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "Couldn't getCurrentCoolingDevices, reconnecting...", e);
+                    connectToHal();
+                }
+                return ret;
+            }
+        }
+
+        @Override
         protected boolean connectToHal() {
             synchronized (mHalLock) {
                 try {
@@ -757,6 +823,42 @@
         }
 
         @Override
+        protected List<CoolingDevice> getCurrentCoolingDevices(boolean shouldFilter,
+                int type) {
+            synchronized (mHalLock) {
+                List<CoolingDevice> ret = new ArrayList<>();
+                if (mThermalHal11 == null) {
+                    return ret;
+                }
+                try {
+                    mThermalHal11.getCoolingDevices((status, coolingDevices) -> {
+                        if (ThermalStatusCode.SUCCESS == status.code) {
+                            for (android.hardware.thermal.V1_0.CoolingDevice
+                                    coolingDevice : coolingDevices) {
+                                if (shouldFilter && type != coolingDevice.type) {
+                                    continue;
+                                }
+                                ret.add(new CoolingDevice(
+                                        (long) coolingDevice.currentValue,
+                                        coolingDevice.type,
+                                        coolingDevice.name));
+                            }
+                        } else {
+                            Slog.e(TAG,
+                                    "Couldn't get cooling device because of HAL error: "
+                                            + status.debugMessage);
+                        }
+
+                    });
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "Couldn't getCurrentCoolingDevices, reconnecting...", e);
+                    connectToHal();
+                }
+                return ret;
+            }
+        }
+
+        @Override
         protected boolean connectToHal() {
             synchronized (mHalLock) {
                 try {
@@ -817,9 +919,7 @@
                 }
                 try {
                     mThermalHal20.getCurrentTemperatures(shouldFilter, type,
-                            (ThermalStatus status,
-                                    ArrayList<android.hardware.thermal.V2_0.Temperature>
-                                            temperatures) -> {
+                            (status, temperatures) -> {
                                 if (ThermalStatusCode.SUCCESS == status.code) {
                                     for (android.hardware.thermal.V2_0.Temperature
                                             temperature : temperatures) {
@@ -844,6 +944,39 @@
         }
 
         @Override
+        protected List<CoolingDevice> getCurrentCoolingDevices(boolean shouldFilter,
+                int type) {
+            synchronized (mHalLock) {
+                List<CoolingDevice> ret = new ArrayList<>();
+                if (mThermalHal20 == null) {
+                    return ret;
+                }
+                try {
+                    mThermalHal20.getCurrentCoolingDevices(shouldFilter, type,
+                            (status, coolingDevices) -> {
+                                if (ThermalStatusCode.SUCCESS == status.code) {
+                                    for (android.hardware.thermal.V2_0.CoolingDevice
+                                            coolingDevice : coolingDevices) {
+                                        ret.add(new CoolingDevice(
+                                                coolingDevice.value, coolingDevice.type,
+                                                coolingDevice.name));
+                                    }
+                                } else {
+                                    Slog.e(TAG,
+                                            "Couldn't get cooling device because of HAL error: "
+                                                    + status.debugMessage);
+                                }
+
+                            });
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "Couldn't getCurrentCoolingDevices, reconnecting...", e);
+                    connectToHal();
+                }
+                return ret;
+            }
+        }
+
+        @Override
         protected boolean connectToHal() {
             synchronized (mHalLock) {
                 try {
diff --git a/services/core/java/com/android/server/role/RoleManagerService.java b/services/core/java/com/android/server/role/RoleManagerService.java
index f4e10ed..6d9e097 100644
--- a/services/core/java/com/android/server/role/RoleManagerService.java
+++ b/services/core/java/com/android/server/role/RoleManagerService.java
@@ -41,6 +41,7 @@
 import android.database.ContentObserver;
 import android.database.CursorWindow;
 import android.net.Uri;
+import android.os.AsyncTask;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
@@ -195,7 +196,13 @@
                     Slog.i(LOG_TAG, "Packages changed - re-running initial grants for user "
                             + userId);
                 }
-                performInitialGrantsIfNecessary(userId);
+                if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
+                        && intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
+                    // Package is being upgraded - we're about to get ACTION_PACKAGE_ADDED
+                    return;
+                }
+                AsyncTask.THREAD_POOL_EXECUTOR.execute(
+                        () -> performInitialGrantsIfNecessaryAsync(userId));
             }
         }, UserHandle.ALL, intentFilter, null, null);
 
@@ -222,8 +229,7 @@
         performInitialGrantsIfNecessary(userId);
     }
 
-    @MainThread
-    private void performInitialGrantsIfNecessary(@UserIdInt int userId) {
+    private CompletableFuture<Void> performInitialGrantsIfNecessaryAsync(@UserIdInt int userId) {
         RoleUserState userState;
         userState = getOrCreateUserState(userId);
 
@@ -247,20 +253,27 @@
             getOrCreateControllerService(userId).grantDefaultRoles(FgThread.getExecutor(),
                     successful -> {
                         if (successful) {
+                            userState.setPackagesHash(packagesHash);
                             result.complete(null);
                         } else {
                             result.completeExceptionally(new RuntimeException());
                         }
                     });
-            try {
-                result.get(30, TimeUnit.SECONDS);
-                userState.setPackagesHash(packagesHash);
-            } catch (InterruptedException | ExecutionException | TimeoutException e) {
-                Slog.e(LOG_TAG, "Failed to grant defaults for user " + userId, e);
-            }
+            return result;
         } else if (DEBUG) {
             Slog.i(LOG_TAG, "Already ran grants for package state " + packagesHash);
         }
+        return CompletableFuture.completedFuture(null);
+    }
+
+    @MainThread
+    private void performInitialGrantsIfNecessary(@UserIdInt int userId) {
+        CompletableFuture<Void> result = performInitialGrantsIfNecessaryAsync(userId);
+        try {
+            result.get(30, TimeUnit.SECONDS);
+        } catch (InterruptedException | ExecutionException | TimeoutException e) {
+            Slog.e(LOG_TAG, "Failed to grant defaults for user " + userId, e);
+        }
     }
 
     private void migrateRoleIfNecessary(String role, @UserIdInt int userId) {
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index 019cb31..73e9bf0 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -499,7 +499,7 @@
     }
 
     if (flags & ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS) {
-        SET(ElapsedRealtimeUncertaintyNanos, location.elapsedRealtime.timeUncertaintyNs);
+        SET(ElapsedRealtimeUncertaintyNanos, static_cast<double>(location.elapsedRealtime.timeUncertaintyNs));
     }
 
     return object.get();
@@ -533,7 +533,7 @@
         jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters,
         jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees,
         jlong timestamp, jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos,
-        jlong elapsedRealtimeUncertaintyNanos) {
+        jdouble elapsedRealtimeUncertaintyNanos) {
     GnssLocation_V2_0 location;
     location.v1_0 = createGnssLocation_V1_0(
             gnssLocationFlags, latitudeDegrees, longitudeDegrees, altitudeMeters,
@@ -1162,7 +1162,7 @@
         SET(ElapsedRealtimeNanos, static_cast<uint64_t>(elapsedRealtime.timestampNs));
     }
     if (flags & ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS) {
-        SET(ElapsedRealtimeUncertaintyNanos, static_cast<uint64_t>(elapsedRealtime.timeUncertaintyNs));
+        SET(ElapsedRealtimeUncertaintyNanos, static_cast<double>(elapsedRealtime.timeUncertaintyNs));
     }
     translateGnssClock(object, data.clock);
 }
@@ -2076,7 +2076,7 @@
         jlong timestamp,
         jint elapsedRealtimeFlags,
         jlong elapsedRealtimeNanos,
-        jlong elapsedRealtimeUncertaintyNanos) {
+        jdouble elapsedRealtimeUncertaintyNanos) {
     if (gnssHal_V2_0 != nullptr) {
         GnssLocation_V2_0 location = createGnssLocation_V2_0(
                 gnssLocationFlags,
@@ -2988,7 +2988,7 @@
             android_location_GnssLocationProvider_read_nmea)},
     {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
             android_location_GnssLocationProvider_inject_time)},
-    {"native_inject_best_location", "(IDDDFFFFFFJIJJ)V", reinterpret_cast<void *>(
+    {"native_inject_best_location", "(IDDDFFFFFFJIJD)V", reinterpret_cast<void *>(
             android_location_GnssLocationProvider_inject_best_location)},
     {"native_inject_location", "(DDF)V", reinterpret_cast<void *>(
             android_location_GnssLocationProvider_inject_location)},
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 9d09c4c..106e642 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -254,6 +254,8 @@
             "com.android.server.autofill.AutofillManagerService";
     private static final String CONTENT_CAPTURE_MANAGER_SERVICE_CLASS =
             "com.android.server.contentcapture.ContentCaptureManagerService";
+    private static final String SYSTEM_CAPTIONS_MANAGER_SERVICE_CLASS =
+            "com.android.server.systemcaptions.SystemCaptionsManagerService";
     private static final String TIME_ZONE_RULES_MANAGER_SERVICE_CLASS =
             "com.android.server.timezone.RulesManagerService$Lifecycle";
     private static final String IOT_SERVICE_CLASS =
@@ -1232,6 +1234,8 @@
             startContentCaptureService(context);
             startAttentionService(context);
 
+            startSystemCaptionsManagerService(context);
+
             // App prediction manager service
             traceBeginAndSlog("StartAppPredictionService");
             mSystemServiceManager.startService(APP_PREDICTION_MANAGER_SERVICE_CLASS);
@@ -2225,6 +2229,19 @@
         }, BOOT_TIMINGS_TRACE_LOG);
     }
 
+    private void startSystemCaptionsManagerService(@NonNull Context context) {
+        String serviceName = context.getString(
+                com.android.internal.R.string.config_defaultSystemCaptionsManagerService);
+        if (TextUtils.isEmpty(serviceName)) {
+            Slog.d(TAG, "SystemCaptionsManagerService disabled because resource is not overlaid");
+            return;
+        }
+
+        traceBeginAndSlog("StartSystemCaptionsManagerService");
+        mSystemServiceManager.startService(SYSTEM_CAPTIONS_MANAGER_SERVICE_CLASS);
+        traceEnd();
+    }
+
     private void startContentCaptureService(@NonNull Context context) {
         // First check if it was explicitly enabled by DeviceConfig
         boolean explicitlyEnabled = false;
@@ -2273,7 +2290,7 @@
         traceEnd();
     }
 
-    static final void startSystemUi(Context context, WindowManagerService windowManager) {
+    private static void startSystemUi(Context context, WindowManagerService windowManager) {
         Intent intent = new Intent();
         intent.setComponent(new ComponentName("com.android.systemui",
                 "com.android.systemui.SystemUIService"));
diff --git a/services/systemcaptions/Android.bp b/services/systemcaptions/Android.bp
new file mode 100644
index 0000000..4e190b6
--- /dev/null
+++ b/services/systemcaptions/Android.bp
@@ -0,0 +1,5 @@
+java_library_static {
+    name: "services.systemcaptions",
+    srcs: ["java/**/*.java"],
+    libs: ["services.core"],
+}
diff --git a/services/systemcaptions/java/com/android/server/systemcaptions/RemoteSystemCaptionsManagerService.java b/services/systemcaptions/java/com/android/server/systemcaptions/RemoteSystemCaptionsManagerService.java
new file mode 100644
index 0000000..5480b6c
--- /dev/null
+++ b/services/systemcaptions/java/com/android/server/systemcaptions/RemoteSystemCaptionsManagerService.java
@@ -0,0 +1,164 @@
+/*
+ * 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.systemcaptions;
+
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.UserHandle;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+
+/** Manages the connection to the remote system captions manager service. */
+final class RemoteSystemCaptionsManagerService {
+
+    private static final String TAG = RemoteSystemCaptionsManagerService.class.getSimpleName();
+
+    private static final String SERVICE_INTERFACE =
+            "android.service.systemcaptions.SystemCaptionsManagerService";
+
+    private final Object mLock = new Object();
+
+    private final Context mContext;
+    private final Intent mIntent;
+    private final ComponentName mComponentName;
+    private final int mUserId;
+    private final boolean mVerbose;
+    private final Handler mHandler;
+
+    private final RemoteServiceConnection mServiceConnection = new RemoteServiceConnection();
+
+    @GuardedBy("mLock")
+    @Nullable private IBinder mService;
+
+    @GuardedBy("mLock")
+    private boolean mBinding = false;
+
+    @GuardedBy("mLock")
+    private boolean mDestroyed = false;
+
+    RemoteSystemCaptionsManagerService(
+            Context context, ComponentName componentName, int userId, boolean verbose) {
+        mContext = context;
+        mComponentName = componentName;
+        mUserId = userId;
+        mVerbose = verbose;
+        mIntent = new Intent(SERVICE_INTERFACE).setComponent(componentName);
+        mHandler = new Handler(Looper.getMainLooper());
+    }
+
+    void initialize() {
+        if (mVerbose) {
+            Slog.v(TAG, "initialize()");
+        }
+        ensureBound();
+    }
+
+    void destroy() {
+        if (mVerbose) {
+            Slog.v(TAG, "destroy()");
+        }
+
+        synchronized (mLock) {
+            if (mDestroyed) {
+                if (mVerbose) {
+                    Slog.v(TAG, "destroy(): Already destroyed");
+                }
+                return;
+            }
+            mDestroyed = true;
+            ensureUnboundLocked();
+        }
+    }
+
+    boolean isDestroyed() {
+        synchronized (mLock) {
+            return mDestroyed;
+        }
+    }
+
+    private void ensureBound() {
+        synchronized (mLock) {
+            if (mService != null || mBinding) {
+                return;
+            }
+
+            if (mVerbose) {
+                Slog.v(TAG, "ensureBound(): binding");
+            }
+            mBinding = true;
+
+            int flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE;
+            boolean willBind = mContext.bindServiceAsUser(mIntent, mServiceConnection, flags,
+                    mHandler, new UserHandle(mUserId));
+            if (!willBind) {
+                Slog.w(TAG, "Could not bind to " + mIntent + " with flags " + flags);
+                mBinding = false;
+                mService = null;
+            }
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void ensureUnboundLocked() {
+        if (mService == null && !mBinding) {
+            return;
+        }
+
+        mBinding = false;
+        mService = null;
+
+        if (mVerbose) {
+            Slog.v(TAG, "ensureUnbound(): unbinding");
+        }
+        mContext.unbindService(mServiceConnection);
+    }
+
+    private class RemoteServiceConnection implements ServiceConnection {
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            synchronized (mLock) {
+                if (mVerbose) {
+                    Slog.v(TAG, "onServiceConnected()");
+                }
+                if (mDestroyed || !mBinding) {
+                    Slog.wtf(TAG, "onServiceConnected() dispatched after unbindService");
+                    return;
+                }
+                mBinding = false;
+                mService = service;
+            }
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            synchronized (mLock) {
+                if (mVerbose) {
+                    Slog.v(TAG, "onServiceDisconnected()");
+                }
+                mBinding = true;
+                mService = null;
+            }
+        }
+    }
+}
diff --git a/services/systemcaptions/java/com/android/server/systemcaptions/SystemCaptionsManagerPerUserService.java b/services/systemcaptions/java/com/android/server/systemcaptions/SystemCaptionsManagerPerUserService.java
new file mode 100644
index 0000000..b503670
--- /dev/null
+++ b/services/systemcaptions/java/com/android/server/systemcaptions/SystemCaptionsManagerPerUserService.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.systemcaptions;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.app.AppGlobals;
+import android.content.ComponentName;
+import android.content.pm.PackageManager;
+import android.content.pm.ServiceInfo;
+import android.os.RemoteException;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.server.infra.AbstractPerUserSystemService;
+
+/** Manages the captions manager service on a per-user basis. */
+final class SystemCaptionsManagerPerUserService extends
+        AbstractPerUserSystemService<SystemCaptionsManagerPerUserService,
+                SystemCaptionsManagerService> {
+
+    private static final String TAG = SystemCaptionsManagerPerUserService.class.getSimpleName();
+
+    @Nullable
+    @GuardedBy("mLock")
+    private RemoteSystemCaptionsManagerService mRemoteService;
+
+    SystemCaptionsManagerPerUserService(
+            @NonNull SystemCaptionsManagerService master,
+            @NonNull Object lock, boolean disabled, @UserIdInt int userId) {
+        super(master, lock, userId);
+    }
+
+    @Override
+    @NonNull
+    protected ServiceInfo newServiceInfoLocked(
+            @SuppressWarnings("unused") @NonNull ComponentName serviceComponent)
+            throws PackageManager.NameNotFoundException {
+        try {
+            return AppGlobals.getPackageManager().getServiceInfo(serviceComponent,
+                    PackageManager.GET_META_DATA, mUserId);
+        } catch (RemoteException e) {
+            throw new PackageManager.NameNotFoundException(
+                    "Could not get service for " + serviceComponent);
+        }
+    }
+
+    @GuardedBy("mLock")
+    void initializeLocked() {
+        if (mMaster.verbose) {
+            Slog.v(TAG, "initialize()");
+        }
+
+        RemoteSystemCaptionsManagerService service = getRemoteServiceLocked();
+        if (service == null && mMaster.verbose) {
+            Slog.v(TAG, "initialize(): Failed to init remote server");
+        }
+    }
+
+    @GuardedBy("mLock")
+    void destroyLocked() {
+        if (mMaster.verbose) {
+            Slog.v(TAG, "destroyLocked()");
+        }
+
+        if (mRemoteService != null) {
+            mRemoteService.destroy();
+            mRemoteService = null;
+        }
+    }
+
+    @GuardedBy("mLock")
+    @Nullable
+    private RemoteSystemCaptionsManagerService getRemoteServiceLocked() {
+        if (mRemoteService == null) {
+            String serviceName = getComponentNameLocked();
+            if (serviceName == null) {
+                if (mMaster.verbose) {
+                    Slog.v(TAG, "getRemoteServiceLocked(): Not set");
+                }
+                return null;
+            }
+
+            ComponentName serviceComponent = ComponentName.unflattenFromString(serviceName);
+            mRemoteService = new RemoteSystemCaptionsManagerService(
+                    getContext(),
+                    serviceComponent,
+                    mUserId,
+                    mMaster.verbose);
+            if (mMaster.verbose) {
+                Slog.v(TAG, "getRemoteServiceLocked(): initialize for user " + mUserId);
+            }
+            mRemoteService.initialize();
+        }
+
+        return mRemoteService;
+    }
+}
diff --git a/services/systemcaptions/java/com/android/server/systemcaptions/SystemCaptionsManagerService.java b/services/systemcaptions/java/com/android/server/systemcaptions/SystemCaptionsManagerService.java
new file mode 100644
index 0000000..27a116c
--- /dev/null
+++ b/services/systemcaptions/java/com/android/server/systemcaptions/SystemCaptionsManagerService.java
@@ -0,0 +1,61 @@
+/*
+ * 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.systemcaptions;
+
+import android.annotation.NonNull;
+import android.annotation.UserIdInt;
+import android.content.Context;
+
+import com.android.server.infra.AbstractMasterSystemService;
+import com.android.server.infra.FrameworkResourcesServiceNameResolver;
+
+/** A system service to bind to a remote system captions manager service. */
+public final class SystemCaptionsManagerService extends
+        AbstractMasterSystemService<SystemCaptionsManagerService,
+                SystemCaptionsManagerPerUserService> {
+
+    public SystemCaptionsManagerService(@NonNull Context context) {
+        super(context,
+                new FrameworkResourcesServiceNameResolver(
+                        context,
+                        com.android.internal.R.string.config_defaultSystemCaptionsManagerService),
+                /*disallowProperty=*/ null,
+                /*packageUpdatePolicy=*/ PACKAGE_UPDATE_POLICY_REFRESH_EAGER);
+    }
+
+    @Override
+    public void onStart() {
+        // Do nothing. This service does not publish any local or system services.
+    }
+
+    @Override
+    protected SystemCaptionsManagerPerUserService newServiceLocked(
+            @UserIdInt int resolvedUserId, boolean disabled) {
+        SystemCaptionsManagerPerUserService perUserService =
+                new SystemCaptionsManagerPerUserService(this, mLock, disabled, resolvedUserId);
+        perUserService.initializeLocked();
+        return perUserService;
+    }
+
+    @Override
+    protected void onServiceRemoved(
+            SystemCaptionsManagerPerUserService service, @UserIdInt int userId) {
+        synchronized (mLock) {
+            service.destroyLocked();
+        }
+    }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
index 7a40e44..7a68e92 100644
--- a/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
@@ -66,6 +66,7 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
@@ -118,6 +119,8 @@
     private AlarmManagerService.ClockReceiver mClockReceiver;
     @Mock
     private PowerManager.WakeLock mWakeLock;
+    @Mock
+    private PackageManager mMockPackageManager;
 
     private MockitoSession mMockingSession;
     private Injector mInjector;
@@ -128,15 +131,21 @@
     static class TestTimer {
         private long mElapsed;
         boolean mExpired;
+        int mType;
 
         synchronized long getElapsed() {
             return mElapsed;
         }
 
-        synchronized void set(long millisElapsed) {
+        synchronized void set(int type, long millisElapsed) {
+            mType = type;
             mElapsed = millisElapsed;
         }
 
+        synchronized int getType() {
+            return mType;
+        }
+
         synchronized void expire() throws InterruptedException {
             mExpired = true;
             notifyAll();
@@ -146,6 +155,8 @@
     }
 
     public class Injector extends AlarmManagerService.Injector {
+        boolean mIsAutomotiveOverride;
+
         Injector(Context context) {
             super(context);
         }
@@ -179,7 +190,7 @@
 
         @Override
         void setAlarm(int type, long millis) {
-            mTestTimer.set(millis);
+            mTestTimer.set(type, millis);
         }
 
         @Override
@@ -211,6 +222,11 @@
         PowerManager.WakeLock getAlarmWakeLock() {
             return mWakeLock;
         }
+
+        @Override
+        boolean isAutomotive() {
+            return mIsAutomotiveOverride;
+        }
     }
 
     @Before
@@ -237,6 +253,8 @@
         when(mMockContext.getContentResolver()).thenReturn(mMockResolver);
         doReturn("min_futurity=0,min_interval=0").when(() ->
                 Settings.Global.getString(mMockResolver, Settings.Global.ALARM_MANAGER_CONSTANTS));
+        when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
+
         mInjector = new Injector(mMockContext);
         mService = new AlarmManagerService(mMockContext, mInjector);
         spyOn(mService);
@@ -933,6 +951,37 @@
     }
 
     @Test
+    public void alarmTypes() throws Exception {
+        final int[] typesToSet = {ELAPSED_REALTIME_WAKEUP, ELAPSED_REALTIME, RTC_WAKEUP, RTC};
+        final int[] typesExpected = {ELAPSED_REALTIME_WAKEUP, ELAPSED_REALTIME,
+                ELAPSED_REALTIME_WAKEUP, ELAPSED_REALTIME};
+        assertAlarmTypeConversion(typesToSet, typesExpected);
+    }
+
+    /**
+     * Confirm that wakeup alarms are never set for automotive.
+     */
+    @Test
+    public void alarmTypesForAuto() throws Exception {
+        mInjector.mIsAutomotiveOverride = true;
+        final int[] typesToSet = {ELAPSED_REALTIME_WAKEUP, ELAPSED_REALTIME, RTC_WAKEUP, RTC};
+        final int[] typesExpected = {ELAPSED_REALTIME, ELAPSED_REALTIME, ELAPSED_REALTIME,
+                ELAPSED_REALTIME};
+        assertAlarmTypeConversion(typesToSet, typesExpected);
+    }
+
+    private void assertAlarmTypeConversion(int[] typesToSet, int[] typesExpected) throws Exception {
+        for (int i = 0; i < typesToSet.length; i++) {
+            setTestAlarm(typesToSet[i], 1234, getNewMockPendingIntent());
+            final int typeSet = mTestTimer.getType();
+            assertEquals("Alarm of type " + typesToSet[i] + " was set to type " + typeSet,
+                    typesExpected[i], typeSet);
+            mNowElapsedTest = mTestTimer.getElapsed();
+            mTestTimer.expire();
+        }
+    }
+
+    @Test
     public void alarmCountOnInvalidSet() {
         setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + 12345, null);
         assertEquals(-1, mService.mAlarmsPerUid.get(TEST_CALLING_UID, -1));
diff --git a/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
index 94d293e..27d5296 100644
--- a/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
@@ -28,6 +28,7 @@
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
+import android.os.CoolingDevice;
 import android.os.IBinder;
 import android.os.IPowerManager;
 import android.os.IThermalEventListener;
@@ -85,6 +86,8 @@
     private class ThermalHalFake extends ThermalHalWrapper {
         private static final int INIT_STATUS = Temperature.THROTTLING_NONE;
         private ArrayList<Temperature> mTemperatureList = new ArrayList<>();
+        private ArrayList<CoolingDevice> mCoolingDeviceList = new ArrayList<>();
+
         private Temperature mSkin1 = new Temperature(0, Temperature.TYPE_SKIN, "skin1",
                 INIT_STATUS);
         private Temperature mSkin2 = new Temperature(0, Temperature.TYPE_SKIN, "skin2",
@@ -93,17 +96,40 @@
                 INIT_STATUS);
         private Temperature mUsbPort = new Temperature(0, Temperature.TYPE_USB_PORT, "usbport",
                 INIT_STATUS);
+        private CoolingDevice mCpu = new CoolingDevice(0, CoolingDevice.TYPE_BATTERY, "cpu");
+        private CoolingDevice mGpu = new CoolingDevice(0, CoolingDevice.TYPE_BATTERY, "gpu");
 
         ThermalHalFake() {
             mTemperatureList.add(mSkin1);
             mTemperatureList.add(mSkin2);
             mTemperatureList.add(mBattery);
             mTemperatureList.add(mUsbPort);
+            mCoolingDeviceList.add(mCpu);
+            mCoolingDeviceList.add(mGpu);
         }
 
         @Override
         protected List<Temperature> getCurrentTemperatures(boolean shouldFilter, int type) {
-            return mTemperatureList;
+            List<Temperature> ret = new ArrayList<>();
+            for (Temperature temperature : mTemperatureList) {
+                if (shouldFilter && type != temperature.getType()) {
+                    continue;
+                }
+                ret.add(temperature);
+            }
+            return ret;
+        }
+
+        @Override
+        protected List<CoolingDevice> getCurrentCoolingDevices(boolean shouldFilter, int type) {
+            List<CoolingDevice> ret = new ArrayList<>();
+            for (CoolingDevice cdev : mCoolingDeviceList) {
+                if (shouldFilter && type != cdev.getType()) {
+                    continue;
+                }
+                ret.add(cdev);
+            }
+            return ret;
         }
 
         @Override
@@ -117,8 +143,10 @@
         }
     }
 
-    private void assertTemperatureEquals(List<Temperature> expected, List<Temperature> value) {
-        assertEquals(new HashSet<>(expected), new HashSet<>(value));
+    private void assertListEqualsIgnoringOrder(List<?> actual, List<?> expected) {
+        HashSet<?> actualSet = new HashSet<>(actual);
+        HashSet<?> expectedSet = new HashSet<>(expected);
+        assertEquals(expectedSet, actualSet);
     }
 
     @Before
@@ -148,13 +176,14 @@
         ArgumentCaptor<Temperature> captor = ArgumentCaptor.forClass(Temperature.class);
         verify(mEventListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
                 .times(4)).notifyThrottling(captor.capture());
-        assertTemperatureEquals(mFakeHal.mTemperatureList, captor.getAllValues());
+        assertListEqualsIgnoringOrder(mFakeHal.mTemperatureList, captor.getAllValues());
         verify(mStatusListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
                 .times(1)).onStatusChange(Temperature.THROTTLING_NONE);
         captor = ArgumentCaptor.forClass(Temperature.class);
         verify(mEventListener2, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
                 .times(2)).notifyThrottling(captor.capture());
-        assertTemperatureEquals(new ArrayList<>(Arrays.asList(mFakeHal.mSkin1, mFakeHal.mSkin2)),
+        assertListEqualsIgnoringOrder(
+                new ArrayList<>(Arrays.asList(mFakeHal.mSkin1, mFakeHal.mSkin2)),
                 captor.getAllValues());
         verify(mStatusListener2, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
                 .times(1)).onStatusChange(Temperature.THROTTLING_NONE);
@@ -185,7 +214,7 @@
         ArgumentCaptor<Temperature> captor = ArgumentCaptor.forClass(Temperature.class);
         verify(mEventListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
                 .times(4)).notifyThrottling(captor.capture());
-        assertTemperatureEquals(mFakeHal.mTemperatureList, captor.getAllValues());
+        assertListEqualsIgnoringOrder(mFakeHal.mTemperatureList, captor.getAllValues());
         verify(mStatusListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
                 .times(1)).onStatusChange(Temperature.THROTTLING_NONE);
         // Register new callbacks and verify old ones are not called (remained same) while new
@@ -200,7 +229,8 @@
         captor = ArgumentCaptor.forClass(Temperature.class);
         verify(mEventListener2, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
                 .times(2)).notifyThrottling(captor.capture());
-        assertTemperatureEquals(new ArrayList<>(Arrays.asList(mFakeHal.mSkin1, mFakeHal.mSkin2)),
+        assertListEqualsIgnoringOrder(
+                new ArrayList<>(Arrays.asList(mFakeHal.mSkin1, mFakeHal.mSkin2)),
                 captor.getAllValues());
         verify(mStatusListener2, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
                 .times(1)).onStatusChange(Temperature.THROTTLING_NONE);
@@ -260,9 +290,9 @@
 
     @Test
     public void testGetCurrentTemperatures() throws RemoteException {
-        assertTemperatureEquals(mFakeHal.getCurrentTemperatures(false, 0),
+        assertListEqualsIgnoringOrder(mFakeHal.getCurrentTemperatures(false, 0),
                 mService.mService.getCurrentTemperatures());
-        assertTemperatureEquals(mFakeHal.getCurrentTemperatures(true, Temperature.TYPE_SKIN),
+        assertListEqualsIgnoringOrder(mFakeHal.getCurrentTemperatures(true, Temperature.TYPE_SKIN),
                 mService.mService.getCurrentTemperaturesWithType(Temperature.TYPE_SKIN));
     }
 
@@ -300,4 +330,16 @@
                 mService.mService.getCurrentTemperaturesWithType(Temperature.TYPE_SKIN).size());
         assertEquals(Temperature.THROTTLING_NONE, mService.mService.getCurrentThermalStatus());
     }
+
+    @Test
+    public void testGetCurrentCoolingDevices() throws RemoteException {
+        assertListEqualsIgnoringOrder(mFakeHal.getCurrentCoolingDevices(false, 0),
+                mService.mService.getCurrentCoolingDevices());
+        assertListEqualsIgnoringOrder(
+                mFakeHal.getCurrentCoolingDevices(false, CoolingDevice.TYPE_BATTERY),
+                mService.mService.getCurrentCoolingDevices());
+        assertListEqualsIgnoringOrder(
+                mFakeHal.getCurrentCoolingDevices(true, CoolingDevice.TYPE_CPU),
+                mService.mService.getCurrentCoolingDevicesWithType(CoolingDevice.TYPE_CPU));
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
index de4fb98..23bae88 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
@@ -37,7 +37,6 @@
 import android.platform.test.annotations.Presubmit;
 import android.util.SparseIntArray;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
 import com.android.server.wm.ActivityMetricsLaunchObserver.ActivityRecordProto;
@@ -119,7 +118,6 @@
     }
 
     @Test
-    @FlakyTest(bugId = 129138370)
     public void testOnIntentStarted() throws Exception {
         Intent intent = new Intent("action 1");
 
@@ -130,7 +128,6 @@
     }
 
     @Test
-    @FlakyTest(bugId = 129138370)
     public void testOnIntentFailed() throws Exception {
         testOnIntentStarted();
 
@@ -146,7 +143,6 @@
     }
 
     @Test
-    @FlakyTest(bugId = 129138370)
     public void testOnActivityLaunched() throws Exception {
         testOnIntentStarted();
 
@@ -158,7 +154,6 @@
     }
 
     @Test
-    @FlakyTest(bugId = 129138370)
     public void testOnActivityLaunchFinished() throws Exception {
        testOnActivityLaunched();
 
@@ -173,7 +168,6 @@
     }
 
     @Test
-    @FlakyTest(bugId = 129138370)
     public void testOnActivityLaunchCancelled() throws Exception {
        testOnActivityLaunched();
 
@@ -187,7 +181,6 @@
     }
 
     @Test
-    @FlakyTest(bugId = 129138370)
     public void testOnActivityLaunchedTrampoline() throws Exception {
         testOnIntentStarted();
 
@@ -204,7 +197,6 @@
     }
 
     @Test
-    @FlakyTest(bugId = 129138370)
     public void testOnActivityLaunchFinishedTrampoline() throws Exception {
        testOnActivityLaunchedTrampoline();
 
@@ -219,7 +211,6 @@
     }
 
     @Test
-    @FlakyTest(bugId = 129138370)
     public void testOnActivityLaunchCancelledTrampoline() throws Exception {
        testOnActivityLaunchedTrampoline();
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java
index 7cfe71e..c9263eb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java
@@ -32,7 +32,6 @@
 import android.platform.test.annotations.Presubmit;
 import android.view.InputChannel;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
 import org.junit.Before;
@@ -88,7 +87,6 @@
         assertNull(mTarget.getDragWindowHandleLocked());
     }
 
-    @FlakyTest(bugId = 129331490)
     @Test
     public void testHandleTapOutsideTask() {
         synchronized (mWm.mGlobalLock) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
index d8a01b9..1eb716a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
@@ -39,7 +39,6 @@
 import android.support.test.uiautomator.UiDevice;
 import android.text.TextUtils;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.MediumTest;
 
 import com.android.internal.annotations.GuardedBy;
@@ -159,6 +158,7 @@
      * Tests for onTaskCreated, onTaskMovedToFront, onTaskRemoved and onTaskRemovalStarted.
      */
     @Test
+    @Presubmit
     public void testTaskChangeCallBacks() throws Exception {
         final Object[] params = new Object[2];
         final CountDownLatch taskCreatedLaunchLatch = new CountDownLatch(1);
diff --git a/telecomm/java/android/telecom/CallRedirectionService.java b/telecomm/java/android/telecom/CallRedirectionService.java
index d01c889..37fab09 100644
--- a/telecomm/java/android/telecom/CallRedirectionService.java
+++ b/telecomm/java/android/telecom/CallRedirectionService.java
@@ -121,8 +121,6 @@
      *
      * @param handle the new phone number to dial
      * @param targetPhoneAccount the {@link PhoneAccountHandle} to use when placing the call.
-     *                           If {@code null}, no change will be made to the
-     *                           {@link PhoneAccountHandle} used to place the call.
      * @param confirmFirst Telecom will ask users to confirm the redirection via a yes/no dialog
      *                     if the confirmFirst is true, and if the redirection request of this
      *                     response was sent with a true flag of allowInteractiveResponse via
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index a567d03..0f8f873 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -2762,6 +2762,48 @@
     public static final String KEY_AUTO_CANCEL_CS_REJECT_NOTIFICATION =
             "carrier_auto_cancel_cs_notification";
 
+    /**
+     * Passing this value as {@link KEY_SUBSCRIPTION_GROUP_UUID_STRING} will remove the
+     * subscription from a group instead of adding it to a group.
+     *
+     * TODO: Expose in a future release.
+     *
+     * @hide
+     */
+    public static final String REMOVE_GROUP_UUID_STRING = "00000000-0000-0000-0000-000000000000";
+
+    /**
+     * The UUID of a Group of related subscriptions in which to place the current subscription.
+     *
+     * A grouped subscription will behave for billing purposes and other UI purposes as though it
+     * is a transparent extension of other subscriptions in the group.
+     *
+     * <p>If set to {@link #REMOVE_GROUP_UUID_STRING}, then the subscription will be removed from
+     * its current group.
+     *
+     * TODO: unhide this key.
+     *
+     * @hide
+     */
+    public static final String KEY_SUBSCRIPTION_GROUP_UUID_STRING =
+            "key_subscription_group_uuid_string";
+
+    /**
+    * A boolean property indicating whether this subscription should be managed as an opportunistic
+    * subscription.
+    *
+    * If true, then this subscription will be selected based on available coverage and will not be
+    * available for a user in settings menus for selecting macro network providers. If unset,
+    * defaults to “false”.
+    *
+    * TODO: unhide this key.
+    *
+    * @hide
+    */
+    public static final String KEY_IS_OPPORTUNISTIC_SUBSCRIPTION_BOOL =
+            "key_is_opportunistic_subscription_bool";
+
+
     /** The default value for every variable. */
     private final static PersistableBundle sDefaults;
 
@@ -3160,6 +3202,8 @@
         sDefaults.putString(KEY_SMART_FORWARDING_CONFIG_COMPONENT_NAME_STRING, "");
         sDefaults.putBoolean(KEY_ALWAYS_SHOW_PRIMARY_SIGNAL_BAR_IN_OPPORTUNISTIC_NETWORK_BOOLEAN,
                 false);
+        sDefaults.putString(KEY_SUBSCRIPTION_GROUP_UUID_STRING, "");
+        sDefaults.putBoolean(KEY_IS_OPPORTUNISTIC_SUBSCRIPTION_BOOL, false);
     }
 
     /**
diff --git a/tools/stats_log_api_gen/Collation.cpp b/tools/stats_log_api_gen/Collation.cpp
index e66ead7..373adca 100644
--- a/tools/stats_log_api_gen/Collation.cpp
+++ b/tools/stats_log_api_gen/Collation.cpp
@@ -226,6 +226,14 @@
         errorCount++;
         continue;
     }
+
+    // Doubles are not supported yet.
+    if (javaType == JAVA_TYPE_DOUBLE) {
+        print_error(field, "Doubles are not supported in atoms. Please change field %s to float\n",
+                    field->name().c_str());
+        errorCount++;
+        continue;
+    }
   }
 
   // Check that if there's an attribution chain, it's at position 1.
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
index a5b56a4..4e6d073 100644
--- a/tools/stats_log_api_gen/main.cpp
+++ b/tools/stats_log_api_gen/main.cpp
@@ -25,6 +25,11 @@
 const string DEFAULT_MODULE_NAME = "DEFAULT";
 const string DEFAULT_CPP_NAMESPACE = "android,util";
 const string DEFAULT_CPP_HEADER_IMPORT = "statslog.h";
+const string DEFAULT_JAVA_PACKAGE = "android.util";
+const string DEFAULT_JAVA_CLASS = "StatsLogInternal";
+
+const int JAVA_MODULE_REQUIRES_FLOAT = 0x01;
+const int JAVA_MODULE_REQUIRES_ATTRIBUTION = 0x02;
 
 using android::os::statsd::Atom;
 
@@ -921,11 +926,350 @@
     }
 }
 
+static void write_java_helpers_for_module(
+        FILE * out,
+        const AtomDecl &attributionDecl,
+        const int requiredHelpers) {
+    fprintf(out, "    private static void copyInt(byte[] buff, int pos, int val) {\n");
+    fprintf(out, "        buff[pos] = (byte) (val);\n");
+    fprintf(out, "        buff[pos + 1] = (byte) (val >> 8);\n");
+    fprintf(out, "        buff[pos + 2] = (byte) (val >> 16);\n");
+    fprintf(out, "        buff[pos + 3] = (byte) (val >> 24);\n");
+    fprintf(out, "        return;\n");
+    fprintf(out, "    }\n");
+    fprintf(out, "\n");
+
+    fprintf(out, "    private static void copyLong(byte[] buff, int pos, long val) {\n");
+    fprintf(out, "        buff[pos] = (byte) (val);\n");
+    fprintf(out, "        buff[pos + 1] = (byte) (val >> 8);\n");
+    fprintf(out, "        buff[pos + 2] = (byte) (val >> 16);\n");
+    fprintf(out, "        buff[pos + 3] = (byte) (val >> 24);\n");
+    fprintf(out, "        buff[pos + 4] = (byte) (val >> 32);\n");
+    fprintf(out, "        buff[pos + 5] = (byte) (val >> 40);\n");
+    fprintf(out, "        buff[pos + 6] = (byte) (val >> 48);\n");
+    fprintf(out, "        buff[pos + 7] = (byte) (val >> 56);\n");
+    fprintf(out, "        return;\n");
+    fprintf(out, "    }\n");
+    fprintf(out, "\n");
+
+    if (requiredHelpers & JAVA_MODULE_REQUIRES_FLOAT) {
+        fprintf(out, "    private static void copyFloat(byte[] buff, int pos, float val) {\n");
+        fprintf(out, "        copyInt(buff, pos, Float.floatToIntBits(val));\n");
+        fprintf(out, "        return;\n");
+        fprintf(out, "    }\n");
+        fprintf(out, "\n");
+    }
+
+    if (requiredHelpers & JAVA_MODULE_REQUIRES_ATTRIBUTION) {
+        fprintf(out, "    private static void writeAttributionChain(byte[] buff, int pos");
+        for (auto chainField : attributionDecl.fields) {
+            fprintf(out, ", %s[] %s",
+                java_type_name(chainField.javaType), chainField.name.c_str());
+        }
+        fprintf(out, ") {\n");
+
+        const char* uidName = attributionDecl.fields.front().name.c_str();
+        const char* tagName = attributionDecl.fields.back().name.c_str();
+
+        // Write the first list begin.
+        fprintf(out, "        buff[pos] = LIST_TYPE;\n");
+        fprintf(out, "        buff[pos + 1] = (byte) (%s.length);\n", tagName);
+        fprintf(out, "        pos += LIST_TYPE_OVERHEAD;\n");
+
+        // Iterate through the attribution chain and write the nodes.
+        fprintf(out, "        for (int i = 0; i < %s.length; i++) {\n", tagName);
+        // Write the list begin.
+        fprintf(out, "            buff[pos] = LIST_TYPE;\n");
+        fprintf(out, "            buff[pos + 1] = %lu;\n", attributionDecl.fields.size());
+        fprintf(out, "            pos += LIST_TYPE_OVERHEAD;\n");
+
+        // Write the uid.
+        fprintf(out, "            buff[pos] = INT_TYPE;\n");
+        fprintf(out, "            copyInt(buff, pos + 1, %s[i]);\n", uidName);
+        fprintf(out, "            pos += INT_TYPE_SIZE;\n");
+
+        // Write the tag.
+        fprintf(out, "            String %sStr = (%s[i] == null) ? \"\" : %s[i];\n",
+                tagName, tagName, tagName);
+        fprintf(out, "            byte[] %sByte = %sStr.getBytes(UTF_8);\n", tagName, tagName);
+        fprintf(out, "            buff[pos] = STRING_TYPE;\n");
+        fprintf(out, "            copyInt(buff, pos + 1, %sByte.length);\n", tagName);
+        fprintf(out, "            System.arraycopy("
+                "%sByte, 0, buff, pos + STRING_TYPE_OVERHEAD, %sByte.length);\n",
+                tagName, tagName);
+        fprintf(out, "            pos += STRING_TYPE_OVERHEAD + %sByte.length;\n", tagName);
+        fprintf(out, "        }\n");
+        fprintf(out, "    }\n");
+        fprintf(out, "\n");
+    }
+}
+
+
+static int write_java_non_chained_method_for_module(
+        FILE* out,
+        const map<vector<java_type_t>, set<string>>& signatures_to_modules,
+        const string& moduleName
+        ) {
+    for (auto signature_to_modules_it = signatures_to_modules.begin();
+            signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) {
+        // Skip if this signature is not needed for the module.
+        if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) {
+            continue;
+        }
+
+        // Print method signature.
+        vector<java_type_t> signature = signature_to_modules_it->first;
+        fprintf(out, "    public static void write_non_chained(int code");
+        int argIndex = 1;
+        for (vector<java_type_t>::const_iterator arg = signature.begin();
+                arg != signature.end(); arg++) {
+            if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
+                // Non chained signatures should not have attribution chains.
+                return 1;
+            } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
+                // Module logging does not yet support key value pair.
+                return 1;
+            } else {
+                fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex);
+            }
+            argIndex++;
+        }
+        fprintf(out, ") {\n");
+
+        fprintf(out, "        write(code");
+        argIndex = 1;
+        for (vector<java_type_t>::const_iterator arg = signature.begin();
+                arg != signature.end(); arg++) {
+            // First two args are uid and tag of attribution chain.
+            if (argIndex == 1) {
+                fprintf(out, ", new int[] {arg%d}", argIndex);
+            } else if (argIndex == 2) {
+                fprintf(out, ", new java.lang.String[] {arg%d}", argIndex);
+            } else {
+                fprintf(out, ", arg%d", argIndex);
+            }
+            argIndex++;
+        }
+        fprintf(out, ");\n");
+        fprintf(out, "    }\n");
+        fprintf(out, "\n");
+    }
+    return 0;
+}
+
+static int write_java_method_for_module(
+        FILE* out,
+        const map<vector<java_type_t>, set<string>>& signatures_to_modules,
+        const AtomDecl &attributionDecl,
+        const string& moduleName,
+        int* requiredHelpers
+        ) {
+
+    for (auto signature_to_modules_it = signatures_to_modules.begin();
+            signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) {
+        // Skip if this signature is not needed for the module.
+        if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) {
+            continue;
+        }
+
+        // Print method signature.
+        vector<java_type_t> signature = signature_to_modules_it->first;
+        fprintf(out, "    public static void write(int code");
+        int argIndex = 1;
+        for (vector<java_type_t>::const_iterator arg = signature.begin();
+                arg != signature.end(); arg++) {
+            if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
+                for (auto chainField : attributionDecl.fields) {
+                    fprintf(out, ", %s[] %s",
+                        java_type_name(chainField.javaType), chainField.name.c_str());
+                }
+            } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
+                // Module logging does not yet support key value pair.
+                return 1;
+            } else {
+                fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex);
+            }
+            argIndex++;
+        }
+        fprintf(out, ") {\n");
+
+        // Calculate the size of the buffer.
+        fprintf(out, "        // Initial overhead of the list, timestamp, and atom tag.\n");
+        fprintf(out, "        int needed = LIST_TYPE_OVERHEAD + LONG_TYPE_SIZE + INT_TYPE_SIZE;\n");
+        argIndex = 1;
+        for (vector<java_type_t>::const_iterator arg = signature.begin();
+                arg != signature.end(); arg++) {
+            switch (*arg) {
+            case JAVA_TYPE_BOOLEAN:
+            case JAVA_TYPE_INT:
+            case JAVA_TYPE_FLOAT:
+            case JAVA_TYPE_ENUM:
+                fprintf(out, "        needed += INT_TYPE_SIZE;\n");
+                break;
+            case JAVA_TYPE_LONG:
+                // Longs take 9 bytes, 1 for the type and 8 for the value.
+                fprintf(out, "        needed += LONG_TYPE_SIZE;\n");
+                break;
+            case JAVA_TYPE_STRING:
+                // Strings take 5 metadata bytes + length of byte encoded string.
+                fprintf(out, "        if (arg%d == null) {\n", argIndex);
+                fprintf(out, "            arg%d = \"\";\n", argIndex);
+                fprintf(out, "        }\n");
+                fprintf(out, "        byte[] arg%dBytes= arg%d.getBytes(UTF_8);\n",
+                        argIndex, argIndex);
+                fprintf(out, "        needed += STRING_TYPE_OVERHEAD + arg%dBytes.length;\n",
+                        argIndex);
+                break;
+            case JAVA_TYPE_BYTE_ARRAY:
+                // Byte arrays take 5 metadata bytes + length of byte array.
+                fprintf(out, "        if (arg%d == null) {\n", argIndex);
+                fprintf(out, "            arg%d = new byte[0];\n", argIndex);
+                fprintf(out, "        }\n");
+                fprintf(out, "        needed += STRING_TYPE_OVERHEAD + arg%d.length;\n", argIndex);
+                break;
+            case JAVA_TYPE_ATTRIBUTION_CHAIN:
+            {
+                const char* uidName = attributionDecl.fields.front().name.c_str();
+                const char* tagName = attributionDecl.fields.back().name.c_str();
+                // Null checks on the params.
+                fprintf(out, "        if (%s == null) {\n", uidName);
+                fprintf(out, "            %s = new %s[0];\n", uidName,
+                        java_type_name(attributionDecl.fields.front().javaType));
+                fprintf(out, "        }\n");
+                fprintf(out, "        if (%s == null) {\n", tagName);
+                fprintf(out, "            %s = new %s[0];\n", tagName,
+                        java_type_name(attributionDecl.fields.back().javaType));
+                fprintf(out, "        }\n");
+
+                // First check that the lengths of the uid and tag arrays are the same.
+                fprintf(out, "        if (%s.length != %s.length) {\n", uidName, tagName);
+                fprintf(out, "            return;\n");
+                fprintf(out, "        }\n");
+                fprintf(out, "        int attrSize = LIST_TYPE_OVERHEAD;\n");
+                fprintf(out, "        for (int i = 0; i < %s.length; i++) {\n", tagName);
+                fprintf(out, "            String str%d = (%s[i] == null) ? \"\" : %s[i];\n",
+                        argIndex, tagName, tagName);
+                fprintf(out, "            int str%dlen = str%d.getBytes(UTF_8).length;\n",
+                        argIndex, argIndex);
+                fprintf(out,
+                        "            attrSize += "
+                        "LIST_TYPE_OVERHEAD + INT_TYPE_SIZE + STRING_TYPE_OVERHEAD + str%dlen;\n",
+                        argIndex);
+                fprintf(out, "        }\n");
+                fprintf(out, "        needed += attrSize;\n");
+                break;
+            }
+            default:
+                // Unsupported types: OBJECT, DOUBLE, KEY_VALUE_PAIR.
+                return 1;
+            }
+            argIndex++;
+        }
+
+        // Now we have the size that is needed. Check for overflow and return if needed.
+        fprintf(out, "        if (needed > MAX_EVENT_PAYLOAD) {\n");
+        fprintf(out, "            return;\n");
+        fprintf(out, "        }\n");
+
+        // Create new buffer, and associated data types.
+        fprintf(out, "        byte[] buff = new byte[needed];\n");
+        fprintf(out, "        int pos = 0;\n");
+
+        // Initialize the buffer with list data type.
+        fprintf(out, "        buff[pos] = LIST_TYPE;\n");
+        fprintf(out, "        buff[pos + 1] = %lu;\n", signature.size() + 2);
+        fprintf(out, "        pos += LIST_TYPE_OVERHEAD;\n");
+
+        // Write timestamp.
+        fprintf(out, "        long elapsedRealtime = SystemClock.elapsedRealtimeNanos();\n");
+        fprintf(out, "        buff[pos] = LONG_TYPE;\n");
+        fprintf(out, "        copyLong(buff, pos + 1, elapsedRealtime);\n");
+        fprintf(out, "        pos += LONG_TYPE_SIZE;\n");
+
+        // Write atom code.
+        fprintf(out, "        buff[pos] = INT_TYPE;\n");
+        fprintf(out, "        copyInt(buff, pos + 1, code);\n");
+        fprintf(out, "        pos += INT_TYPE_SIZE;\n");
+
+        // Write the args.
+        argIndex = 1;
+        for (vector<java_type_t>::const_iterator arg = signature.begin();
+                arg != signature.end(); arg++) {
+            switch (*arg) {
+            case JAVA_TYPE_BOOLEAN:
+                fprintf(out, "        buff[pos] = INT_TYPE;\n");
+                fprintf(out, "        copyInt(buff, pos + 1, arg%d? 1 : 0);\n", argIndex);
+                fprintf(out, "        pos += INT_TYPE_SIZE;\n");
+                break;
+            case JAVA_TYPE_INT:
+            case JAVA_TYPE_ENUM:
+                fprintf(out, "        buff[pos] = INT_TYPE;\n");
+                fprintf(out, "        copyInt(buff, pos + 1, arg%d);\n", argIndex);
+                fprintf(out, "        pos += INT_TYPE_SIZE;\n");
+                break;
+            case JAVA_TYPE_FLOAT:
+                *requiredHelpers |= JAVA_MODULE_REQUIRES_FLOAT;
+                fprintf(out, "        buff[pos] = FLOAT_TYPE;\n");
+                fprintf(out, "        copyFloat(buff, pos + 1, arg%d);\n", argIndex);
+                fprintf(out, "        pos += FLOAT_TYPE_SIZE;\n");
+                break;
+            case JAVA_TYPE_LONG:
+                fprintf(out, "        buff[pos] = LONG_TYPE;\n");
+                fprintf(out, "        copyLong(buff, pos + 1, arg%d);\n", argIndex);
+                fprintf(out, "        pos += LONG_TYPE_SIZE;\n");
+                break;
+            case JAVA_TYPE_STRING:
+                fprintf(out, "        buff[pos] = STRING_TYPE;\n");
+                fprintf(out, "        copyInt(buff, pos + 1, arg%dBytes.length);\n", argIndex);
+                fprintf(out, "        System.arraycopy("
+                        "arg%dBytes, 0, buff, pos + STRING_TYPE_OVERHEAD, arg%dBytes.length);\n",
+                        argIndex, argIndex);
+                fprintf(out, "        pos += STRING_TYPE_OVERHEAD + arg%dBytes.length;\n",
+                        argIndex);
+                break;
+            case JAVA_TYPE_BYTE_ARRAY:
+                fprintf(out, "        buff[pos] = STRING_TYPE;\n");
+                fprintf(out, "        copyInt(buff, pos + 1, arg%d.length);\n", argIndex);
+                fprintf(out, "        System.arraycopy("
+                        "arg%d, 0, buff, pos + STRING_TYPE_OVERHEAD, arg%d.length);\n",
+                        argIndex, argIndex);
+                fprintf(out, "        pos += STRING_TYPE_OVERHEAD + arg%d.length;\n", argIndex);
+                break;
+            case JAVA_TYPE_ATTRIBUTION_CHAIN:
+            {
+                *requiredHelpers |= JAVA_MODULE_REQUIRES_ATTRIBUTION;
+                const char* uidName = attributionDecl.fields.front().name.c_str();
+                const char* tagName = attributionDecl.fields.back().name.c_str();
+
+                fprintf(out, "        writeAttributionChain(buff, pos, %s, %s);\n",
+                        uidName, tagName);
+                fprintf(out, "        pos += attrSize;\n");
+                break;
+            }
+            default:
+                // Unsupported types: OBJECT, DOUBLE, KEY_VALUE_PAIR.
+                return 1;
+            }
+            argIndex++;
+        }
+
+        fprintf(out, "        StatsLog.writeRaw(buff, pos);\n");
+        fprintf(out, "    }\n");
+        fprintf(out, "\n");
+    }
+    return 0;
+}
+
 static void write_java_work_source_method(FILE* out,
-        const map<vector<java_type_t>, set<string>>& signatures_to_modules) {
+        const map<vector<java_type_t>, set<string>>& signatures_to_modules,
+        const string& moduleName) {
     fprintf(out, "\n    // WorkSource methods.\n");
     for (auto signature_to_modules_it = signatures_to_modules.begin();
             signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) {
+        // Skip if this signature is not needed for the module.
+        if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) {
+            continue;
+        }
         vector<java_type_t> signature = signature_to_modules_it->first;
         // Determine if there is Attribution in this signature.
         int attributionArg = -1;
@@ -948,7 +1292,9 @@
         }
 
         // Method header (signature)
-        fprintf(out, "    /** @hide */\n");
+        if (moduleName == DEFAULT_MODULE_NAME) {
+            fprintf(out, "    /** @hide */\n");
+        }
         fprintf(out, "    public static void write(int code");
         int argIndex = 1;
         for (vector<java_type_t>::const_iterator arg = signature.begin();
@@ -973,7 +1319,7 @@
             }
         }
         fprintf(out, ");\n");
-        fprintf(out, "        }\n"); // close flor-loop
+        fprintf(out, "        }\n"); // close for-loop
 
         // write() component.
         fprintf(out, "        ArrayList<WorkSource.WorkChain> workChains = ws.getWorkChains();\n");
@@ -994,6 +1340,67 @@
     }
 }
 
+static void write_java_atom_codes(FILE* out, const Atoms& atoms, const string& moduleName) {
+    fprintf(out, "    // Constants for atom codes.\n");
+
+    std::map<int, set<AtomDecl>::const_iterator> atom_code_to_non_chained_decl_map;
+    build_non_chained_decl_map(atoms, &atom_code_to_non_chained_decl_map);
+
+    // Print constants for the atom codes.
+    for (set<AtomDecl>::const_iterator atom = atoms.decls.begin();
+            atom != atoms.decls.end(); atom++) {
+        // Skip if the atom is not needed for the module.
+        if (!atom_needed_for_module(*atom, moduleName)) {
+            continue;
+        }
+        string constant = make_constant_name(atom->name);
+        fprintf(out, "\n");
+        fprintf(out, "    /**\n");
+        fprintf(out, "     * %s %s<br>\n", atom->message.c_str(), atom->name.c_str());
+        write_java_usage(out, "write", constant, *atom);
+        auto non_chained_decl = atom_code_to_non_chained_decl_map.find(atom->code);
+        if (non_chained_decl != atom_code_to_non_chained_decl_map.end()) {
+            write_java_usage(out, "write_non_chained", constant, *non_chained_decl->second);
+        }
+        if (moduleName == DEFAULT_MODULE_NAME) {
+            fprintf(out, "     * @hide\n");
+        }
+        fprintf(out, "     */\n");
+        fprintf(out, "    public static final int %s = %d;\n", constant.c_str(), atom->code);
+    }
+    fprintf(out, "\n");
+}
+
+static void write_java_enum_values(FILE* out, const Atoms& atoms, const string& moduleName) {
+    fprintf(out, "    // Constants for enum values.\n\n");
+    for (set<AtomDecl>::const_iterator atom = atoms.decls.begin();
+        atom != atoms.decls.end(); atom++) {
+        // Skip if the atom is not needed for the module.
+        if (!atom_needed_for_module(*atom, moduleName)) {
+            continue;
+        }
+        for (vector<AtomField>::const_iterator field = atom->fields.begin();
+            field != atom->fields.end(); field++) {
+            if (field->javaType == JAVA_TYPE_ENUM) {
+                fprintf(out, "    // Values for %s.%s\n", atom->message.c_str(),
+                    field->name.c_str());
+                for (map<int, string>::const_iterator value = field->enumValues.begin();
+                    value != field->enumValues.end(); value++) {
+                    if (moduleName == DEFAULT_MODULE_NAME) {
+                        fprintf(out, "    /** @hide */\n");
+                    }
+                    fprintf(out, "    public static final int %s__%s__%s = %d;\n",
+                        make_constant_name(atom->message).c_str(),
+                        make_constant_name(field->name).c_str(),
+                        make_constant_name(value->second).c_str(),
+                        value->first);
+                }
+                fprintf(out, "\n");
+            }
+        }
+    }
+}
+
 static int
 write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl)
 {
@@ -1012,64 +1419,87 @@
     fprintf(out, " * @hide\n");
     fprintf(out, " */\n");
     fprintf(out, "public class StatsLogInternal {\n");
-    fprintf(out, "    // Constants for atom codes.\n");
+    write_java_atom_codes(out, atoms, DEFAULT_MODULE_NAME);
 
-    std::map<int, set<AtomDecl>::const_iterator> atom_code_to_non_chained_decl_map;
-    build_non_chained_decl_map(atoms, &atom_code_to_non_chained_decl_map);
-
-    // Print constants for the atom codes.
-    for (set<AtomDecl>::const_iterator atom = atoms.decls.begin();
-            atom != atoms.decls.end(); atom++) {
-        string constant = make_constant_name(atom->name);
-        fprintf(out, "\n");
-        fprintf(out, "    /**\n");
-        fprintf(out, "     * %s %s<br>\n", atom->message.c_str(), atom->name.c_str());
-        write_java_usage(out, "write", constant, *atom);
-        auto non_chained_decl = atom_code_to_non_chained_decl_map.find(atom->code);
-        if (non_chained_decl != atom_code_to_non_chained_decl_map.end()) {
-            write_java_usage(out, "write_non_chained", constant, *non_chained_decl->second);
-        }
-        fprintf(out, "     * @hide\n");
-        fprintf(out, "     */\n");
-        fprintf(out, "    public static final int %s = %d;\n", constant.c_str(), atom->code);
-    }
-    fprintf(out, "\n");
-
-    // Print constants for the enum values.
-    fprintf(out, "    // Constants for enum values.\n\n");
-    for (set<AtomDecl>::const_iterator atom = atoms.decls.begin();
-        atom != atoms.decls.end(); atom++) {
-        for (vector<AtomField>::const_iterator field = atom->fields.begin();
-            field != atom->fields.end(); field++) {
-            if (field->javaType == JAVA_TYPE_ENUM) {
-                fprintf(out, "    // Values for %s.%s\n", atom->message.c_str(),
-                    field->name.c_str());
-                for (map<int, string>::const_iterator value = field->enumValues.begin();
-                    value != field->enumValues.end(); value++) {
-                    fprintf(out, "    /** @hide */\n");
-                    fprintf(out, "    public static final int %s__%s__%s = %d;\n",
-                        make_constant_name(atom->message).c_str(),
-                        make_constant_name(field->name).c_str(),
-                        make_constant_name(value->second).c_str(),
-                        value->first);
-                }
-                fprintf(out, "\n");
-            }
-        }
-    }
+    write_java_enum_values(out, atoms, DEFAULT_MODULE_NAME);
 
     // Print write methods
     fprintf(out, "    // Write methods\n");
     write_java_method(out, "write", atoms.signatures_to_modules, attributionDecl);
     write_java_method(out, "write_non_chained", atoms.non_chained_signatures_to_modules,
             attributionDecl);
-    write_java_work_source_method(out, atoms.signatures_to_modules);
+    write_java_work_source_method(out, atoms.signatures_to_modules, DEFAULT_MODULE_NAME);
 
     fprintf(out, "}\n");
 
     return 0;
 }
 
+// TODO: Merge this with write_stats_log_java so that we can get rid of StatsLogInternal JNI.
+static int
+write_stats_log_java_for_module(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl,
+                     const string& moduleName, const string& javaClass, const string& javaPackage)
+{
+    // Print prelude
+    fprintf(out, "// This file is autogenerated\n");
+    fprintf(out, "\n");
+    fprintf(out, "package %s;\n", javaPackage.c_str());
+    fprintf(out, "\n");
+    fprintf(out, "import static java.nio.charset.StandardCharsets.UTF_8;\n");
+    fprintf(out, "\n");
+    fprintf(out, "import android.util.StatsLog;\n");
+    fprintf(out, "import android.os.SystemClock;\n");
+    fprintf(out, "\n");
+    fprintf(out, "import java.util.ArrayList;\n");
+    fprintf(out, "\n");
+    fprintf(out, "\n");
+    fprintf(out, "/**\n");
+    fprintf(out, " * Utility class for logging statistics events.\n");
+    fprintf(out, " */\n");
+    fprintf(out, "public class %s {\n", javaClass.c_str());
+
+    // TODO: ideally these match with the native values (and automatically change if they change).
+    fprintf(out, "    private static final int LOGGER_ENTRY_MAX_PAYLOAD = 4068;\n");
+    fprintf(out,
+            "    private static final int MAX_EVENT_PAYLOAD = LOGGER_ENTRY_MAX_PAYLOAD - 4;\n");
+    // Value types. Must match with EventLog.java and log.h.
+    fprintf(out, "    private static final byte INT_TYPE = 0;\n");
+    fprintf(out, "    private static final byte LONG_TYPE = 1;\n");
+    fprintf(out, "    private static final byte STRING_TYPE = 2;\n");
+    fprintf(out, "    private static final byte LIST_TYPE = 3;\n");
+    fprintf(out, "    private static final byte FLOAT_TYPE = 4;\n");
+
+    // Size of each value type.
+    // Booleans, ints, floats, and enums take 5 bytes, 1 for the type and 4 for the value.
+    fprintf(out, "    private static final int INT_TYPE_SIZE = 5;\n");
+    fprintf(out, "    private static final int FLOAT_TYPE_SIZE = 5;\n");
+    // Longs take 9 bytes, 1 for the type and 8 for the value.
+    fprintf(out, "    private static final int LONG_TYPE_SIZE = 9;\n");
+    // Strings take 5 metadata bytes: 1 byte is for the type, 4 are for the length.
+    fprintf(out, "    private static final int STRING_TYPE_OVERHEAD = 5;\n");
+    fprintf(out, "    private static final int LIST_TYPE_OVERHEAD = 2;\n");
+
+    write_java_atom_codes(out, atoms, moduleName);
+
+    write_java_enum_values(out, atoms, moduleName);
+
+    int errors = 0;
+    int requiredHelpers = 0;
+    // Print write methods
+    fprintf(out, "    // Write methods\n");
+    errors += write_java_method_for_module(out, atoms.signatures_to_modules, attributionDecl,
+            moduleName, &requiredHelpers);
+    errors += write_java_non_chained_method_for_module(out, atoms.non_chained_signatures_to_modules,
+            moduleName);
+
+    fprintf(out, "    // Helper methods for copying primitives\n");
+    write_java_helpers_for_module(out, attributionDecl, requiredHelpers);
+
+    fprintf(out, "}\n");
+
+    return errors;
+}
+
 static const char*
 jni_type_name(java_type_t type)
 {
@@ -1521,7 +1951,11 @@
     fprintf(stderr, "  --namespace COMMA,SEP,NAMESPACE   required for cpp/header with module\n");
     fprintf(stderr, "                                    comma separated namespace of the files\n");
     fprintf(stderr, "  --importHeader NAME  required for cpp/jni to say which header to import\n");
-}
+    fprintf(stderr, "  --javaPackage PACKAGE             the package for the java file.\n");
+    fprintf(stderr, "                                    required for java with module\n");
+    fprintf(stderr, "  --javaClass CLASS    the class name of the java class.\n");
+    fprintf(stderr, "                       Optional for Java with module.\n");
+    fprintf(stderr, "                       Default is \"StatsLogInternal\"\n");}
 
 /**
  * Do the argument parsing and execute the tasks.
@@ -1537,6 +1971,8 @@
     string moduleName = DEFAULT_MODULE_NAME;
     string cppNamespace = DEFAULT_CPP_NAMESPACE;
     string cppHeaderImport = DEFAULT_CPP_HEADER_IMPORT;
+    string javaPackage = DEFAULT_JAVA_PACKAGE;
+    string javaClass = DEFAULT_JAVA_CLASS;
 
     int index = 1;
     while (index < argc) {
@@ -1592,6 +2028,20 @@
                 return 1;
             }
             cppHeaderImport = argv[index];
+        } else if (0 == strcmp("--javaPackage", argv[index])) {
+            index++;
+            if (index >= argc) {
+                print_usage();
+                return 1;
+            }
+            javaPackage = argv[index];
+        } else if (0 == strcmp("--javaClass", argv[index])) {
+            index++;
+            if (index >= argc) {
+                print_usage();
+                return 1;
+            }
+            javaClass = argv[index];
         }
         index++;
     }
@@ -1661,8 +2111,18 @@
             fprintf(stderr, "Unable to open file for write: %s\n", javaFilename.c_str());
             return 1;
         }
-        errorCount = android::stats_log_api_gen::write_stats_log_java(
-            out, atoms, attributionDecl);
+        // If this is for a specific module, the java package must also be provided.
+        if (moduleName != DEFAULT_MODULE_NAME && javaPackage== DEFAULT_JAVA_PACKAGE) {
+            fprintf(stderr, "Must supply --javaPackage if supplying a specific module\n");
+            return 1;
+        }
+        if (moduleName == DEFAULT_MODULE_NAME) {
+            errorCount = android::stats_log_api_gen::write_stats_log_java(
+                    out, atoms, attributionDecl);
+        } else {
+            errorCount = android::stats_log_api_gen::write_stats_log_java_for_module(
+                    out, atoms, attributionDecl, moduleName, javaClass, javaPackage);
+        }
         fclose(out);
     }
 
@@ -1678,7 +2138,7 @@
         fclose(out);
     }
 
-    return 0;
+    return errorCount;
 }
 
 }