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

Commit c8d8b7cd authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Clean up BLOCK_ACTIVITY_STARTS_AFTER_HOME_FLAG." into sc-dev

parents f13458e3 dfebe6bd
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ message RootWindowContainerProto {
    // Whether or not the home activity is the recents activity. This is needed for the CTS tests to
    // know what activity types to check for when invoking splitscreen multi-window.
    optional bool is_home_recents_component = 6;
    repeated IdentifierProto pending_activities = 7;
    repeated IdentifierProto pending_activities = 7 [deprecated=true];
}

message BarControllerProto {
+0 −75
Original line number Diff line number Diff line
@@ -37,15 +37,11 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Slog;
import android.util.SparseArray;
import android.util.proto.ProtoOutputStream;
import android.view.RemoteAnimationAdapter;

import com.android.internal.annotations.VisibleForTesting;
@@ -55,10 +51,8 @@ import com.android.server.am.PendingIntentRecord;
import com.android.server.uri.NeededUriGrants;
import com.android.server.wm.ActivityStarter.DefaultFactory;
import com.android.server.wm.ActivityStarter.Factory;
import com.android.server.wm.ActivityTaskSupervisor.PendingActivityLaunch;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

/**
@@ -87,35 +81,12 @@ public class ActivityStartController {
    /** The result of the last home activity we attempted to start. */
    private int mLastHomeActivityStartResult;

    /** A list of activities that are waiting to launch. */
    private final ArrayList<ActivityTaskSupervisor.PendingActivityLaunch>
            mPendingActivityLaunches = new ArrayList<>();

    private final Factory mFactory;

    private final Handler mHandler;

    private final PendingRemoteAnimationRegistry mPendingRemoteAnimationRegistry;

    boolean mCheckedForSetup = false;

    private final class StartHandler extends Handler {
        public StartHandler(Looper looper) {
            super(looper, null, true);
        }

        @Override
        public void handleMessage(Message msg) {
            switch(msg.what) {
                case DO_PENDING_ACTIVITY_LAUNCHES_MSG:
                    synchronized (mService.mGlobalLock) {
                        doPendingActivityLaunches(true);
                    }
                    break;
            }
        }
    }

    /**
     * TODO(b/64750076): Capture information necessary for dump and
     * {@link #postStartActivityProcessingForLastStarter} rather than keeping the entire object
@@ -134,7 +105,6 @@ public class ActivityStartController {
            Factory factory) {
        mService = service;
        mSupervisor = supervisor;
        mHandler = new StartHandler(mService.mH.getLooper());
        mFactory = factory;
        mFactory.setController(this);
        mPendingRemoteAnimationRegistry = new PendingRemoteAnimationRegistry(service.mGlobalLock,
@@ -514,45 +484,6 @@ public class ActivityStartController {
        return START_SUCCESS;
    }

    void schedulePendingActivityLaunches(long delayMs) {
        mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
        Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
        mHandler.sendMessageDelayed(msg, delayMs);
    }

    void doPendingActivityLaunches(boolean doResume) {
        while (!mPendingActivityLaunches.isEmpty()) {
            final PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);
            final boolean resume = doResume && mPendingActivityLaunches.isEmpty();
            final ActivityStarter starter = obtainStarter(null /* intent */,
                    "pendingActivityLaunch");
            try {
                starter.startResolvedActivity(pal.r, pal.sourceRecord, null, null, pal.startFlags,
                        resume, pal.r.getOptions(), null, pal.intentGrants);
            } catch (Exception e) {
                Slog.e(TAG, "Exception during pending activity launch pal=" + pal, e);
                pal.sendErrorResult(e.getMessage());
            }
        }
    }

    void addPendingActivityLaunch(PendingActivityLaunch launch) {
        mPendingActivityLaunches.add(launch);
    }

    boolean clearPendingActivityLaunches(String packageName) {
        final int pendingLaunches = mPendingActivityLaunches.size();

        for (int palNdx = pendingLaunches - 1; palNdx >= 0; --palNdx) {
            final PendingActivityLaunch pal = mPendingActivityLaunches.get(palNdx);
            final ActivityRecord r = pal.r;
            if (r != null && r.packageName.equals(packageName)) {
                mPendingActivityLaunches.remove(palNdx);
            }
        }
        return mPendingActivityLaunches.size() < pendingLaunches;
    }

    void registerRemoteAnimationForNextActivityStart(String packageName,
            RemoteAnimationAdapter adapter) {
        mPendingRemoteAnimationRegistry.addPendingAnimation(packageName, adapter);
@@ -609,10 +540,4 @@ public class ActivityStartController {
            pw.println("(nothing)");
        }
    }

    public void dumpDebug(ProtoOutputStream proto, long fieldId) {
        for (PendingActivityLaunch activity: mPendingActivityLaunches) {
            activity.r.writeIdentifierToProto(proto, fieldId);
        }
    }
}
+11 −38
Original line number Diff line number Diff line
@@ -122,7 +122,6 @@ 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;
import com.android.server.wm.LaunchParamsController.LaunchParams;

import java.io.PrintWriter;
@@ -1171,24 +1170,6 @@ class ActivityStarter {
            r.appTimeTracker = sourceRecord.appTimeTracker;
        }

        final Task rootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();

        // If we are starting an activity that is not from the same uid as the currently resumed
        // one, check whether app switches are allowed.
        if (voiceSession == null && rootTask != null && (rootTask.getResumedActivity() == null
                || rootTask.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
            if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
                    realCallingPid, realCallingUid, "Activity start")) {
                if (!(restrictedBgActivity && handleBackgroundActivityAbort(r))) {
                    mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
                            sourceRecord, startFlags, rootTask, callerApp, intentGrants));
                }
                ActivityOptions.abort(checkedOptions);
                return ActivityManager.START_SWITCHES_CANCELED;
            }
        }

        if (mService.getBalAppSwitchesProtectionEnabled()) {
        // Only allow app switching to be resumed if activity is not a restricted background
        // activity and target app is not home process, otherwise any background activity
        // started in background task can stop home button protection mode.
@@ -1201,11 +1182,6 @@ class ActivityStarter {
        if (!restrictedBgActivity && !isHomeProcess) {
            mService.resumeAppSwitches();
        }
        } else {
            mService.onStartActivitySetDidAppSwitch();
        }

        mController.doPendingActivityLaunches(false);

        mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
                request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
@@ -1286,8 +1262,6 @@ class ActivityStarter {
            return false;
        }

        // App switching will be allowed if BAL app switching flag is not enabled, or if
        // its app switching rule allows it.
        // This is used to block background activity launch even if the app is still
        // visible to user after user clicking home button.
        final boolean appSwitchAllowed = mService.getBalAppSwitchesAllowed();
@@ -1438,7 +1412,6 @@ class ActivityStarter {
        Slog.w(TAG, "Background activity start [callingPackage: " + callingPackage
                + "; callingUid: " + callingUid
                + "; appSwitchAllowed: " + appSwitchAllowed
                + "; balAppSwitchEnabled: " + mService.getBalAppSwitchesProtectionEnabled()
                + "; isCallingUidForeground: " + isCallingUidForeground
                + "; callingUidHasAnyVisibleWindow: " + callingUidHasAnyVisibleWindow
                + "; callingUidProcState: " + DebugUtils.valueToString(ActivityManager.class,
+9 −122
Original line number Diff line number Diff line
@@ -202,7 +202,6 @@ import android.os.UserManager;
import android.os.WorkSource;
import android.os.storage.IStorageManager;
import android.os.storage.StorageManager;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.service.dreams.DreamActivity;
import android.service.voice.IVoiceInteractionSession;
@@ -324,12 +323,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
    /** This activity is being relaunched due to a free-resize operation. */
    public static final int RELAUNCH_REASON_FREE_RESIZE = 2;

    /**
     * Apps are blocked from starting activities in the foreground after the user presses home.
     */
    public static final String BLOCK_ACTIVITY_STARTS_AFTER_HOME_FLAG =
            "am_block_activity_starts_after_home";

    Context mContext;

    /**
@@ -386,7 +379,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
    volatile WindowProcessController mHeavyWeightProcess;
    boolean mHasHeavyWeightFeature;
    boolean mHasLeanbackFeature;
    boolean mBlockActivityAfterHomeEnabled;
    /** The process of the top most activity. */
    volatile WindowProcessController mTopApp;
    /**
@@ -490,20 +482,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
    /** Temporary to avoid allocations. */
    final StringBuilder mStringBuilder = new StringBuilder(256);

    // Amount of time after a call to stopAppSwitches() during which we will
    // prevent further untrusted switches from happening.
    private static final long APP_SWITCH_DELAY_TIME = 5 * 1000;

    /**
     * The time at which we will allow normal application switches again,
     * after a call to {@link #stopAppSwitches()}.
     * Whether normal application switches are allowed; a call to {@link #stopAppSwitches()
     * disables this.
     */
    private long mAppSwitchesAllowedTime;
    /**
     * This is set to true after the first switch after mAppSwitchesAllowedTime
     * is set; any switches after that will clear the time.
     */
    private boolean mDidAppSwitch;
    private boolean mAppSwitchesAllowed = true;

    /**
     * Last stop app switches time, apps finished before this time cannot start background activity
@@ -749,9 +732,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
            mRecentTasks.onSystemReadyLocked();
            mTaskSupervisor.onSystemReady();
            mActivityClientController.onSystemReady();
            mBlockActivityAfterHomeEnabled = DeviceConfig.getBoolean(
                    DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
                    BLOCK_ACTIVITY_STARTS_AFTER_HOME_FLAG, true);
        }
    }

@@ -1146,7 +1126,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
            if (topFocusedRootTask != null && topFocusedRootTask.getResumedActivity() != null
                    && topFocusedRootTask.getResumedActivity().info.applicationInfo.uid
                    == Binder.getCallingUid()) {
                mAppSwitchesAllowedTime = 0;
                mAppSwitchesAllowed = true;
            }
        }
        return pir.sendInner(0, fillInIntent, resolvedType, allowlistToken, null, null,
@@ -2002,10 +1982,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        final int callingPid = Binder.getCallingPid();
        final int callingUid = Binder.getCallingUid();
        assertPackageMatchesCallingUid(callingPackage);
        if (!checkAppSwitchAllowedLocked(callingPid, callingUid, -1, -1, "Task to front")) {
            SafeActivityOptions.abort(options);
            return;
        }

        final long origId = Binder.clearCallingIdentity();
        WindowProcessController callerApp = null;
        if (appThread != null) {
@@ -2085,77 +2062,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        throw new SecurityException(msg);
    }

    /**
     * Return true if app switch protection will be handled by background activity launch logic.
     */
    boolean getBalAppSwitchesProtectionEnabled() {
         return mBlockActivityAfterHomeEnabled;
    }

    /**
     * Return true if app switching is allowed.
     */
    boolean getBalAppSwitchesAllowed() {
        if (getBalAppSwitchesProtectionEnabled()) {
            // Apps no longer able to start BAL again until app switching is resumed.
            return mAppSwitchesAllowedTime == 0;
        } else {
            // Legacy behavior, BAL logic won't block app switching.
            return true;
        }
    }

    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
            int callingPid, int callingUid, String name) {

        // Background activity launch logic replaces app switching protection, so allow
        // apps to start activity here now.
        if (getBalAppSwitchesProtectionEnabled()) {
            return true;
        }

        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
            return true;
        }

        if (getRecentTasks().isCallerRecents(sourceUid)) {
            return true;
        }

        int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
        if (perm == PackageManager.PERMISSION_GRANTED) {
            return true;
        }
        if (checkAllowAppSwitchUid(sourceUid)) {
            return true;
        }

        // If the actual IPC caller is different from the logical source, then
        // also see if they are allowed to control app switches.
        if (callingUid != -1 && callingUid != sourceUid) {
            perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
            if (perm == PackageManager.PERMISSION_GRANTED) {
                return true;
            }
            if (checkAllowAppSwitchUid(callingUid)) {
                return true;
            }
        }

        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
        return false;
    }

    private boolean checkAllowAppSwitchUid(int uid) {
        ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
        if (types != null) {
            for (int i = types.size() - 1; i >= 0; i--) {
                if (types.valueAt(i).intValue() == uid) {
                    return true;
                }
            }
        }
        return false;
        return mAppSwitchesAllowed;
    }

    @Override
@@ -3663,13 +3574,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
    public void stopAppSwitches() {
        enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
        synchronized (mGlobalLock) {
            mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
            mAppSwitchesAllowed = false;
            mLastStopAppSwitchesTime = SystemClock.uptimeMillis();
            mDidAppSwitch = false;
            // If BAL app switching enabled, app switches are blocked not delayed.
            if (!getBalAppSwitchesProtectionEnabled()) {
                getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
            }
        }
    }

@@ -3677,10 +3583,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
    public void resumeAppSwitches() {
        enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
        synchronized (mGlobalLock) {
            // Note that we don't execute any pending app switches... we will
            // let those wait until either the timeout, or the next start
            // activity request.
            mAppSwitchesAllowedTime = 0;
            mAppSwitchesAllowed = true;
        }
    }

@@ -3688,19 +3591,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        return mLastStopAppSwitchesTime;
    }

    void onStartActivitySetDidAppSwitch() {
        if (mDidAppSwitch) {
            // This is the second allowed switch since we stopped switches, so now just generally
            // allow switches. Use case:
            // - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
            // - user taps a home icon (coming from home so allowed, we hit here and now allow
            // anyone to switch again).
            mAppSwitchesAllowedTime = 0;
        } else {
            mDidAppSwitch = true;
        }
    }

    /** @return whether the system should disable UI modes incompatible with VR mode. */
    boolean shouldDisableNonVrUiLocked() {
        return mVrController.shouldDisableNonVrUiLocked();
@@ -5822,15 +5712,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
                int userId) {
            synchronized (mGlobalLock) {

                boolean didSomething =
                        getActivityStartController().clearPendingActivityLaunches(packageName);
                didSomething |= mRootWindowContainer.finishDisabledPackageActivities(packageName,
                return mRootWindowContainer.finishDisabledPackageActivities(packageName,
                        null /* filterByClasses */, doit, evenPersistent, userId,
                        // Only remove the activities without process because the activities with
                        // attached process will be removed when handling process died with
                        // WindowProcessController#isRemoved == true.
                        true /* onlyRemoveNoProcess */);
                return didSomething;
            }
        }

+0 −36
Original line number Diff line number Diff line
@@ -142,7 +142,6 @@ import com.android.internal.util.function.pooled.PooledConsumer;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.am.ActivityManagerService;
import com.android.server.am.UserState;
import com.android.server.uri.NeededUriGrants;
import com.android.server.wm.ActivityMetricsLogger.LaunchingState;

import java.io.FileDescriptor;
@@ -376,41 +375,6 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {

    private boolean mInitialized;

    /**
     * Description of a request to start a new activity, which has been held
     * due to app switches being disabled.
     */
    static class PendingActivityLaunch {
        final ActivityRecord r;
        final ActivityRecord sourceRecord;
        final int startFlags;
        final Task rootTask;
        final WindowProcessController callerApp;
        final NeededUriGrants intentGrants;

        PendingActivityLaunch(ActivityRecord r, ActivityRecord sourceRecord,
                int startFlags, Task rootTask, WindowProcessController callerApp,
                NeededUriGrants intentGrants) {
            this.r = r;
            this.sourceRecord = sourceRecord;
            this.startFlags = startFlags;
            this.rootTask = rootTask;
            this.callerApp = callerApp;
            this.intentGrants = intentGrants;
        }

        void sendErrorResult(String message) {
            try {
                if (callerApp != null && callerApp.hasThread()) {
                    callerApp.getThread().scheduleCrash(message);
                }
            } catch (RemoteException e) {
                Slog.e(TAG, "Exception scheduling crash of failed "
                        + "activity launcher sourceRecord=" + sourceRecord, e);
            }
        }
    }

    public ActivityTaskSupervisor(ActivityTaskManagerService service, Looper looper) {
        mService = service;
        mLooper = looper;
Loading