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

Commit 85e35643 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Improve behavior of bg check.

There is a new APP_START_MODE_DELAYED_RIGID which means that
things discovering something is not allowed to start should
report a clear error back to the caller.  This is how apps
that opt in to bg check should behave, and will now
be used if the app op mode is set to ERRORED.

This (for now?) removes the code that allows services to
be started if the request is coming from a foreground process.
That behavior isn't in the current bg check spec, and
probably not what we want as the standard platform model (since
it makes knowing when a service can start even harder to
determine).  It was originally done for the experimental
bg check work in N to see how much we could avoid
breaking existing apps, so not relevant when apps need to
explicitly opt in.

Also report temporary whitelist changes to activity manager for
it to lift background restrictions temporarily for apps.  Being
on the whitelist is now part of UidRecord, preventing a uid from
going idle.

Test: Initial CTS test added.

Change-Id: I36fd906fa69de8b7ff360605ae17c088f182e172
parent 9553a1ec
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -526,9 +526,13 @@ public class ActivityManager {
    /** @hide Mode for {@link IActivityManager#getAppStartMode}: delay running until later. */
    public static final int APP_START_MODE_DELAYED = 1;

    /** @hide Mode for {@link IActivityManager#getAppStartMode}: delay running until later, with
     * rigid errors (throwing exception). */
    public static final int APP_START_MODE_DELAYED_RIGID = 2;

    /** @hide Mode for {@link IActivityManager#getAppStartMode}: disable/cancel pending
     * launches. */
    public static final int APP_START_MODE_DISABLED = 2;
     * launches; this is the mode for ephemeral apps. */
    public static final int APP_START_MODE_DISABLED = 3;

    /**
     * Lock task mode is not active.
+11 −0
Original line number Diff line number Diff line
@@ -200,6 +200,17 @@ public abstract class ActivityManagerInternal {
     */
    public abstract void setPendingIntentWhitelistDuration(IIntentSender target, long duration);

    /**
     * Allow DeviceIdleController to tell us about what apps are whitelisted.
     */
    public abstract void setDeviceIdleWhitelist(int[] appids);

    /**
     * Update information about which app IDs are on the temp whitelist.
     */
    public abstract void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId,
            boolean adding);

    /**
     * Updates and persists the {@link Configuration} for a given user.
     *
+3 −0
Original line number Diff line number Diff line
@@ -1430,6 +1430,9 @@ class ContextImpl extends Context {
                    throw new SecurityException(
                            "Unable to start service " + service
                            + ": " + cn.getClassName());
                } else if (cn.getPackageName().equals("?")) {
                    throw new IllegalStateException(
                            "Not allowed to start service " + service + ": " + cn.getClassName());
                }
            }
            return cn;
+10 −3
Original line number Diff line number Diff line
@@ -2509,7 +2509,10 @@ public abstract class Context {
     * {@link ComponentName} of the actual service that was started is
     * returned; else if the service does not exist null is returned.
     *
     * @throws SecurityException  
     * @throws SecurityException If the caller does not permission to access the service
     * or the service can not be found.
     * @throws IllegalStateException If the application is in a state where the service
     * can not be started (such as not in the foreground in a state when services are allowed).
     *
     * @see #stopService
     * @see #bindService
@@ -2550,7 +2553,10 @@ public abstract class Context {
     * @return If there is a service matching the given Intent that is already
     * running, then it is stopped and {@code true} is returned; else {@code false} is returned.
     *
     * @throws SecurityException  
     * @throws SecurityException If the caller does not permission to access the service
     * or the service can not be found.
     * @throws IllegalStateException If the application is in a state where the service
     * can not be started (such as not in the foreground in a state when services are allowed).
     *
     * @see #startService
     */
@@ -2612,7 +2618,8 @@ public abstract class Context {
     *         {@code false} is returned if the connection is not made so you will not
     *         receive the service object.
     *
     * @throws SecurityException  
     * @throws SecurityException If the caller does not permission to access the service
     * or the service can not be found.
     *
     * @see #unbindService
     * @see #startService
+34 −6
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server;

import android.Manifest;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.AlarmManager;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
@@ -114,6 +115,7 @@ public class DeviceIdleController extends SystemService

    private AlarmManager mAlarmManager;
    private IBatteryStats mBatteryStats;
    private ActivityManagerInternal mLocalActivityManager;
    private PowerManagerInternal mLocalPowerManager;
    private PowerManager mPowerManager;
    private ConnectivityService mConnectivityService;
@@ -1373,6 +1375,7 @@ public class DeviceIdleController extends SystemService
            synchronized (this) {
                mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
                mBatteryStats = BatteryStatsService.getService();
                mLocalActivityManager = getLocalService(ActivityManagerInternal.class);
                mLocalPowerManager = getLocalService(PowerManagerInternal.class);
                mPowerManager = getContext().getSystemService(PowerManager.class);
                mActiveIdleWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
@@ -1442,6 +1445,7 @@ public class DeviceIdleController extends SystemService
                filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
                getContext().registerReceiver(mReceiver, filter);

                mLocalActivityManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
                mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
                mLocalAlarmManager.setDeviceIdleUserWhitelist(mPowerSaveWhitelistUserAppIdArray);
                mDisplayManager.registerDisplayListener(mDisplayListener, null);
@@ -1663,7 +1667,7 @@ public class DeviceIdleController extends SystemService
                } catch (RemoteException e) {
                }
                postTempActiveTimeoutMessage(appId, duration);
                updateTempWhitelistAppIdsLocked();
                updateTempWhitelistAppIdsLocked(appId, true);
                if (mNetworkPolicyTempWhitelistCallback != null) {
                    if (!sync) {
                        mHandler.post(mNetworkPolicyTempWhitelistCallback);
@@ -1709,7 +1713,7 @@ public class DeviceIdleController extends SystemService
                if (DEBUG) {
                    Slog.d(TAG, "Removing UID " + uid + " from temp whitelist");
                }
                updateTempWhitelistAppIdsLocked();
                updateTempWhitelistAppIdsLocked(uid, false);
                if (mNetworkPolicyTempWhitelistCallback != null) {
                    mHandler.post(mNetworkPolicyTempWhitelistCallback);
                }
@@ -2329,6 +2333,13 @@ public class DeviceIdleController extends SystemService
                mPowerSaveWhitelistUserApps, mPowerSaveWhitelistAllAppIds);
        mPowerSaveWhitelistUserAppIdArray = buildAppIdArray(null,
                mPowerSaveWhitelistUserApps, mPowerSaveWhitelistUserAppIds);
        if (mLocalActivityManager != null) {
            if (DEBUG) {
                Slog.d(TAG, "Setting activity manager whitelist to "
                        + Arrays.toString(mPowerSaveWhitelistAllAppIdArray));
            }
            mLocalActivityManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
        }
        if (mLocalPowerManager != null) {
            if (DEBUG) {
                Slog.d(TAG, "Setting wakelock whitelist to "
@@ -2345,7 +2356,7 @@ public class DeviceIdleController extends SystemService
        }
    }

    private void updateTempWhitelistAppIdsLocked() {
    private void updateTempWhitelistAppIdsLocked(int appId, boolean adding) {
        final int size = mTempWhitelistAppIdEndTimes.size();
        if (mTempWhitelistAppIdArray.length != size) {
            mTempWhitelistAppIdArray = new int[size];
@@ -2353,6 +2364,14 @@ public class DeviceIdleController extends SystemService
        for (int i = 0; i < size; i++) {
            mTempWhitelistAppIdArray[i] = mTempWhitelistAppIdEndTimes.keyAt(i);
        }
        if (mLocalActivityManager != null) {
            if (DEBUG) {
                Slog.d(TAG, "Setting activity manager temp whitelist to "
                        + Arrays.toString(mTempWhitelistAppIdArray));
            }
            mLocalActivityManager.updateDeviceIdleTempWhitelist(mTempWhitelistAppIdArray, appId,
                    adding);
        }
        if (mLocalPowerManager != null) {
            if (DEBUG) {
                Slog.d(TAG, "Setting wakelock temp whitelist to "
@@ -2523,8 +2542,9 @@ public class DeviceIdleController extends SystemService
        pw.println("    Add (prefix with +) or remove (prefix with -) packages.");
        pw.println("  tempwhitelist");
        pw.println("    Print packages that are temporarily whitelisted.");
        pw.println("  tempwhitelist [-u] [package ..]");
        pw.println("    Temporarily place packages in whitelist for 10 seconds.");
        pw.println("  tempwhitelist [-u USER] [-d DURATION] [package ..]");
        pw.println("    Temporarily place packages in whitelist for DURATION milliseconds.");
        pw.println("    If no DURATION is specified, 10 seconds is used");
    }

    class Shell extends ShellCommand {
@@ -2807,6 +2827,7 @@ public class DeviceIdleController extends SystemService
                }
            }
        } else if ("tempwhitelist".equals(cmd)) {
            long duration = 10000;
            String opt;
            while ((opt=shell.getNextOption()) != null) {
                if ("-u".equals(opt)) {
@@ -2816,12 +2837,19 @@ public class DeviceIdleController extends SystemService
                        return -1;
                    }
                    shell.userId = Integer.parseInt(opt);
                } else if ("-d".equals(opt)) {
                    opt = shell.getNextArg();
                    if (opt == null) {
                        pw.println("-d requires a duration");
                        return -1;
                    }
                    duration = Long.parseLong(opt);
                }
            }
            String arg = shell.getNextArg();
            if (arg != null) {
                try {
                    addPowerSaveTempWhitelistAppChecked(arg, 10000L, shell.userId, "shell");
                    addPowerSaveTempWhitelistAppChecked(arg, duration, shell.userId, "shell");
                } catch (RemoteException re) {
                    pw.println("Failed: " + re);
                }
Loading