Merge "Add Missed call People Tile" into sc-dev
diff --git a/apex/appsearch/Android.bp b/apex/appsearch/Android.bp
index b014fdc..ab44dd9 100644
--- a/apex/appsearch/Android.bp
+++ b/apex/appsearch/Android.bp
@@ -21,6 +21,7 @@
     ],
     key: "com.android.appsearch.key",
     certificate: ":com.android.appsearch.certificate",
+    updatable: false,
 }
 
 apex_key {
diff --git a/core/api/current.txt b/core/api/current.txt
index db5d143..5b639ff 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -4735,6 +4735,13 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.app.AutomaticZenRule> CREATOR;
   }
 
+  public final class BackgroundServiceStartNotAllowedException extends android.app.ServiceStartNotAllowedException implements android.os.Parcelable {
+    ctor public BackgroundServiceStartNotAllowedException(@NonNull String);
+    method public int describeContents();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.BackgroundServiceStartNotAllowedException> CREATOR;
+  }
+
   public class DatePickerDialog extends android.app.AlertDialog implements android.widget.DatePicker.OnDateChangedListener android.content.DialogInterface.OnClickListener {
     ctor public DatePickerDialog(@NonNull android.content.Context);
     ctor public DatePickerDialog(@NonNull android.content.Context, @StyleRes int);
@@ -4980,6 +4987,13 @@
     method @Deprecated public void setSelectedGroup(int);
   }
 
+  public final class ForegroundServiceStartNotAllowedException extends android.app.ServiceStartNotAllowedException implements android.os.Parcelable {
+    ctor public ForegroundServiceStartNotAllowedException(@NonNull String);
+    method public int describeContents();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.ForegroundServiceStartNotAllowedException> CREATOR;
+  }
+
   @Deprecated public class Fragment implements android.content.ComponentCallbacks2 android.view.View.OnCreateContextMenuListener {
     ctor @Deprecated public Fragment();
     method @Deprecated public void dump(String, java.io.FileDescriptor, java.io.PrintWriter, String[]);
@@ -6563,6 +6577,9 @@
     field public static final int STOP_FOREGROUND_REMOVE = 1; // 0x1
   }
 
+  public abstract class ServiceStartNotAllowedException extends java.lang.IllegalStateException {
+  }
+
   public abstract class SharedElementCallback {
     ctor public SharedElementCallback();
     method public android.os.Parcelable onCaptureSharedElementSnapshot(android.view.View, android.graphics.Matrix, android.graphics.RectF);
@@ -51684,6 +51701,7 @@
     method public int describeContents();
     method public void dump(android.util.Printer, String);
     method public android.content.ComponentName getComponent();
+    method public int getConfigChanges();
     method public String getId();
     method public int getIsDefaultResourceId();
     method public String getPackageName();
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index fc1edf1..a02320d 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -2548,6 +2548,10 @@
     method @NonNull public static android.view.inputmethod.InlineSuggestionsResponse newInlineSuggestionsResponse(@NonNull java.util.List<android.view.inputmethod.InlineSuggestion>);
   }
 
+  public final class InputMethodInfo implements android.os.Parcelable {
+    ctor public InputMethodInfo(@NonNull String, @NonNull String, @NonNull CharSequence, @NonNull String, int);
+  }
+
   public final class InputMethodManager {
     method public int getDisplayId();
     method public boolean hasActiveInputConnection(@Nullable android.view.View);
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index b8735c7..2f3b50b 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -2551,9 +2551,9 @@
             false, // READ_MEDIA_AUDIO
             false, // WRITE_MEDIA_AUDIO
             false, // READ_MEDIA_VIDEO
-            false, // WRITE_MEDIA_VIDEO
+            true,  // WRITE_MEDIA_VIDEO
             false, // READ_MEDIA_IMAGES
-            false, // WRITE_MEDIA_IMAGES
+            true,  // WRITE_MEDIA_IMAGES
             true,  // LEGACY_STORAGE
             false, // ACCESS_ACCESSIBILITY
             false, // READ_DEVICE_IDENTIFIERS
diff --git a/core/java/android/app/BackgroundServiceStartNotAllowedException.java b/core/java/android/app/BackgroundServiceStartNotAllowedException.java
new file mode 100644
index 0000000..f6361b5
--- /dev/null
+++ b/core/java/android/app/BackgroundServiceStartNotAllowedException.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.app;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Exception thrown when an app tries to start a background {@link Service} when it's not allowed to
+ * do so.
+ */
+public final class BackgroundServiceStartNotAllowedException
+        extends ServiceStartNotAllowedException implements Parcelable {
+    /**
+     * Constructor.
+     */
+    public BackgroundServiceStartNotAllowedException(@NonNull String message) {
+        super(message);
+    }
+
+    BackgroundServiceStartNotAllowedException(@NonNull Parcel source) {
+        super(source.readString());
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString(getMessage());
+    }
+
+    public static final @NonNull Creator<android.app.BackgroundServiceStartNotAllowedException>
+            CREATOR = new Creator<android.app.BackgroundServiceStartNotAllowedException>() {
+                @NonNull
+                public android.app.BackgroundServiceStartNotAllowedException createFromParcel(
+                        Parcel source) {
+                    return new android.app.BackgroundServiceStartNotAllowedException(source);
+                }
+
+                @NonNull
+                public android.app.BackgroundServiceStartNotAllowedException[] newArray(int size) {
+                    return new android.app.BackgroundServiceStartNotAllowedException[size];
+                }
+            };
+}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 85fb543..bc79813 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1796,7 +1796,7 @@
                             "Unable to start service " + service
                             + ": " + cn.getClassName());
                 } else if (cn.getPackageName().equals("?")) {
-                    throw new IllegalStateException(
+                    throw ServiceStartNotAllowedException.newInstance(requireForeground,
                             "Not allowed to start service " + service + ": " + cn.getClassName());
                 }
             }
diff --git a/core/java/android/app/ForegroundServiceStartNotAllowedException.java b/core/java/android/app/ForegroundServiceStartNotAllowedException.java
new file mode 100644
index 0000000..41eeada2
--- /dev/null
+++ b/core/java/android/app/ForegroundServiceStartNotAllowedException.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.app;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Exception thrown when an app tries to start a foreground {@link Service} when it's not allowed to
+ * do so.
+ */
+public final class ForegroundServiceStartNotAllowedException
+        extends ServiceStartNotAllowedException implements Parcelable {
+    /**
+     * Constructor.
+     */
+    public ForegroundServiceStartNotAllowedException(@NonNull String message) {
+        super(message);
+    }
+
+    ForegroundServiceStartNotAllowedException(@NonNull Parcel source) {
+        super(source.readString());
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString(getMessage());
+    }
+
+    public static final @NonNull Creator<android.app.ForegroundServiceStartNotAllowedException>
+            CREATOR = new Creator<android.app.ForegroundServiceStartNotAllowedException>() {
+                @NonNull
+                public android.app.ForegroundServiceStartNotAllowedException createFromParcel(
+                        Parcel source) {
+                    return new android.app.ForegroundServiceStartNotAllowedException(source);
+                }
+
+                @NonNull
+                public android.app.ForegroundServiceStartNotAllowedException[] newArray(int size) {
+                    return new android.app.ForegroundServiceStartNotAllowedException[size];
+                }
+            };
+}
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index 3798de9..2ceea7f 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -697,7 +697,8 @@
      * service element of manifest file. The value of attribute
      * {@link android.R.attr#foregroundServiceType} can be multiple flags ORed together.</p>
      *
-     * @throws IllegalStateException If the app targeting API is
+     * @throws ForegroundServiceStartNotAllowedException
+     * If the app targeting API is
      * {@link android.os.Build.VERSION_CODES#S} or later, and the service is restricted from
      * becoming foreground service due to background restriction.
      *
@@ -738,8 +739,14 @@
    * @param notification The Notification to be displayed.
    * @param foregroundServiceType must be a subset flags of manifest attribute
    * {@link android.R.attr#foregroundServiceType} flags.
+   *
    * @throws IllegalArgumentException if param foregroundServiceType is not subset of manifest
    *     attribute {@link android.R.attr#foregroundServiceType}.
+   * @throws ForegroundServiceStartNotAllowedException
+   * If the app targeting API is
+   * {@link android.os.Build.VERSION_CODES#S} or later, and the service is restricted from
+   * becoming foreground service due to background restriction.
+   *
    * @see android.content.pm.ServiceInfo#FOREGROUND_SERVICE_TYPE_MANIFEST
    */
     public final void startForeground(int id, @NonNull Notification notification,
diff --git a/core/java/android/app/ServiceStartNotAllowedException.java b/core/java/android/app/ServiceStartNotAllowedException.java
new file mode 100644
index 0000000..33285b2
--- /dev/null
+++ b/core/java/android/app/ServiceStartNotAllowedException.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import android.annotation.NonNull;
+
+/**
+ * Exception thrown when an app tries to start a {@link Service} when it's not allowed to do so.
+ */
+public abstract class ServiceStartNotAllowedException extends IllegalStateException {
+    ServiceStartNotAllowedException(@NonNull String message) {
+        super(message);
+    }
+
+    /**
+     * Return either {@link ForegroundServiceStartNotAllowedException} or
+     * {@link BackgroundServiceStartNotAllowedException}
+     * @hide
+     */
+    @NonNull
+    public static ServiceStartNotAllowedException newInstance(boolean foreground,
+            @NonNull String message) {
+        if (foreground) {
+            return new ForegroundServiceStartNotAllowedException(message);
+        } else {
+            return new BackgroundServiceStartNotAllowedException(message);
+        }
+    }
+}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 4284dc2..e20f706 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3118,8 +3118,18 @@
      *
      * @throws SecurityException If the caller does not have permission to access the service
      * or the service can not be found.
-     * @throws IllegalStateException If the application is in a state where the service
-     * can not be started (such as not in the foreground in a state when services are allowed).
+     * @throws IllegalStateException
+     * Before Android {@link android.os.Build.VERSION_CODES#S},
+     * if the application is in a state where the service
+     * can not be started (such as not in the foreground in a state when services are allowed),
+     * {@link IllegalStateException} was thrown.
+     * @throws android.app.BackgroundServiceStartNotAllowedException
+     * On Android {@link android.os.Build.VERSION_CODES#S} and later,
+     * if the application is in a state where the service
+     * can not be started (such as not in the foreground in a state when services are allowed),
+     * {@link android.app.BackgroundServiceStartNotAllowedException} is thrown
+     * This excemption extends {@link IllegalStateException}, so apps can
+     * use {@code catch (IllegalStateException)} to catch both.
      *
      * @see #stopService
      * @see #bindService
@@ -3150,7 +3160,8 @@
      * @throws SecurityException If the caller does not have permission to access the service
      * or the service can not be found.
      *
-     * @throws IllegalStateException If the caller app's targeting API is
+     * @throws android.app.ForegroundServiceStartNotAllowedException
+     * If the caller app's targeting API is
      * {@link android.os.Build.VERSION_CODES#S} or later, and the foreground service is restricted
      * from start due to background restriction.
      *
diff --git a/core/java/android/inputmethodservice/IInputMethodWrapper.java b/core/java/android/inputmethodservice/IInputMethodWrapper.java
index 5cfcd66..9198eb7 100644
--- a/core/java/android/inputmethodservice/IInputMethodWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodWrapper.java
@@ -171,7 +171,7 @@
                 SomeArgs args = (SomeArgs) msg.obj;
                 try {
                     inputMethod.initializeInternal((IBinder) args.arg1, msg.arg1,
-                            (IInputMethodPrivilegedOperations) args.arg2);
+                            (IInputMethodPrivilegedOperations) args.arg2, (int) args.arg3);
                 } finally {
                     args.recycle();
                 }
@@ -280,9 +280,10 @@
     @BinderThread
     @Override
     public void initializeInternal(IBinder token, int displayId,
-            IInputMethodPrivilegedOperations privOps) {
+            IInputMethodPrivilegedOperations privOps, int configChanges) {
         mCaller.executeOrSendMessage(
-                mCaller.obtainMessageIOO(DO_INITIALIZE_INTERNAL, displayId, token, privOps));
+                mCaller.obtainMessageIOOO(DO_INITIALIZE_INTERNAL, displayId, token, privOps,
+                        configChanges));
     }
 
     @BinderThread
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 7e2be01..03dd306 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -70,6 +70,7 @@
 import android.compat.annotation.EnabledSince;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
+import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -131,6 +132,7 @@
 import android.window.WindowMetricsHelper;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.inputmethod.IInputContentUriToken;
 import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
 import com.android.internal.inputmethod.InputMethodPrivilegedOperations;
@@ -513,6 +515,8 @@
     private boolean mIsAutomotive;
     private Handler mHandler;
     private boolean mImeSurfaceScheduledForRemoval;
+    private Configuration mLastKnownConfig;
+    private int mHandledConfigChanges;
 
     /**
      * An opaque {@link Binder} token of window requesting {@link InputMethodImpl#showSoftInput}
@@ -588,12 +592,14 @@
         @MainThread
         @Override
         public final void initializeInternal(@NonNull IBinder token, int displayId,
-                IInputMethodPrivilegedOperations privilegedOperations) {
+                IInputMethodPrivilegedOperations privilegedOperations,
+                int configChanges) {
             if (InputMethodPrivilegedOperationsRegistry.isRegistered(token)) {
                 Log.w(TAG, "The token has already registered, ignore this initialization.");
                 return;
             }
             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.initializeInternal");
+            mHandledConfigChanges = configChanges;
             mPrivOps.set(privilegedOperations);
             InputMethodPrivilegedOperationsRegistry.put(token, mPrivOps);
             updateInputMethodDisplay(displayId);
@@ -821,6 +827,9 @@
                 setImeWindowStatus(mapToImeWindowStatus(), mBackDisposition);
             }
             final boolean isVisible = isInputViewShown();
+            if (isVisible && getResources() != null) {
+                mLastKnownConfig = getResources().getConfiguration();
+            }
             final boolean visibilityChanged = isVisible != wasVisible;
             if (resultReceiver != null) {
                 resultReceiver.send(visibilityChanged
@@ -1428,10 +1437,37 @@
      * state: {@link #onStartInput} if input is active, and
      * {@link #onCreateInputView} and {@link #onStartInputView} and related
      * appropriate functions if the UI is displayed.
+     * <p>Starting with {@link Build.VERSION_CODES#S}, IMEs can opt into handling configuration
+     * changes themselves instead of being restarted with
+     * {@link android.R.styleable#InputMethod_configChanges}.
      */
     @Override public void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
-        resetStateForNewConfiguration();
+        if (shouldImeRestartForConfig(newConfig)) {
+            resetStateForNewConfiguration();
+        }
+    }
+
+    /**
+     * @return {@code true} if {@link InputMethodService} needs to restart to handle
+     * .{@link #onConfigurationChanged(Configuration)}
+     */
+    @VisibleForTesting
+    boolean shouldImeRestartForConfig(@NonNull Configuration newConfig) {
+        if (mLastKnownConfig == null) {
+            return true;
+        }
+        // If the new config is the same as the config this Service is already running with,
+        // then don't bother calling resetStateForNewConfiguration.
+        int diff = mLastKnownConfig.diffPublicOnly(newConfig);
+        if (diff != 0) {
+            // remove attrs not-relevant to IME service.
+            diff &= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
+            diff &= ActivityInfo.CONFIG_KEYBOARD;
+            diff &= ActivityInfo.CONFIG_NAVIGATION;
+        }
+        int unhandledDiff = (diff & ~mHandledConfigChanges);
+        return unhandledDiff != 0;
     }
 
     private void resetStateForNewConfiguration() {
@@ -3181,7 +3217,17 @@
             requestHideSelf(InputMethodManager.HIDE_NOT_ALWAYS);
         }
     }
-    
+
+    @VisibleForTesting
+    void setLastKnownConfig(@NonNull Configuration config) {
+        mLastKnownConfig = config;
+    }
+
+    @VisibleForTesting
+    void setHandledConfigChanges(int configChanges) {
+        mHandledConfigChanges = configChanges;
+    }
+
     void startExtractingText(boolean inputChanged) {
         final ExtractEditText eet = mExtractEditText;
         if (eet != null && getCurrentInputStarted()
diff --git a/core/java/android/os/incremental/IncrementalFileStorages.java b/core/java/android/os/incremental/IncrementalFileStorages.java
index a078e04..73520e0 100644
--- a/core/java/android/os/incremental/IncrementalFileStorages.java
+++ b/core/java/android/os/incremental/IncrementalFileStorages.java
@@ -59,7 +59,6 @@
     /**
      * Set up files and directories used in an installation session. Only used by Incremental.
      * All the files will be created in defaultStorage.
-     * TODO(b/133435829): code clean up
      *
      * @throws IllegalStateException the session is not an Incremental installation session.
      * @throws IOException if fails to setup files or directories.
@@ -73,12 +72,10 @@
             @Nullable IStorageHealthListener healthListener,
             @NonNull List<InstallationFileParcel> addedFiles,
             @NonNull PerUidReadTimeouts[] perUidReadTimeouts,
-            IPackageLoadingProgressCallback progressCallback) throws IOException {
-        // TODO(b/136132412): validity check if session should not be incremental
+            @Nullable IPackageLoadingProgressCallback progressCallback) throws IOException {
         IncrementalManager incrementalManager = (IncrementalManager) context.getSystemService(
                 Context.INCREMENTAL_SERVICE);
         if (incrementalManager == null) {
-            // TODO(b/146080380): add incremental-specific error code
             throw new IOException("Failed to obtain incrementalManager.");
         }
 
@@ -89,7 +86,6 @@
                 try {
                     result.addApkFile(file);
                 } catch (IOException e) {
-                    // TODO(b/146080380): add incremental-specific error code
                     throw new IOException(
                             "Failed to add file to IncFS: " + file.name + ", reason: ", e);
                 }
@@ -203,7 +199,6 @@
 
     /**
      * Resets the states and unbinds storage instances for an installation session.
-     * TODO(b/136132412): make sure unnecessary binds are removed but useful storages are kept
      */
     public void cleanUp() {
         if (mDefaultStorage == null) {
@@ -211,8 +206,8 @@
         }
 
         try {
+            mIncrementalManager.unregisterLoadingProgressCallbacks(mStageDir.getAbsolutePath());
             mDefaultStorage.unBind(mStageDir.getAbsolutePath());
-            mDefaultStorage.unregisterLoadingProgressListener();
         } catch (IOException ignored) {
         }
         mDefaultStorage = null;
diff --git a/core/java/android/os/incremental/IncrementalManager.java b/core/java/android/os/incremental/IncrementalManager.java
index 0589994..cec6a1f 100644
--- a/core/java/android/os/incremental/IncrementalManager.java
+++ b/core/java/android/os/incremental/IncrementalManager.java
@@ -342,7 +342,6 @@
             storage.unregisterLoadingProgressListener();
         }
 
-        // TODO(b/165841827): handle reboot and app update
         public boolean registerCallback(@NonNull IncrementalStorage storage,
                 @NonNull IPackageLoadingProgressCallback callback) {
             final int storageId = storage.getId();
@@ -364,30 +363,6 @@
             return storage.registerLoadingProgressListener(this);
         }
 
-        public boolean unregisterCallback(@NonNull IncrementalStorage storage,
-                @NonNull IPackageLoadingProgressCallback callback) {
-            final int storageId = storage.getId();
-            final RemoteCallbackList<IPackageLoadingProgressCallback> callbacksForStorage;
-            synchronized (mCallbacks) {
-                callbacksForStorage = mCallbacks.get(storageId);
-                if (callbacksForStorage == null) {
-                    // no callback has ever been registered on this storage
-                    return false;
-                }
-                if (!callbacksForStorage.unregister(callback)) {
-                    // the callback was not registered
-                    return false;
-                }
-                if (callbacksForStorage.getRegisteredCallbackCount() > 0) {
-                    // other callbacks are still listening on this storage
-                    return true;
-                }
-                mCallbacks.delete(storageId);
-            }
-            // stop listening for this storage
-            return storage.unregisterLoadingProgressListener();
-        }
-
         @Override
         public void onStorageLoadingProgressChanged(int storageId, float progress) {
             final RemoteCallbackList<IPackageLoadingProgressCallback> callbacksForStorage;
diff --git a/core/java/android/view/inputmethod/InputMethod.java b/core/java/android/view/inputmethod/InputMethod.java
index de4554b..6ade5e6 100644
--- a/core/java/android/view/inputmethod/InputMethod.java
+++ b/core/java/android/view/inputmethod/InputMethod.java
@@ -105,7 +105,7 @@
      */
     @MainThread
     default void initializeInternal(IBinder token, int displayId,
-            IInputMethodPrivilegedOperations privilegedOperations) {
+            IInputMethodPrivilegedOperations privilegedOperations, int configChanges) {
         updateInputMethodDisplay(displayId);
         attachToken(token);
     }
diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java
index 5d876a6..25712f8 100644
--- a/core/java/android/view/inputmethod/InputMethodInfo.java
+++ b/core/java/android/view/inputmethod/InputMethodInfo.java
@@ -18,19 +18,23 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.TestApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.content.res.Resources.NotFoundException;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
 import android.graphics.drawable.Drawable;
+import android.inputmethodservice.InputMethodService;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.AttributeSet;
@@ -60,6 +64,7 @@
  * @attr ref android.R.styleable#InputMethod_isDefault
  * @attr ref android.R.styleable#InputMethod_supportsSwitchingToNextInputMethod
  * @attr ref android.R.styleable#InputMethod_supportsInlineSuggestions
+ * @attr ref android.R.styleable#InputMethod_configChanges
  */
 public final class InputMethodInfo implements Parcelable {
     static final String TAG = "InputMethodInfo";
@@ -118,6 +123,12 @@
     private final boolean mInlineSuggestionsEnabled;
 
     /**
+     * The flag for configurations IME assumes the responsibility for handling in
+     * {@link InputMethodService#onConfigurationChanged(Configuration)}}.
+     */
+    private final int mHandledConfigChanges;
+
+    /**
      * @param service the {@link ResolveInfo} corresponds in which the IME is implemented.
      * @return a unique ID to be returned by {@link #getId()}. We have used
      *         {@link ComponentName#flattenToShortString()} for this purpose (and it is already
@@ -203,6 +214,8 @@
                     false);
             inlineSuggestionsEnabled = sa.getBoolean(
                     com.android.internal.R.styleable.InputMethod_supportsInlineSuggestions, false);
+            mHandledConfigChanges = sa.getInt(
+                    com.android.internal.R.styleable.InputMethod_configChanges, 0);
             sa.recycle();
 
             final int depth = parser.getDepth();
@@ -287,6 +300,7 @@
         mIsVrOnly = source.readBoolean();
         mService = ResolveInfo.CREATOR.createFromParcel(source);
         mSubtypes = new InputMethodSubtypeArray(source);
+        mHandledConfigChanges = source.readInt();
         mForceDefault = false;
     }
 
@@ -298,7 +312,22 @@
         this(buildFakeResolveInfo(packageName, className, label), false /* isAuxIme */,
                 settingsActivity, null /* subtypes */, 0 /* isDefaultResId */,
                 false /* forceDefault */, true /* supportsSwitchingToNextInputMethod */,
-                false /* inlineSuggestionsEnabled */, false /* isVrOnly */);
+                false /* inlineSuggestionsEnabled */, false /* isVrOnly */,
+                0 /* handledConfigChanges */);
+    }
+
+    /**
+     * Temporary API for creating a built-in input method for test.
+     * @hide
+     */
+    @TestApi
+    public InputMethodInfo(@NonNull String packageName, @NonNull String className,
+            @NonNull CharSequence label, @NonNull String settingsActivity,
+            int handledConfigChanges) {
+        this(buildFakeResolveInfo(packageName, className, label), false /* isAuxIme */,
+                settingsActivity, null /* subtypes */, 0 /* isDefaultResId */,
+                false /* forceDefault */, true /* supportsSwitchingToNextInputMethod */,
+                false /* inlineSuggestionsEnabled */, false /* isVrOnly */, handledConfigChanges);
     }
 
     /**
@@ -310,7 +339,7 @@
             boolean forceDefault) {
         this(ri, isAuxIme, settingsActivity, subtypes, isDefaultResId, forceDefault,
                 true /* supportsSwitchingToNextInputMethod */, false /* inlineSuggestionsEnabled */,
-                false /* isVrOnly */);
+                false /* isVrOnly */, 0 /* handledconfigChanges */);
     }
 
     /**
@@ -321,7 +350,8 @@
             List<InputMethodSubtype> subtypes, int isDefaultResId, boolean forceDefault,
             boolean supportsSwitchingToNextInputMethod, boolean isVrOnly) {
         this(ri, isAuxIme, settingsActivity, subtypes, isDefaultResId, forceDefault,
-                supportsSwitchingToNextInputMethod, false /* inlineSuggestionsEnabled */, isVrOnly);
+                supportsSwitchingToNextInputMethod, false /* inlineSuggestionsEnabled */, isVrOnly,
+                0 /* handledConfigChanges */);
     }
 
     /**
@@ -331,7 +361,7 @@
     public InputMethodInfo(ResolveInfo ri, boolean isAuxIme, String settingsActivity,
             List<InputMethodSubtype> subtypes, int isDefaultResId, boolean forceDefault,
             boolean supportsSwitchingToNextInputMethod, boolean inlineSuggestionsEnabled,
-            boolean isVrOnly) {
+            boolean isVrOnly, int handledConfigChanges) {
         final ServiceInfo si = ri.serviceInfo;
         mService = ri;
         mId = new ComponentName(si.packageName, si.name).flattenToShortString();
@@ -343,6 +373,7 @@
         mSupportsSwitchingToNextInputMethod = supportsSwitchingToNextInputMethod;
         mInlineSuggestionsEnabled = inlineSuggestionsEnabled;
         mIsVrOnly = isVrOnly;
+        mHandledConfigChanges = handledConfigChanges;
     }
 
     private static ResolveInfo buildFakeResolveInfo(String packageName, String className,
@@ -489,6 +520,17 @@
         }
     }
 
+    /**
+     * Returns the bit mask of kinds of configuration changes that this IME
+     * can handle itself (without being restarted by the system).
+     *
+     * @attr ref android.R.styleable#InputMethod_configChanges
+     */
+    @ActivityInfo.Config
+    public int getConfigChanges() {
+        return mHandledConfigChanges;
+    }
+
     public void dump(Printer pw, String prefix) {
         pw.println(prefix + "mId=" + mId
                 + " mSettingsActivityName=" + mSettingsActivityName
@@ -579,6 +621,7 @@
         dest.writeBoolean(mIsVrOnly);
         mService.writeToParcel(dest, flags);
         mSubtypes.writeToParcel(dest);
+        dest.writeInt(mHandledConfigChanges);
     }
 
     /**
diff --git a/core/java/com/android/internal/view/IInputMethod.aidl b/core/java/com/android/internal/view/IInputMethod.aidl
index c336373..8d82e33 100644
--- a/core/java/com/android/internal/view/IInputMethod.aidl
+++ b/core/java/com/android/internal/view/IInputMethod.aidl
@@ -35,7 +35,8 @@
  * {@hide}
  */
 oneway interface IInputMethod {
-    void initializeInternal(IBinder token, int displayId, IInputMethodPrivilegedOperations privOps);
+    void initializeInternal(IBinder token, int displayId, IInputMethodPrivilegedOperations privOps,
+             int configChanges);
 
     void onCreateInlineSuggestionsRequest(in InlineSuggestionsRequestInfo requestInfo,
             in IInlineSuggestionsRequestCallback cb);
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 69bb20c..99f58ee 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3564,6 +3564,16 @@
         <attr name="__removed2" format="boolean" />
         <!-- Specifies whether the IME supports showing inline suggestions. -->
         <attr name="supportsInlineSuggestions" format="boolean" />
+        <!-- Specify one or more configuration changes that the IME will handle itself. If not
+             specified, the IME will be restarted if any of these configuration changes happen in
+              the system.  Otherwise, the IME will remain running and its
+             {@link android.inputmethodservice.InputMethodService#onConfigurationChanged}
+             method is called with the new configuration.
+             <p>Note that all of these configuration changes can impact the
+             resource values seen by the application, so you will generally need
+             to re-retrieve all resources (including view layouts, drawables, etc)
+             to correctly handle any configuration change.-->
+        <attr name="configChanges" />
     </declare-styleable>
 
     <!-- This is the subtype of InputMethod. Subtype can describe locales (for example, en_US and
diff --git a/core/tests/coretests/src/android/inputmethodservice/InputMethodServiceTest.java b/core/tests/coretests/src/android/inputmethodservice/InputMethodServiceTest.java
new file mode 100644
index 0000000..8906149
--- /dev/null
+++ b/core/tests/coretests/src/android/inputmethodservice/InputMethodServiceTest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2021 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.inputmethodservice;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+
+import static junit.framework.Assert.assertFalse;
+
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
+import android.os.Build;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.rule.ServiceTestRule;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.TimeoutException;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class InputMethodServiceTest {
+    private InputMethodService mService;
+    private Context mContext;
+    @Rule
+    public final ServiceTestRule serviceRule = new ServiceTestRule();
+
+    @Before
+    public void setUp() throws TimeoutException {
+        mContext = getInstrumentation().getContext();
+        mService = new InputMethodService();
+    }
+
+    @Test
+    public void testShouldImeRestartForConfig() throws Exception {
+        // Make sure we preserve Pre-S behavior i.e. Service restarts.
+        mContext.getApplicationInfo().targetSdkVersion = Build.VERSION_CODES.R;
+        Configuration config = mContext.getResources().getConfiguration();
+        mService.setLastKnownConfig(config);
+        assertTrue("IME should restart for Pre-S",
+                mService.shouldImeRestartForConfig(config));
+
+        // IME shouldn't restart on targetSdk S+ (with no config changes).
+        mContext.getApplicationInfo().targetSdkVersion = Build.VERSION_CODES.S;
+        assertFalse("IME shouldn't restart for S+",
+                mService.shouldImeRestartForConfig(config));
+
+        // Screen density changed but IME doesn't handle congfigChanges
+        config.densityDpi = 99;
+        assertTrue("IME should restart for unhandled configChanges",
+                mService.shouldImeRestartForConfig(config));
+
+        // opt-in IME to handle config changes.
+        mService.setHandledConfigChanges(ActivityInfo.CONFIG_DENSITY);
+        assertFalse("IME shouldn't restart for S+ since it handles configChanges",
+                mService.shouldImeRestartForConfig(config));
+    }
+}
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index 6e458681..be49e1f 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -170,7 +170,6 @@
 
     <declare-styleable name="AlphaTintDrawableWrapper">
         <attr name="android:tint" />
-        <attr name="android:drawable" />
         <attr name="android:alpha" />
     </declare-styleable>
 
@@ -191,9 +190,5 @@
         <attr name="borderThickness" format="dimension" />
         <attr name="borderColor" format="color" />
     </declare-styleable>
-
-    <declare-styleable name="RoundedCornerProgressDrawable">
-        <attr name="android:drawable" />
-    </declare-styleable>
 </resources>
 
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetEnabler.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetEnabler.java
index b188acb..3df2644 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetEnabler.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetEnabler.java
@@ -23,6 +23,7 @@
 
 import com.android.systemui.SystemUI;
 import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.people.PeopleSpaceActivity;
 import com.android.systemui.statusbar.FeatureFlags;
 
 import javax.inject.Inject;
@@ -54,6 +55,12 @@
                             ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
                             : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                     PackageManager.DONT_KILL_APP);
+            mContext.getPackageManager().setComponentEnabledSetting(
+                    new ComponentName(mContext, PeopleSpaceActivity.class),
+                    showPeopleSpace
+                            ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
+                            : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+                    PackageManager.DONT_KILL_APP);
         } catch (Exception e) {
             Log.w(TAG, "Error enabling People Space widget:", e);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSlider.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSlider.java
index a6aec3b..0b40e22 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSlider.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSlider.java
@@ -17,8 +17,6 @@
 package com.android.systemui.settings.brightness;
 
 import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.LayerDrawable;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
@@ -29,10 +27,8 @@
 import androidx.annotation.Nullable;
 
 import com.android.settingslib.RestrictedLockUtils;
-import com.android.settingslib.Utils;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.policy.BrightnessMirrorController;
-import com.android.systemui.util.RoundedCornerProgressDrawable;
 import com.android.systemui.util.ViewController;
 
 import javax.inject.Inject;
@@ -274,9 +270,6 @@
         private BrightnessSlider fromTree(ViewGroup root, boolean useMirror) {
             BrightnessSliderView v = root.requireViewById(R.id.brightness_slider);
 
-            // TODO(175026098) Workaround. Remove when b/175026098 is fixed
-            applyTheme(v);
-
             return new BrightnessSlider(root, v, useMirror);
         }
 
@@ -286,32 +279,5 @@
                     ? R.layout.quick_settings_brightness_dialog_thick
                     : R.layout.quick_settings_brightness_dialog;
         }
-
-        private LayerDrawable findProgressClippableDrawable(BrightnessSliderView v) {
-            SeekBar b = v.requireViewById(R.id.slider);
-            if (b.getProgressDrawable() instanceof LayerDrawable) {
-                Drawable progress = ((LayerDrawable) b.getProgressDrawable())
-                        .findDrawableByLayerId(com.android.internal.R.id.progress);
-                if (progress instanceof RoundedCornerProgressDrawable) {
-                    Drawable inner = ((RoundedCornerProgressDrawable) progress).getDrawable();
-                    if (inner instanceof LayerDrawable) {
-                        return (LayerDrawable) inner;
-                    }
-                }
-            }
-            return null;
-        }
-
-        private void applyTheme(BrightnessSliderView v) {
-            LayerDrawable layer = findProgressClippableDrawable(v);
-            if (layer != null) {
-                layer.findDrawableByLayerId(R.id.slider_foreground).setTintList(
-                        Utils.getColorAttr(v.getContext(),
-                                com.android.internal.R.attr.colorControlActivated));
-                layer.findDrawableByLayerId(R.id.slider_icon).setTintList(
-                        Utils.getColorAttr(v.getContext(),
-                                com.android.internal.R.attr.colorBackground));
-            }
-        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/util/AlphaTintDrawableWrapper.java b/packages/SystemUI/src/com/android/systemui/util/AlphaTintDrawableWrapper.java
index 79a197d..a22793b 100644
--- a/packages/SystemUI/src/com/android/systemui/util/AlphaTintDrawableWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/util/AlphaTintDrawableWrapper.java
@@ -16,15 +16,18 @@
 
 package com.android.systemui.util;
 
-import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
 import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
 import android.graphics.drawable.DrawableWrapper;
+import android.graphics.drawable.InsetDrawable;
 import android.util.AttributeSet;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
 import com.android.systemui.R;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -45,13 +48,18 @@
  * @attr ref R.styleable#AlphaTintDrawableWrapper_tint
  * @attr ref R.styleable#AlphaTintDrawableWrapper_alpha
  */
-public class AlphaTintDrawableWrapper extends DrawableWrapper {
+public class AlphaTintDrawableWrapper extends InsetDrawable {
     private ColorStateList mTint;
     private int[] mThemeAttrs;
 
     /** No-arg constructor used by drawable inflation. */
     public AlphaTintDrawableWrapper() {
-        super(null);
+        super(null, 0);
+    }
+
+    AlphaTintDrawableWrapper(Drawable drawable, int[] themeAttrs) {
+        super(drawable, 0);
+        mThemeAttrs = themeAttrs;
     }
 
     @Override
@@ -74,7 +82,7 @@
     public void applyTheme(Theme t) {
         super.applyTheme(t);
 
-        if (mThemeAttrs != null) {
+        if (mThemeAttrs != null && t != null) {
             final TypedArray a = t.resolveAttributes(mThemeAttrs,
                     R.styleable.AlphaTintDrawableWrapper);
             updateStateFromTypedArray(a);
@@ -92,9 +100,6 @@
     }
 
     private void updateStateFromTypedArray(@NonNull TypedArray a) {
-        if (a.hasValue(R.styleable.AlphaTintDrawableWrapper_android_drawable)) {
-            setDrawable(a.getDrawable(R.styleable.AlphaTintDrawableWrapper_android_drawable));
-        }
         if (a.hasValue(R.styleable.AlphaTintDrawableWrapper_android_tint)) {
             mTint = a.getColorStateList(R.styleable.AlphaTintDrawableWrapper_android_tint);
         }
@@ -109,4 +114,57 @@
             getDrawable().mutate().setTintList(mTint);
         }
     }
+
+    @Nullable
+    @Override
+    public ConstantState getConstantState() {
+        return new AlphaTintState(super.getConstantState(), mThemeAttrs, getAlpha(), mTint);
+    }
+
+    static class AlphaTintState extends Drawable.ConstantState {
+
+        private ConstantState mWrappedState;
+        private int[] mThemeAttrs;
+        private int mAlpha;
+        private ColorStateList mColorStateList;
+
+        AlphaTintState(
+                ConstantState wrappedState,
+                int[] themeAttrs,
+                int alpha,
+                ColorStateList colorStateList
+        ) {
+            mWrappedState = wrappedState;
+            mThemeAttrs = themeAttrs;
+            mAlpha = alpha;
+            mColorStateList = colorStateList;
+        }
+
+        @NonNull
+        @Override
+        public Drawable newDrawable() {
+            return newDrawable(null, null);
+        }
+
+        @NonNull
+        @Override
+        public Drawable newDrawable(Resources res, Theme theme) {
+            DrawableWrapper wrapper = (DrawableWrapper) mWrappedState.newDrawable(res, theme);
+            AlphaTintDrawableWrapper alphaTintDrawableWrapper =
+                    new AlphaTintDrawableWrapper(wrapper.getDrawable(), mThemeAttrs);
+            alphaTintDrawableWrapper.setTintList(mColorStateList);
+            alphaTintDrawableWrapper.setAlpha(mAlpha);
+            return alphaTintDrawableWrapper;
+        }
+
+        @Override
+        public boolean canApplyTheme() {
+            return true;
+        }
+
+        @Override
+        public int getChangingConfigurations() {
+            return mWrappedState.getChangingConfigurations();
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/util/RoundedCornerProgressDrawable.kt b/packages/SystemUI/src/com/android/systemui/util/RoundedCornerProgressDrawable.kt
index 1af2c9f..6aadd10 100644
--- a/packages/SystemUI/src/com/android/systemui/util/RoundedCornerProgressDrawable.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/RoundedCornerProgressDrawable.kt
@@ -17,15 +17,12 @@
 package com.android.systemui.util
 
 import android.content.res.Resources
-import android.content.res.TypedArray
 import android.graphics.Canvas
 import android.graphics.Path
 import android.graphics.Rect
 import android.graphics.drawable.Drawable
 import android.graphics.drawable.DrawableWrapper
-import android.util.AttributeSet
-import com.android.systemui.R
-import org.xmlpull.v1.XmlPullParser
+import android.graphics.drawable.InsetDrawable
 
 /**
  * [DrawableWrapper] to use in the progress of a slider.
@@ -38,9 +35,9 @@
  * is meant to be smaller than the rounded corner. The background should have rounded corners that
  * are half of the height.
  */
-class RoundedCornerProgressDrawable(drawable: Drawable?) : DrawableWrapper(drawable) {
-
-    constructor() : this(null)
+class RoundedCornerProgressDrawable @JvmOverloads constructor(
+    drawable: Drawable? = null
+) : InsetDrawable(drawable, 0) {
 
     companion object {
         private const val MAX_LEVEL = 10000 // Taken from Drawable
@@ -52,35 +49,11 @@
         setClipPath(Rect())
     }
 
-    override fun inflate(
-        r: Resources,
-        parser: XmlPullParser,
-        attrs: AttributeSet,
-        theme: Resources.Theme?
-    ) {
-        val a = obtainAttributes(r, theme, attrs, R.styleable.RoundedCornerProgressDrawable)
-
-        // Inflation will advance the XmlPullParser and AttributeSet.
-        super.inflate(r, parser, attrs, theme)
-
-        updateStateFromTypedArray(a)
-        if (drawable == null) {
-            throw IllegalStateException("${this::class.java.simpleName} needs a drawable")
-        }
-        a.recycle()
-    }
-
     override fun onLayoutDirectionChanged(layoutDirection: Int): Boolean {
         onLevelChange(level)
         return super.onLayoutDirectionChanged(layoutDirection)
     }
 
-    private fun updateStateFromTypedArray(a: TypedArray) {
-        if (a.hasValue(R.styleable.RoundedCornerProgressDrawable_android_drawable)) {
-            setDrawable(a.getDrawable(R.styleable.RoundedCornerProgressDrawable_android_drawable))
-        }
-    }
-
     override fun onBoundsChange(bounds: Rect) {
         setClipPath(bounds)
         super.onBoundsChange(bounds)
@@ -115,4 +88,24 @@
         super.draw(canvas)
         canvas.restore()
     }
+
+    override fun getConstantState(): ConstantState? {
+        // This should not be null as it was created with a state in the constructor.
+        return RoundedCornerState(super.getConstantState()!!)
+    }
+
+    private class RoundedCornerState(private val wrappedState: ConstantState) : ConstantState() {
+        override fun newDrawable(): Drawable {
+            return newDrawable(null, null)
+        }
+
+        override fun newDrawable(res: Resources?, theme: Resources.Theme?): Drawable {
+            val wrapper = wrappedState.newDrawable(res, theme) as DrawableWrapper
+            return RoundedCornerProgressDrawable(wrapper.drawable)
+        }
+
+        override fun getChangingConfigurations(): Int {
+            return wrappedState.changingConfigurations
+        }
+    }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java b/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java
index 06806d0..6a648bd 100644
--- a/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java
+++ b/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java
@@ -347,6 +347,7 @@
         public void check(long timeoutMs, Consumer<Boolean> callback) {
             if (!mSensor.isLoaded()) {
                 callback.accept(null);
+                return;
             }
             mCallbacks.add(callback);
             if (!mRegistered.getAndSet(true)) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximityCheckTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximityCheckTest.java
index c5a197e..242fe9f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximityCheckTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximityCheckTest.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.util.sensors;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
@@ -86,6 +88,29 @@
     }
 
     @Test
+    public void testNotLoaded() {
+        mFakeProximitySensor.setSensorAvailable(false);
+
+        assertThat(mTestableCallback.mLastResult).isNull();
+        assertThat(mTestableCallback.mNumCalls).isEqualTo(0);
+
+        mProximityCheck.check(100, mTestableCallback);
+
+        assertThat(mTestableCallback.mLastResult).isNull();
+        assertThat(mTestableCallback.mNumCalls).isEqualTo(1);
+
+        mFakeProximitySensor.setSensorAvailable(true);
+
+        mProximityCheck.check(100, mTestableCallback);
+
+        mFakeProximitySensor.setLastEvent(new ProximitySensor.ThresholdSensorEvent(true, 0));
+        mFakeProximitySensor.alertListeners();
+
+        assertThat(mTestableCallback.mLastResult).isNotNull();
+        assertThat(mTestableCallback.mNumCalls).isEqualTo(2);
+    }
+
+    @Test
     public void testProxDoesntCancelOthers() {
         assertFalse(mFakeProximitySensor.isRegistered());
         // We don't need our "other" listener to do anything. Just ensure our sensor is registered.
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 5550999..2efc83c 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -52,6 +52,7 @@
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
 import android.app.BroadcastOptions;
+import android.app.ForegroundServiceStartNotAllowedException;
 import android.app.IApplicationThread;
 import android.app.IServiceConnection;
 import android.app.Notification;
@@ -693,7 +694,7 @@
                             + "could not resolve client package " + callingPackage);
                 }
                 if (CompatChanges.isChangeEnabled(FGS_START_EXCEPTION_CHANGE_ID, aInfo.uid)) {
-                    throw new IllegalStateException(msg);
+                    throw new ForegroundServiceStartNotAllowedException(msg);
                 }
                 return null;
             }
@@ -1778,7 +1779,7 @@
                         ignoreForeground = true;
                         if (CompatChanges.isChangeEnabled(FGS_START_EXCEPTION_CHANGE_ID,
                                 r.appInfo.uid)) {
-                            throw new IllegalStateException(msg);
+                            throw new ForegroundServiceStartNotAllowedException(msg);
                         }
                     }
                 }
diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java
index cd17cfe..b3070b7 100644
--- a/services/core/java/com/android/server/display/DisplayDevice.java
+++ b/services/core/java/com/android/server/display/DisplayDevice.java
@@ -16,6 +16,7 @@
 
 package com.android.server.display;
 
+import android.content.Context;
 import android.graphics.Rect;
 import android.hardware.display.DisplayViewport;
 import android.os.IBinder;
@@ -38,12 +39,14 @@
     private final IBinder mDisplayToken;
     private final String mUniqueId;
 
+    protected DisplayDeviceConfig mDisplayDeviceConfig;
     // The display device does not manage these properties itself, they are set by
     // the display manager service.  The display device shouldn't really be looking at these.
     private int mCurrentLayerStack = -1;
     private int mCurrentOrientation = -1;
     private Rect mCurrentLayerStackRect;
     private Rect mCurrentDisplayRect;
+    private final Context mContext;
 
     // The display device owns its surface, but it should only set it
     // within a transaction from performTraversalLocked.
@@ -53,10 +56,13 @@
     // Do not use for any other purpose.
     DisplayDeviceInfo mDebugLastLoggedDeviceInfo;
 
-    public DisplayDevice(DisplayAdapter displayAdapter, IBinder displayToken, String uniqueId) {
+    public DisplayDevice(DisplayAdapter displayAdapter, IBinder displayToken, String uniqueId,
+            Context context) {
         mDisplayAdapter = displayAdapter;
         mDisplayToken = displayToken;
         mUniqueId = uniqueId;
+        mDisplayDeviceConfig = null;
+        mContext = context;
     }
 
     /**
@@ -74,7 +80,10 @@
      * @return The DisplayDeviceConfig; {@code null} if not overridden.
      */
     public DisplayDeviceConfig getDisplayDeviceConfig() {
-        return null;
+        if (mDisplayDeviceConfig == null) {
+            mDisplayDeviceConfig = loadDisplayDeviceConfig();
+        }
+        return mDisplayDeviceConfig;
     }
 
     /**
@@ -292,4 +301,8 @@
         pw.println("mCurrentDisplayRect=" + mCurrentDisplayRect);
         pw.println("mCurrentSurface=" + mCurrentSurface);
     }
+
+    private DisplayDeviceConfig loadDisplayDeviceConfig() {
+        return DisplayDeviceConfig.create(mContext, false);
+    }
 }
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index 1b25427..49328f1 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -120,7 +120,20 @@
         // If no config can be loaded from any ddc xml at all,
         // prepare a whole config using the global config.xml.
         // Guaranteed not null
-        if (isDefaultDisplay) {
+        return create(context, isDefaultDisplay);
+    }
+
+    /**
+     * Creates an instance using global values since no display device config xml exists.
+     * Uses values from config or PowerManager.
+     *
+     * @param context
+     * @param useConfigXml
+     * @return A configuration instance.
+     */
+    public static DisplayDeviceConfig create(Context context, boolean useConfigXml) {
+        DisplayDeviceConfig config;
+        if (useConfigXml) {
             config = getConfigFromGlobalXml(context);
         } else {
             config = getConfigFromPmValues(context);
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index ed01044..a4e2c70 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -40,7 +40,6 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.display.BrightnessSynchronizer;
-import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.LocalServices;
 import com.android.server.lights.LightsManager;
@@ -213,7 +212,6 @@
         private SurfaceControl.DisplayMode mActiveSfDisplayMode;
         private Spline mSystemBrightnessToNits;
         private Spline mNitsToHalBrightness;
-        private DisplayDeviceConfig mDisplayDeviceConfig;
 
         private DisplayEventReceiver.FrameRateOverride[] mFrameRateOverrides =
                 new DisplayEventReceiver.FrameRateOverride[0];
@@ -222,7 +220,8 @@
                 SurfaceControl.StaticDisplayInfo staticDisplayInfo,
                 SurfaceControl.DynamicDisplayInfo dynamicInfo,
                 SurfaceControl.DesiredDisplayModeSpecs modeSpecs, boolean isDefaultDisplay) {
-            super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + physicalDisplayId);
+            super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + physicalDisplayId,
+                    getContext());
             mPhysicalDisplayId = physicalDisplayId;
             mIsDefaultDisplay = isDefaultDisplay;
             updateDisplayPropertiesLocked(staticDisplayInfo, dynamicInfo, modeSpecs);
@@ -232,9 +231,6 @@
             mAllmSupported = SurfaceControl.getAutoLowLatencyModeSupport(displayToken);
             mGameContentTypeSupported = SurfaceControl.getGameContentTypeSupport(displayToken);
             mDisplayDeviceConfig = null;
-            // Defer configuration file loading
-            BackgroundThread.getHandler().sendMessage(PooledLambda.obtainMessage(
-                    LocalDisplayDevice::loadDisplayConfiguration, this));
         }
 
         @Override
@@ -413,6 +409,9 @@
 
         @Override
         public DisplayDeviceConfig getDisplayDeviceConfig() {
+            if (mDisplayDeviceConfig == null) {
+                loadDisplayConfiguration();
+            }
             return mDisplayDeviceConfig;
         }
 
diff --git a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
index 69943e3..330379c 100644
--- a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
@@ -281,7 +281,8 @@
                 List<OverlayMode> modes, int activeMode, int defaultMode,
                 float refreshRate, long presentationDeadlineNanos,
                 OverlayFlags flags, int state, SurfaceTexture surfaceTexture, int number) {
-            super(OverlayDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + number);
+            super(OverlayDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + number,
+                    getContext());
             mName = name;
             mRefreshRate = refreshRate;
             mDisplayPresentationDeadlineNanos = presentationDeadlineNanos;
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index ff4717b..52a810b 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -236,7 +236,7 @@
                 int ownerUid, String ownerPackageName, Surface surface, int flags,
                 Callback callback, String uniqueId, int uniqueIndex,
                 VirtualDisplayConfig virtualDisplayConfig) {
-            super(VirtualDisplayAdapter.this, displayToken, uniqueId);
+            super(VirtualDisplayAdapter.this, displayToken, uniqueId, getContext());
             mAppToken = appToken;
             mOwnerUid = ownerUid;
             mOwnerPackageName = ownerPackageName;
diff --git a/services/core/java/com/android/server/display/WifiDisplayAdapter.java b/services/core/java/com/android/server/display/WifiDisplayAdapter.java
index 5732317..d2baaf22 100644
--- a/services/core/java/com/android/server/display/WifiDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/WifiDisplayAdapter.java
@@ -598,7 +598,8 @@
         public WifiDisplayDevice(IBinder displayToken, String name,
                 int width, int height, float refreshRate, int flags, String address,
                 Surface surface) {
-            super(WifiDisplayAdapter.this, displayToken, DISPLAY_NAME_PREFIX + address);
+            super(WifiDisplayAdapter.this, displayToken, DISPLAY_NAME_PREFIX + address,
+                    getContext());
             mName = name;
             mWidth = width;
             mHeight = height;
diff --git a/services/core/java/com/android/server/hdmi/DeviceSelectAction.java b/services/core/java/com/android/server/hdmi/DeviceSelectAction.java
index 86a8e36..983b6b5 100644
--- a/services/core/java/com/android/server/hdmi/DeviceSelectAction.java
+++ b/services/core/java/com/android/server/hdmi/DeviceSelectAction.java
@@ -100,9 +100,9 @@
 
     @Override
     public boolean start() {
-        if (mIsCec20) {
-            sendSetStreamPath();
-        }
+      // Wake-up on <Set Stream Path> was not mandatory before CEC 2.0.
+      // The message is re-sent at the end of the action for devices that don't support 2.0.
+      sendSetStreamPath();
         int targetPowerStatus = localDevice().mService.getHdmiCecNetwork()
                 .getCecDeviceInfo(getTargetAddress()).getDevicePowerStatus();
         if (!mIsCec20 || targetPowerStatus == HdmiControlManager.POWER_STATUS_UNKNOWN) {
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 0754df0..1e66589 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -2620,8 +2620,9 @@
                 }
                 if (DEBUG) Slog.v(TAG, "Initiating attach with token: " + mCurToken);
                 // Dispatch display id for InputMethodService to update context display.
-                executeOrSendMessage(mCurMethod, mCaller.obtainMessageIOO(
-                        MSG_INITIALIZE_IME, mCurTokenDisplayId, mCurMethod, mCurToken));
+                executeOrSendMessage(mCurMethod, mCaller.obtainMessageIOOO(
+                        MSG_INITIALIZE_IME, mCurTokenDisplayId, mCurMethod, mCurToken,
+                        mMethodMap.get(mCurMethodId).getConfigChanges()));
                 scheduleNotifyImeUidToAudioService(mCurMethodUid);
                 if (mCurClient != null) {
                     clearClientSessionLocked(mCurClient);
@@ -4466,7 +4467,8 @@
                     }
                     final IBinder token = (IBinder) args.arg2;
                     ((IInputMethod) args.arg1).initializeInternal(token, msg.arg1,
-                            new InputMethodPrivilegedOperationsImpl(this, token));
+                            new InputMethodPrivilegedOperationsImpl(this, token),
+                            (int) args.arg3);
                 } catch (RemoteException e) {
                 }
                 args.recycle();
diff --git a/services/core/java/com/android/server/notification/SnoozeHelper.java b/services/core/java/com/android/server/notification/SnoozeHelper.java
index f078242..4500bbc 100644
--- a/services/core/java/com/android/server/notification/SnoozeHelper.java
+++ b/services/core/java/com/android/server/notification/SnoozeHelper.java
@@ -39,6 +39,7 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.internal.util.XmlUtils;
+import com.android.server.pm.PackageManagerService;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -465,6 +466,7 @@
         return PendingIntent.getBroadcast(mContext,
                 REQUEST_CODE_REPOST,
                 new Intent(REPOST_ACTION)
+                        .setPackage(PackageManagerService.PLATFORM_PACKAGE_NAME)
                         .setData(new Uri.Builder().scheme(REPOST_SCHEME).appendPath(key).build())
                         .addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
                         .putExtra(EXTRA_KEY, key)
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 9e2ca9d..7bf3c5c 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -1207,8 +1207,13 @@
 
     @GuardedBy("mLock")
     private void computeProgressLocked(boolean forcePublish) {
-        mProgress = MathUtils.constrain(mClientProgress * 0.8f, 0f, 0.8f)
-                + MathUtils.constrain(mInternalProgress * 0.2f, 0f, 0.2f);
+        if (!mCommitted) {
+            mProgress = MathUtils.constrain(mClientProgress * 0.8f, 0f, 0.8f)
+                    + MathUtils.constrain(mInternalProgress * 0.2f, 0f, 0.2f);
+        } else {
+            // For incremental installs, continue publishing the install progress during committing.
+            mProgress = mIncrementalProgress;
+        }
 
         // Only publish when meaningful change
         if (forcePublish || Math.abs(mProgress - mReportedProgress) >= 0.01) {
@@ -1944,9 +1949,11 @@
                     throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
                             "Session destroyed");
                 }
-                // Client staging is fully done at this point
-                mClientProgress = 1f;
-                computeProgressLocked(true);
+                if (!isIncrementalInstallation()) {
+                    // For non-incremental installs, client staging is fully done at this point
+                    mClientProgress = 1f;
+                    computeProgressLocked(true);
+                }
 
                 // This ongoing commit should keep session active, even though client
                 // will probably close their end.
@@ -3804,6 +3811,7 @@
                             public void onPackageLoadingProgressChanged(float progress) {
                                 synchronized (mLock) {
                                     mIncrementalProgress = progress;
+                                    computeProgressLocked(true);
                                 }
                             }
                         });
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
index 1c55072..bc86d1d 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -993,7 +993,7 @@
         private DisplayDeviceInfo mDisplayDeviceInfo;
 
         FakeDisplayDevice() {
-            super(null, null, "");
+            super(null, null, "", mContext);
         }
 
         public void setDisplayDeviceInfo(DisplayDeviceInfo displayDeviceInfo) {
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionTest.java
index f49cbca..9bf95c0 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionTest.java
@@ -221,7 +221,8 @@
                                                  "testDeviceSelect");
         action.start();
         mTestLooper.dispatchAll();
-        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(SET_STREAM_PATH);
+        assertThat(mNativeWrapper.getResultMessages()).contains(SET_STREAM_PATH);
+        mNativeWrapper.clearResultMessages();
         assertThat(actionTimer.getState()).isEqualTo(STATE_WAIT_FOR_REPORT_POWER_STATUS);
         action.processCommand(REPORT_POWER_STATUS_ON);
         mTestLooper.dispatchAll();
@@ -238,12 +239,15 @@
         DeviceSelectAction action = createDeviceSelectAction(actionTimer, callback,
                                         /*isCec20=*/false);
         action.start();
+        mTestLooper.dispatchAll();
+        assertThat(mNativeWrapper.getResultMessages()).contains(SET_STREAM_PATH);
         assertThat(actionTimer.getState()).isEqualTo(STATE_WAIT_FOR_REPORT_POWER_STATUS);
         action.processCommand(REPORT_POWER_STATUS_STANDBY);
         mTestLooper.dispatchAll();
         HdmiCecMessage userControlPressed = HdmiCecMessageBuilder.buildUserControlPressed(
                         ADDR_TV, ADDR_PLAYBACK_1, HdmiCecKeycode.CEC_KEYCODE_POWER);
         assertThat(mNativeWrapper.getResultMessages()).contains(userControlPressed);
+        mNativeWrapper.clearResultMessages();
         assertThat(actionTimer.getState()).isEqualTo(STATE_WAIT_FOR_DEVICE_POWER_ON);
         action.handleTimerEvent(STATE_WAIT_FOR_DEVICE_POWER_ON);
         action.processCommand(REPORT_POWER_STATUS_ON);
@@ -261,6 +265,9 @@
         DeviceSelectAction action = createDeviceSelectAction(actionTimer, callback,
                                         /*isCec20=*/false);
         action.start();
+        mTestLooper.dispatchAll();
+        assertThat(mNativeWrapper.getResultMessages()).contains(SET_STREAM_PATH);
+        mNativeWrapper.clearResultMessages();
         assertThat(actionTimer.getState()).isEqualTo(STATE_WAIT_FOR_REPORT_POWER_STATUS);
         action.processCommand(REPORT_POWER_STATUS_STANDBY);
         assertThat(actionTimer.getState()).isEqualTo(STATE_WAIT_FOR_DEVICE_POWER_ON);
@@ -285,6 +292,9 @@
         DeviceSelectAction action = createDeviceSelectAction(actionTimer, callback,
                                         /*isCec20=*/false);
         action.start();
+        mTestLooper.dispatchAll();
+        assertThat(mNativeWrapper.getResultMessages()).contains(SET_STREAM_PATH);
+        mNativeWrapper.clearResultMessages();
         assertThat(actionTimer.getState()).isEqualTo(STATE_WAIT_FOR_REPORT_POWER_STATUS);
         action.processCommand(REPORT_POWER_STATUS_STANDBY);
         assertThat(actionTimer.getState()).isEqualTo(STATE_WAIT_FOR_DEVICE_POWER_ON);
@@ -330,8 +340,11 @@
         action.start();
         mTestLooper.dispatchAll();
         assertThat(mNativeWrapper.getResultMessages()).contains(SET_STREAM_PATH);
+        mNativeWrapper.clearResultMessages();
         assertThat(actionTimer.getState()).isEqualTo(STATE_WAIT_FOR_REPORT_POWER_STATUS);
         action.processCommand(REPORT_POWER_STATUS_ON);
+        mTestLooper.dispatchAll();
+        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(SET_STREAM_PATH);
         assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS);
     }
 
@@ -354,9 +367,12 @@
         HdmiCecMessage userControlPressed = HdmiCecMessageBuilder.buildUserControlPressed(
                         ADDR_TV, ADDR_PLAYBACK_1, HdmiCecKeycode.CEC_KEYCODE_POWER);
         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(userControlPressed);
+        mNativeWrapper.clearResultMessages();
         assertThat(actionTimer.getState()).isEqualTo(STATE_WAIT_FOR_DEVICE_POWER_ON);
         action.handleTimerEvent(STATE_WAIT_FOR_DEVICE_POWER_ON);
         action.processCommand(REPORT_POWER_STATUS_ON);
+        mTestLooper.dispatchAll();
+        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(SET_STREAM_PATH);
         assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS);
     }
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
index 35b224a..2ae2ef7 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java
@@ -51,6 +51,7 @@
 
 import com.android.internal.util.FastXmlSerializer;
 import com.android.server.UiServiceTestCase;
+import com.android.server.pm.PackageManagerService;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -259,6 +260,17 @@
     }
 
     @Test
+    public void testSnoozeSentToAndroid() throws Exception {
+        NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
+        mSnoozeHelper.snooze(r, 1000);
+        ArgumentCaptor<PendingIntent> captor = ArgumentCaptor.forClass(PendingIntent.class);
+        verify(mAm, times(1)).setExactAndAllowWhileIdle(
+                anyInt(), anyLong(), captor.capture());
+        assertEquals(PackageManagerService.PLATFORM_PACKAGE_NAME,
+                captor.getValue().getIntent().getPackage());
+    }
+
+    @Test
     public void testSnooze() throws Exception {
         NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM);
         mSnoozeHelper.snooze(r, (String) null);