Merge "Reinflate silent notif header on config change" into qt-dev
diff --git a/core/java/android/service/notification/ConditionProviderService.java b/core/java/android/service/notification/ConditionProviderService.java
index 45480cb..7d3b13b 100644
--- a/core/java/android/service/notification/ConditionProviderService.java
+++ b/core/java/android/service/notification/ConditionProviderService.java
@@ -77,6 +77,7 @@
 
     private Provider mProvider;
     private INotificationManager mNoMan;
+    boolean mIsConnected;
 
     /**
      * The {@link Intent} that must be declared as handled by the service.
@@ -179,7 +180,7 @@
         try {
             noMan.requestUnbindProvider(mProvider);
             // Disable future messages.
-            mProvider = null;
+            mIsConnected = false;
         } catch (RemoteException ex) {
             throw ex.rethrowFromSystemServer();
         }
@@ -233,16 +234,16 @@
      */
     @TestApi
     public boolean isBound() {
-        if (mProvider == null) {
+        if (!mIsConnected) {
             Log.w(TAG, "Condition provider service not yet bound.");
-            return false;
         }
-        return true;
+        return mIsConnected;
     }
 
     private final class Provider extends IConditionProvider.Stub {
         @Override
         public void onConnected() {
+            mIsConnected = true;
             mHandler.obtainMessage(H.ON_CONNECTED).sendToTarget();
         }
 
@@ -265,7 +266,7 @@
         @Override
         public void handleMessage(Message msg) {
             String name = null;
-            if (!isBound()) {
+            if (!mIsConnected) {
                 return;
             }
             try {
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
index 77bb514..9228b17 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
@@ -55,10 +55,17 @@
     /**
      * Control the {@param alpha} of the back button in the navigation bar and {@param animate} if
      * needed from current value
+     * @deprecated
      */
     void setBackButtonAlpha(float alpha, boolean animate) = 8;
 
     /**
+     * Control the {@param alpha} of the option nav bar button (back-button in 2 button mode
+     * and home bar in no-button mode) and {@param animate} if needed from current value
+     */
+    void setNavBarButtonAlpha(float alpha, boolean animate) = 19;
+
+    /**
      * Proxies motion events from the homescreen UI to the status bar. Only called when
      * swipe down is detected on WORKSPACE. The sender guarantees the following order of events on
      * the tracking pointer.
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index b4299fd..e5caf68 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -118,7 +118,7 @@
     private boolean mBound;
     private boolean mIsEnabled;
     private int mCurrentBoundedUserId = -1;
-    private float mBackButtonAlpha;
+    private float mNavBarButtonAlpha;
     private MotionEvent mStatusBarGestureDownEvent;
     private float mWindowCornerRadius;
     private boolean mSupportsRoundedCornersOnWindows;
@@ -244,22 +244,25 @@
         }
 
         @Override
-        public void setBackButtonAlpha(float alpha, boolean animate) {
-            if (!verifyCaller("setBackButtonAlpha")) {
+        public void setNavBarButtonAlpha(float alpha, boolean animate) {
+            if (!verifyCaller("setNavBarButtonAlpha")) {
                 return;
             }
             long token = Binder.clearCallingIdentity();
             try {
-                mBackButtonAlpha = alpha;
-                mHandler.post(() -> {
-                    notifyBackButtonAlphaChanged(alpha, animate);
-                });
+                mNavBarButtonAlpha = alpha;
+                mHandler.post(() -> notifyNavBarButtonAlphaChanged(alpha, animate));
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override
+        public void setBackButtonAlpha(float alpha, boolean animate) {
+            setNavBarButtonAlpha(alpha, animate);
+        }
+
+        @Override
         public void onAssistantProgress(@FloatRange(from = 0.0, to = 1.0) float progress) {
             if (!verifyCaller("onAssistantProgress")) {
                 return;
@@ -470,7 +473,7 @@
                 .supportsRoundedCornersOnWindows(mContext.getResources());
 
         // Assumes device always starts with back button until launcher tells it that it does not
-        mBackButtonAlpha = 1.0f;
+        mNavBarButtonAlpha = 1.0f;
 
         // Listen for nav bar mode changes
         mNavBarMode = navModeController.addListener(this);
@@ -583,7 +586,7 @@
     }
 
     public float getBackButtonAlpha() {
-        return mBackButtonAlpha;
+        return mNavBarButtonAlpha;
     }
 
     public void cleanupAfterDeath() {
@@ -655,7 +658,7 @@
     public void addCallback(OverviewProxyListener listener) {
         mConnectionCallbacks.add(listener);
         listener.onConnectionChanged(mOverviewProxy != null);
-        listener.onBackButtonAlphaChanged(mBackButtonAlpha, false);
+        listener.onNavBarButtonAlphaChanged(mNavBarButtonAlpha, false);
         listener.onSystemUiStateChanged(mSysUiStateFlags);
     }
 
@@ -686,14 +689,14 @@
         if (mOverviewProxy != null) {
             mOverviewProxy.asBinder().unlinkToDeath(mOverviewServiceDeathRcpt, 0);
             mOverviewProxy = null;
-            notifyBackButtonAlphaChanged(1f, false /* animate */);
+            notifyNavBarButtonAlphaChanged(1f, false /* animate */);
             notifyConnectionChanged();
         }
     }
 
-    private void notifyBackButtonAlphaChanged(float alpha, boolean animate) {
+    private void notifyNavBarButtonAlphaChanged(float alpha, boolean animate) {
         for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
-            mConnectionCallbacks.get(i).onBackButtonAlphaChanged(alpha, animate);
+            mConnectionCallbacks.get(i).onNavBarButtonAlphaChanged(alpha, animate);
         }
     }
 
@@ -784,7 +787,8 @@
         default void onQuickStepStarted() {}
         default void onOverviewShown(boolean fromHome) {}
         default void onQuickScrubStarted() {}
-        default void onBackButtonAlphaChanged(float alpha, boolean animate) {}
+        /** Notify changes in the nav bar button alpha */
+        default void onNavBarButtonAlphaChanged(float alpha, boolean animate) {}
         default void onSystemUiStateChanged(int sysuiStateFlags) {}
         default void onAssistantProgress(@FloatRange(from = 0.0, to = 1.0) float progress) {}
         default void onAssistantGestureCompletion(float velocity) {}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index 79976d0..5708c1b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -203,17 +203,16 @@
         }
 
         @Override
-        public void onBackButtonAlphaChanged(float alpha, boolean animate) {
-            final ButtonDispatcher backButton = mNavigationBarView.getBackButton();
-            final boolean useAltBack =
-                    (mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0;
-            if (QuickStepContract.isGesturalMode(mNavBarMode) && !useAltBack) {
-                // If property was changed to hide/show back button, going home will trigger
-                // launcher to to change the back button alpha to reflect property change
-                backButton.setVisibility(View.GONE);
-            } else {
-                backButton.setVisibility(alpha > 0 ? View.VISIBLE : View.INVISIBLE);
-                backButton.setAlpha(alpha, animate);
+        public void onNavBarButtonAlphaChanged(float alpha, boolean animate) {
+            ButtonDispatcher buttonDispatcher = null;
+            if (QuickStepContract.isSwipeUpMode(mNavBarMode)) {
+                buttonDispatcher = mNavigationBarView.getBackButton();
+            } else if (QuickStepContract.isGesturalMode(mNavBarMode)) {
+                buttonDispatcher = mNavigationBarView.getHomeHandle();
+            }
+            if (buttonDispatcher != null) {
+                buttonDispatcher.setVisibility(alpha > 0 ? View.VISIBLE : View.INVISIBLE);
+                buttonDispatcher.setAlpha(alpha, animate);
             }
         }
     };
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index e4e0c55..e5f914d 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -2129,7 +2129,7 @@
         }
 
         if (bp.isSoftRestricted() && !SoftRestrictedPermissionPolicy.forPermission(mContext,
-                pkg.applicationInfo, permName).canBeGranted()) {
+                pkg.applicationInfo, UserHandle.of(userId), permName).canBeGranted()) {
             Log.e(TAG, "Cannot grant soft restricted permission " + permName + " for package "
                     + packageName);
             return;
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java
index 6882afb..93b11be 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyService.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java
@@ -414,7 +414,7 @@
             } else if (permissionInfo.isSoftRestricted()) {
                 final SoftRestrictedPermissionPolicy policy =
                         SoftRestrictedPermissionPolicy.forPermission(mContext, pkg.applicationInfo,
-                                permission);
+                                mContext.getUser(), permission);
 
                 if (opCode != OP_NONE) {
                     if (policy.canBeGranted()) {
diff --git a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
index d447617..90e0dc4 100644
--- a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
+++ b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
@@ -33,6 +33,7 @@
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.os.Build;
+import android.os.UserHandle;
 
 /**
  * The behavior of soft restricted permissions is different for each permission. This class collects
@@ -75,12 +76,14 @@
      *
      * @param context A context to use
      * @param appInfo The application the permission belongs to
+     * @param user The user the app belongs to
      * @param permission The name of the permission
      *
      * @return The policy for this permission
      */
     public static @NonNull SoftRestrictedPermissionPolicy forPermission(@NonNull Context context,
-            @NonNull ApplicationInfo appInfo, @NonNull String permission) {
+            @NonNull ApplicationInfo appInfo, @NonNull UserHandle user,
+            @NonNull String permission) {
         switch (permission) {
             // Storage uses a special app op to decide the mount state and supports soft restriction
             // where the restricted state allows the permission but only for accessing the medial
@@ -88,7 +91,7 @@
             case READ_EXTERNAL_STORAGE:
             case WRITE_EXTERNAL_STORAGE: {
                 int flags = context.getPackageManager().getPermissionFlags(
-                        permission, appInfo.packageName, context.getUser());
+                        permission, appInfo.packageName, user);
                 boolean applyRestriction = (flags & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
                 boolean isWhiteListed = (flags & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
                 boolean hasRequestedLegacyExternalStorage =
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index feef5e2..bc0f747 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -544,14 +544,30 @@
 
             // If we have an active transition that's waiting on a certain activity that will be
             // invisible now, we'll never get onWindowsDrawn, so abort the transition if necessary.
-            if (info != null && !hasVisibleNonFinishingActivity(t)) {
-                if (DEBUG_METRICS) Slog.i(TAG, "notifyVisibilityChanged to invisible"
-                        + " activity=" + r);
-                logAppTransitionCancel(info);
-                mWindowingModeTransitionInfo.remove(r.getWindowingMode());
-                if (mWindowingModeTransitionInfo.size() == 0) {
-                    reset(true /* abort */, info, "notifyVisibilityChanged to invisible");
-                }
+
+            // We have no active transitions.
+            if (info == null) {
+                return;
+            }
+
+            // The notified activity whose visibility changed is no longer the launched activity.
+            // We can still wait to get onWindowsDrawn.
+            if (info.launchedActivity != r) {
+                return;
+            }
+
+            // Check if there is any activity in the task that is visible and not finishing. If the
+            // launched activity finished before it is drawn and if there is another activity in
+            // the task then that activity will be draw on screen.
+            if (hasVisibleNonFinishingActivity(t)) {
+                return;
+            }
+
+            if (DEBUG_METRICS) Slog.i(TAG, "notifyVisibilityChanged to invisible activity=" + r);
+            logAppTransitionCancel(info);
+            mWindowingModeTransitionInfo.remove(r.getWindowingMode());
+            if (mWindowingModeTransitionInfo.size() == 0) {
+                reset(true /* abort */, info, "notifyVisibilityChanged to invisible");
             }
         }
     }