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

Commit 8596dedf authored by Michal Karpinski's avatar Michal Karpinski
Browse files

Add a setting for background activity starts enabled state

and basic rules for enforcement

The setting is on by default. It can be switched off with
a developer option (see accompanying commit) or
"adb shell settings put global background_activity_starts_enabled 0".

The setting is wired into ActivityStarter. When it's switched
off, all unsupported background activity starts are aborted and
it's currently manifested with a toast for quick feedback.

Only basic policy rules are added for now:
0) is it one of the most important UIDs?
1) does the calling app have any foreground activity?
2) is the calling process important enough to always be able
   to start an activity?
3) does the calling uid have any visible window?

The policy rules will be extended to allow for more use cases
in forthcoming CLs.

Most notable use cases not currently covered:
1) Notifications
2) Widgets
3) Shortcuts
4) Some of the most important system apps (e.g. com.android.vending)
5) Accessibility services and similar (IMEs covered thanks to
   visible window exemption)
6) Recents button double tap to open the previous app
See bluedoc for some more.

Bug: 110956953
Test: atest WmTests:ActivityStarterTests
Manual test:
  (on)  observe all activities are started as they used to be
  (off) starts not satisfying one of the above rules are aborted,
        a toast specifying callingPackage is shown instead
Change-Id:  I1a3e14828c96f005d975ef6998f3bda678ccab29
parent e30fc89f
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -243,6 +243,8 @@ public abstract class ActivityManagerInternal {
    public abstract void ensureBootCompleted();
    public abstract void updateOomLevelsForDisplay(int displayId);
    public abstract boolean isActivityStartsLoggingEnabled();
    /** Returns true if the background activity starts is enabled. */
    public abstract boolean isBackgroundActivityStartsEnabled();
    public abstract void reportCurKeyguardUsageEvent(boolean keyguardShowing);

    /** Input dispatch timeout to a window, start the ANR process. */
+10 −0
Original line number Diff line number Diff line
@@ -11034,6 +11034,16 @@ public final class Settings {
        public static final String ACTIVITY_STARTS_LOGGING_ENABLED
                = "activity_starts_logging_enabled";
        /**
         * Feature flag to enable or disable the background activity starts.
         * When disabled, apps aren't allowed to start activities unless they're in the foreground.
         * Type: int (0 for false, 1 for true)
         * Default: 1
         * @hide
         */
        public static final String BACKGROUND_ACTIVITY_STARTS_ENABLED =
                "background_activity_starts_enabled";
        /**
         * @hide
         * @see com.android.server.appbinding.AppBindingConstants
+1 −0
Original line number Diff line number Diff line
@@ -126,6 +126,7 @@ public class SettingsBackupTest {
                    Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS,
                    Settings.Global.AUTOFILL_SMART_SUGGESTION_EMULATION_FLAGS,
                    Settings.Global.AUTOMATIC_POWER_SAVER_MODE,
                    Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED,
                    Settings.Global.BATTERY_DISCHARGE_DURATION_THRESHOLD,
                    Settings.Global.BATTERY_DISCHARGE_THRESHOLD,
                    Settings.Global.BATTERY_SAVER_DEVICE_SPECIFIC_CONSTANTS,
+19 −2
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server.am;

import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;

import android.content.ContentResolver;
import android.database.ContentObserver;
import android.net.Uri;
@@ -26,8 +28,6 @@ import android.util.Slog;

import java.io.PrintWriter;

import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;

/**
 * Settings constants that can modify the activity manager's behavior.
 */
@@ -222,6 +222,10 @@ final class ActivityManagerConstants extends ContentObserver {
    // Controlled by Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED
    volatile boolean mFlagActivityStartsLoggingEnabled;

    // Indicates whether the background activity starts is enabled.
    // Controlled by Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED
    volatile boolean mFlagBackgroundActivityStartsEnabled;

    private final ActivityManagerService mService;
    private ContentResolver mResolver;
    private final KeyValueListParser mParser = new KeyValueListParser(',');
@@ -256,6 +260,10 @@ final class ActivityManagerConstants extends ContentObserver {
    private static final Uri ACTIVITY_STARTS_LOGGING_ENABLED_URI = Settings.Global.getUriFor(
                Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED);

    private static final Uri BACKGROUND_ACTIVITY_STARTS_ENABLED_URI =
                Settings.Global.getUriFor(
                        Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED);

    public ActivityManagerConstants(ActivityManagerService service, Handler handler) {
        super(handler);
        mService = service;
@@ -266,8 +274,10 @@ final class ActivityManagerConstants extends ContentObserver {
        mResolver = resolver;
        mResolver.registerContentObserver(ACTIVITY_MANAGER_CONSTANTS_URI, false, this);
        mResolver.registerContentObserver(ACTIVITY_STARTS_LOGGING_ENABLED_URI, false, this);
        mResolver.registerContentObserver(BACKGROUND_ACTIVITY_STARTS_ENABLED_URI, false, this);
        updateConstants();
        updateActivityStartsLoggingEnabled();
        updateBackgroundActivityStartsEnabled();
    }

    public void setOverrideMaxCachedProcesses(int value) {
@@ -290,6 +300,8 @@ final class ActivityManagerConstants extends ContentObserver {
            updateConstants();
        } else if (ACTIVITY_STARTS_LOGGING_ENABLED_URI.equals(uri)) {
            updateActivityStartsLoggingEnabled();
        } else if (BACKGROUND_ACTIVITY_STARTS_ENABLED_URI.equals(uri)) {
            updateBackgroundActivityStartsEnabled();
        }
    }

@@ -373,6 +385,11 @@ final class ActivityManagerConstants extends ContentObserver {
                Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED, 0) == 1;
    }

    private void updateBackgroundActivityStartsEnabled() {
        mFlagBackgroundActivityStartsEnabled = Settings.Global.getInt(mResolver,
                Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED, 1) == 1;
    }

    private void updateMaxCachedProcesses() {
        CUR_MAX_CACHED_PROCESSES = mOverrideMaxCachedProcesses < 0
                ? MAX_CACHED_PROCESSES : mOverrideMaxCachedProcesses;
+4 −0
Original line number Diff line number Diff line
@@ -19204,6 +19204,10 @@ public class ActivityManagerService extends IActivityManager.Stub
            return mConstants.mFlagActivityStartsLoggingEnabled;
        }
        public boolean isBackgroundActivityStartsEnabled() {
            return mConstants.mFlagBackgroundActivityStartsEnabled;
        }
        public void reportCurKeyguardUsageEvent(boolean keyguardShowing) {
            synchronized(ActivityManagerService.this) {
                ActivityManagerService.this.reportGlobalUsageEventLocked(keyguardShowing
Loading