Merge "Use connected boolean as NLS does vs IBinder" into qt-dev
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index e920843..93e8b9d 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -305,6 +305,8 @@
         LocationManagerApiUsageReported location_manager_api_usage_reported = 210;
         ReviewPermissionsFragmentResultReported review_permissions_fragment_result_reported
             = 211 [(log_from_module) = "permissioncontroller"];
+        RuntimePermissionsUpgradeResult runtime_permissions_upgrade_result =
+            212 [(log_from_module) = "permissioncontroller"];
     }
 
     // Pulled events will start at field 10000.
@@ -6567,3 +6569,18 @@
     // The result of the permission grant
     optional bool permission_granted = 5;
 }
+
+/**
+* Information about results of permission upgrade by RuntimePermissionsUpgradeController
+* Logged from: RuntimePermissionUpdgradeController
+*/
+message RuntimePermissionsUpgradeResult {
+    // Permission granted as result of upgrade
+    optional string permission_name = 1;
+
+    // UID of package granted permission
+    optional int32 uid = 2 [(is_uid) = true];
+
+    // Name of package granted permission
+    optional string package_name = 3;
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 88a8b31..b4299fd 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -27,6 +27,9 @@
 import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SUPPORTS_WINDOW_CORNERS;
 import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY;
 import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_WINDOW_CORNER_RADIUS;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
 
 import android.annotation.FloatRange;
 import android.app.ActivityTaskManager;
@@ -67,6 +70,7 @@
 import com.android.systemui.statusbar.phone.NavigationBarView;
 import com.android.systemui.statusbar.phone.NavigationModeController;
 import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.StatusBarWindowCallback;
 import com.android.systemui.statusbar.phone.StatusBarWindowController;
 import com.android.systemui.statusbar.policy.CallbackController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -90,7 +94,6 @@
     private static final String ACTION_QUICKSTEP = "android.intent.action.QUICKSTEP_SERVICE";
 
     public static final String TAG_OPS = "OverviewProxyService";
-    public static final boolean DEBUG_OVERVIEW_PROXY = false;
     private static final long BACKOFF_MILLIS = 1000;
     private static final long DEFERRED_CALLBACK_MILLIS = 5000;
 
@@ -442,6 +445,8 @@
         }
     };
 
+    private final StatusBarWindowCallback mStatusBarWindowCallback = this::onStatusBarStateChanged;
+
     // This is the death handler for the binder from the launcher service
     private final IBinder.DeathRecipient mOverviewServiceDeathRcpt
             = this::cleanupAfterDeath;
@@ -481,6 +486,9 @@
                 PatternMatcher.PATTERN_LITERAL);
         filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
         mContext.registerReceiver(mLauncherStateChangedReceiver, filter);
+
+        // Listen for status bar state changes
+        statusBarWinController.registerCallback(mStatusBarWindowCallback);
     }
 
     public void notifyBackAction(boolean completed, int downX, int downY, boolean isButton,
@@ -531,7 +539,7 @@
             navBarView.updateSystemUiStateFlags();
         }
         if (mStatusBarWinController != null) {
-            mStatusBarWinController.updateSystemUiStateFlags();
+            mStatusBarWinController.notifyStateChangedCallbacks();
         }
         notifySystemUiStateFlags(mSysUiStateFlags);
     }
@@ -546,6 +554,16 @@
         }
     }
 
+    private void onStatusBarStateChanged(boolean keyguardShowing, boolean keyguardOccluded,
+            boolean bouncerShowing) {
+        int displayId = mContext.getDisplayId();
+        setSystemUiStateFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING,
+                keyguardShowing && !keyguardOccluded, displayId);
+        setSystemUiStateFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED,
+                keyguardShowing && keyguardOccluded, displayId);
+        setSystemUiStateFlag(SYSUI_STATE_BOUNCER_SHOWING, bouncerShowing, displayId);
+    }
+
     /**
      * Sets the navbar region which can receive touch inputs
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowCallback.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowCallback.java
new file mode 100644
index 0000000..f33ff27
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowCallback.java
@@ -0,0 +1,20 @@
+/*
+ * 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.systemui.statusbar.phone;
+
+public interface StatusBarWindowCallback {
+    void onStateChanged(boolean keyguardShowing, boolean keyguardOccluded, boolean bouncerShowing);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
index c73ed60..8621b72 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
@@ -18,9 +18,6 @@
 
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
 import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENABLE_REMOTE_INPUT;
 
 import android.app.ActivityManager;
@@ -47,17 +44,19 @@
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
-import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.statusbar.RemoteInputController.Callback;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
 
+import com.google.android.collect.Lists;
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
 import java.lang.reflect.Field;
 
+import java.util.ArrayList;
 import javax.inject.Inject;
 import javax.inject.Singleton;
 
@@ -83,6 +82,8 @@
     private float mScreenBrightnessDoze;
     private final State mCurrentState = new State();
     private OtherwisedCollapsedListener mListener;
+    private final ArrayList<WeakReference<StatusBarWindowCallback>>
+            mCallbacks = Lists.newArrayList();
 
     private final SysuiColorExtractor mColorExtractor = Dependency.get(SysuiColorExtractor.class);
 
@@ -108,6 +109,19 @@
         Dependency.get(ConfigurationController.class).addCallback(this);
     }
 
+    /**
+     * Register to receive notifications about status bar window state changes.
+     */
+    public void registerCallback(StatusBarWindowCallback callback) {
+        // Prevent adding duplicate callbacks
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            if (mCallbacks.get(i).get() == callback) {
+                return;
+            }
+        }
+        mCallbacks.add(new WeakReference<StatusBarWindowCallback>(callback));
+    }
+
     private boolean shouldEnableKeyguardScreenRotation() {
         Resources res = mContext.getResources();
         return SystemProperties.getBoolean("lockscreen.rot_override", false)
@@ -318,18 +332,18 @@
             }
             mHasTopUi = mHasTopUiChanged;
         }
-        updateSystemUiStateFlags();
+        notifyStateChangedCallbacks();
     }
 
-    public void updateSystemUiStateFlags() {
-        int displayId = mContext.getDisplayId();
-        OverviewProxyService overviewProxyService = Dependency.get(OverviewProxyService.class);
-        overviewProxyService.setSystemUiStateFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING,
-                mCurrentState.keyguardShowing && !mCurrentState.keyguardOccluded, displayId);
-        overviewProxyService.setSystemUiStateFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED,
-                mCurrentState.keyguardShowing && mCurrentState.keyguardOccluded, displayId);
-        overviewProxyService.setSystemUiStateFlag(SYSUI_STATE_BOUNCER_SHOWING,
-                mCurrentState.bouncerShowing, displayId);
+    public void notifyStateChangedCallbacks() {
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            StatusBarWindowCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onStateChanged(mCurrentState.keyguardShowing,
+                        mCurrentState.keyguardOccluded,
+                        mCurrentState.bouncerShowing);
+            }
+        }
     }
 
     private void applyForceStatusBarVisibleFlag(State state) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 4d84048..5f4d113 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -24334,8 +24334,12 @@
         @Override
         public boolean isPermissionsReviewRequired(String packageName, int userId) {
             synchronized (mPackages) {
-                return mPermissionManager.isPermissionsReviewRequired(
-                        mPackages.get(packageName), userId);
+                final PackageParser.Package pkg = mPackages.get(packageName);
+                if (pkg == null) {
+                    return false;
+                }
+
+                return mPermissionManager.isPermissionsReviewRequired(pkg, userId);
             }
         }
 
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 4edd9ef..e4e0c55 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -1897,14 +1897,15 @@
         return Boolean.TRUE == granted;
     }
 
-    private boolean isPermissionsReviewRequired(PackageParser.Package pkg, int userId) {
+    private boolean isPermissionsReviewRequired(@NonNull PackageParser.Package pkg,
+            @UserIdInt int userId) {
         // Permission review applies only to apps not supporting the new permission model.
         if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
             return false;
         }
 
         // Legacy apps have the permission and get user consent on launch.
-        if (pkg == null || pkg.mExtras == null) {
+        if (pkg.mExtras == null) {
             return false;
         }
         final PackageSetting ps = (PackageSetting) pkg.mExtras;
@@ -2952,7 +2953,7 @@
             PermissionManagerService.this.systemReady();
         }
         @Override
-        public boolean isPermissionsReviewRequired(Package pkg, int userId) {
+        public boolean isPermissionsReviewRequired(@NonNull Package pkg, @UserIdInt int userId) {
             return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId);
         }
         @Override
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
index 9fb71f4..313de3d 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.PermissionInfoFlags;
 import android.content.pm.PackageParser;
@@ -65,7 +66,8 @@
 
     public abstract void systemReady();
 
-    public abstract boolean isPermissionsReviewRequired(PackageParser.Package pkg, int userId);
+    public abstract boolean isPermissionsReviewRequired(@NonNull PackageParser.Package pkg,
+            @UserIdInt int userId);
 
     public abstract void grantRuntimePermission(
             @NonNull String permName, @NonNull String packageName, boolean overridePolicy,
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");
             }
         }
     }