Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ba2eb648 authored by Bernardo Rufino's avatar Bernardo Rufino Committed by Android (Google) Code Review
Browse files

Merge "Window Z rule for closing the notification shade"

parents 4979f47a 2f91fbf9
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -40,6 +40,9 @@ public interface StatusBarManagerInternal {

    void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);

    /** Collapses the notification shade. */
    void collapsePanels();

    void dismissKeyboardShortcutsMenu();
    void toggleKeyboardShortcutsMenu(int deviceId);

+10 −0
Original line number Diff line number Diff line
@@ -383,6 +383,16 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
            }
        }

        @Override
        public void collapsePanels() {
            if (mBar != null) {
                try {
                    mBar.animateCollapsePanels();
                } catch (RemoteException ex) {
                }
            }
        }

        @Override
        public void dismissKeyboardShortcutsMenu() {
            if (mBar != null) {
+15 −0
Original line number Diff line number Diff line
@@ -118,6 +118,7 @@ import com.android.internal.protolog.common.ProtoLog;
import com.android.server.am.PendingIntentRecord;
import com.android.server.pm.InstantAppResolver;
import com.android.server.power.ShutdownCheckPoints;
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.uri.NeededUriGrants;
import com.android.server.wm.ActivityMetricsLogger.LaunchingState;
import com.android.server.wm.ActivityTaskSupervisor.PendingActivityLaunch;
@@ -1589,6 +1590,20 @@ class ActivityStarter {
                    newTransition.abort();
                }
            } else {
                if (!mAvoidMoveToFront && mDoResume
                        && mRootWindowContainer.hasVisibleWindowAboveNotificationShade(
                            r.launchedFromUid)) {
                    // If the UID launching the activity has a visible window on top of the
                    // notification shade and it's launching an activity that's going to be at the
                    // front, we should move the shade out of the way so the user can see it.
                    // We want to avoid the case where the activity is launched on top of a
                    // background task which is not moved to the front.
                    StatusBarManagerInternal statusBar = mService.getStatusBarManagerInternal();
                    if (statusBar != null) {
                        // This results in a async call since the interface is one-way
                        statusBar.collapsePanels();
                    }
                }
                if (result == START_SUCCESS || result == START_TASK_TO_FRONT) {
                    // The activity is started new rather than just brought forward, so record
                    // it as an existence change.
+27 −4
Original line number Diff line number Diff line
@@ -28,6 +28,8 @@ import static android.Manifest.permission.READ_FRAME_BUFFER;
import static android.Manifest.permission.REMOVE_TASKS;
import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
import static android.Manifest.permission.STOP_APP_SWITCHES;
import static android.app.ActivityManager.DROP_CLOSE_SYSTEM_DIALOGS;
import static android.app.ActivityManager.LOCK_DOWN_CLOSE_SYSTEM_DIALOGS;
import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
import static android.app.ActivityManagerInternal.ALLOW_NON_FULL;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
@@ -253,6 +255,7 @@ import com.android.server.firewall.IntentFirewall;
import com.android.server.inputmethod.InputMethodSystemProperty;
import com.android.server.pm.UserManagerService;
import com.android.server.policy.PermissionPolicyInternal;
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.uri.NeededUriGrants;
import com.android.server.uri.UriGrantsManagerInternal;

@@ -342,6 +345,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
    /** The cached sys ui service component name from package manager. */
    private ComponentName mSysUiServiceComponent;
    private PermissionPolicyInternal mPermissionPolicyInternal;
    private StatusBarManagerInternal mStatusBarManagerInternal;
    @VisibleForTesting
    final ActivityTaskManagerInternal mInternal;
    PowerManagerInternal mPowerManagerInternal;
@@ -2927,14 +2931,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        }
        if (!canCloseSystemDialogs(pid, uid, process)) {
            // The app can't close system dialogs, throw only if it targets S+
            if (CompatChanges.isChangeEnabled(
                    ActivityManager.LOCK_DOWN_CLOSE_SYSTEM_DIALOGS, uid)) {
            if (CompatChanges.isChangeEnabled(LOCK_DOWN_CLOSE_SYSTEM_DIALOGS, uid)) {
                throw new SecurityException(
                        "Permission Denial: " + Intent.ACTION_CLOSE_SYSTEM_DIALOGS
                                + " broadcast from " + caller + " requires "
                                + Manifest.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS + ".");
            } else if (CompatChanges.isChangeEnabled(
                    ActivityManager.DROP_CLOSE_SYSTEM_DIALOGS, uid)) {
            } else if (CompatChanges.isChangeEnabled(DROP_CLOSE_SYSTEM_DIALOGS, uid)) {
                Slog.e(TAG,
                        "Permission Denial: " + Intent.ACTION_CLOSE_SYSTEM_DIALOGS
                                + " broadcast from " + caller + " requires "
@@ -2983,6 +2985,20 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
                return true;
            }
        }
        // This covers the case where the app is displaying some UI on top of the notification shade
        // and wants to start an activity. The app then sends the intent in order to move the
        // notification shade out of the way and show the activity to the user. This is fine since
        // the caller already has privilege to show a visible window on top of the notification
        // shade, so it can already prevent the user from accessing the shade if it wants to.
        // We only allow for targetSdk < S, for S+ we automatically collapse the shade on
        // startActivity() for these apps.
        if (!CompatChanges.isChangeEnabled(LOCK_DOWN_CLOSE_SYSTEM_DIALOGS, uid)) {
            synchronized (mGlobalLock) {
                if (mRootWindowContainer.hasVisibleWindowAboveNotificationShade(uid)) {
                    return true;
                }
            }
        }
        return false;
    }

@@ -4787,6 +4803,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        return mPermissionPolicyInternal;
    }

    StatusBarManagerInternal getStatusBarManagerInternal() {
        if (mStatusBarManagerInternal == null) {
            mStatusBarManagerInternal = LocalServices.getService(StatusBarManagerInternal.class);
        }
        return mStatusBarManagerInternal;
    }

    AppWarnings getAppWarningsLocked() {
        return mAppWarnings;
    }
+22 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import static android.view.Display.INVALID_DISPLAY;
import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE;
import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_FLAG_APP_CRASHED;
import static android.view.WindowManager.TRANSIT_NONE;
@@ -3137,6 +3138,27 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
        });
    }

    /**
     * Returns {@code true} if {@code uid} has a visible window that's above a window of type {@link
     * WindowManager.LayoutParams#TYPE_NOTIFICATION_SHADE}. If there is no window with type {@link
     * WindowManager.LayoutParams#TYPE_NOTIFICATION_SHADE}, it returns {@code false}.
     */
    boolean hasVisibleWindowAboveNotificationShade(int uid) {
        boolean[] visibleWindowFound = {false};
        // We only return true if we found the notification shade (ie. window of type
        // TYPE_NOTIFICATION_SHADE). Usually, it should always be there, but if for some reason
        // it isn't, we should better be on the safe side and return false for this.
        return forAllWindows(w -> {
            if (w.mOwnerUid == uid && w.isVisible()) {
                visibleWindowFound[0] = true;
            }
            if (w.mAttrs.type == TYPE_NOTIFICATION_SHADE) {
                return visibleWindowFound[0];
            }
            return false;
        }, true /* traverseTopToBottom */);
    }

    private boolean shouldCloseAssistant(ActivityRecord r, String reason) {
        if (!r.isActivityTypeAssistant()) return false;
        if (reason == SYSTEM_DIALOG_REASON_ASSIST) return false;