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

Commit d5c7dc04 authored by Jing Ji's avatar Jing Ji Committed by Android (Google) Code Review
Browse files

Merge "Kill process if it's cached & idle and in forced-app-standby mode" into sc-dev

parents 919348e6 6cf25139
Loading
Loading
Loading
Loading
+18 −8
Original line number Diff line number Diff line
@@ -25,19 +25,29 @@ public interface AppStateTracker {
    String TAG = "AppStateTracker";

    /**
     * Register a {@link ServiceStateListener} to listen for forced-app-standby changes that should
     * affect services.
     * Register a {@link ForcedAppStandbyListener} to listen for forced-app-standby changes that
     * should affect services etc.
     */
    void addServiceStateListener(@NonNull ServiceStateListener listener);
    void addForcedAppStandbyListener(@NonNull ForcedAppStandbyListener listener);

    /**
     * A listener to listen to forced-app-standby changes that should affect services.
     * @return {code true} if the given UID/package has been in forced app standby mode.
     */
    interface ServiceStateListener {
    boolean isAppInForcedAppStandby(int uid, @NonNull String packageName);

    /**
     * A listener to listen to forced-app-standby changes that should affect services etc.
     */
    interface ForcedAppStandbyListener {
        /**
         * Called when an app goes in/out of forced app standby.
         */
        void updateForceAppStandbyForUidPackage(int uid, String packageName, boolean standby);

        /**
         * Called when an app goes into forced app standby and its foreground
         * services need to be removed from that state.
         * Called when all apps' forced-app-standby states need to be re-evaluated, due to
         * enable/disable certain feature flags.
         */
        void stopForegroundServicesForUidPackage(int uid, String packageName);
        void updateForcedAppStandbyForAllApps();
    }
}
+85 −10
Original line number Diff line number Diff line
@@ -60,8 +60,10 @@ import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;

import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * Class to keep track of the information related to "force app standby", which includes:
@@ -160,16 +162,46 @@ public class AppStateTrackerImpl implements AppStateTracker {
    @GuardedBy("mLock")
    boolean mForcedAppStandbyEnabled;

    /**
     * A lock-free set of (uid, packageName) pairs in forced app standby mode.
     *
     * <p>
     * It's bascially shadowing the {@link #mRunAnyRestrictedPackages} together with
     * the {@link #mForcedAppStandbyEnabled} and the {@link #mForceAllAppsStandby} - mutations on
     * them would result in copy-on-write.
     *
     * Note: when {@link #mForcedAppStandbyEnabled} is {@code false}, it'll be set to an empty set.
     *       when {@link #mForceAllAppsStandby} is {@code true}, it'll be set to null;
     * </p>
     */
    volatile Set<Pair<Integer, String>> mForcedAppStandbyUidPackages = Collections.emptySet();

    @Override
    public void addServiceStateListener(@NonNull ServiceStateListener listener) {
    public void addForcedAppStandbyListener(@NonNull ForcedAppStandbyListener listener) {
        addListener(new Listener() {
            @Override
            public void stopForegroundServicesForUidPackage(int uid, String packageName) {
                listener.stopForegroundServicesForUidPackage(uid, packageName);
            public void updateForceAppStandbyForUidPackage(int uid, String packageName,
                    boolean standby) {
                listener.updateForceAppStandbyForUidPackage(uid, packageName, standby);
            }

            @Override
            public void updateForcedAppStandbyForAllApps() {
                listener.updateForcedAppStandbyForAllApps();
            }
        });
    }

    @Override
    public boolean isAppInForcedAppStandby(int uid, @NonNull String packageName) {
        final Set<Pair<Integer, String>> fasUidPkgs = mForcedAppStandbyUidPackages;
        if (fasUidPkgs == null) {
            // Meaning the mForceAllAppsStandby is true.
            return true;
        }
        return fasUidPkgs.contains(Pair.create(uid, packageName));
    }

    interface Stats {
        int UID_FG_STATE_CHANGED = 0;
        int UID_ACTIVE_STATE_CHANGED = 1;
@@ -233,6 +265,7 @@ public class AppStateTrackerImpl implements AppStateTracker {
                        return;
                    }
                    mForcedAppStandbyEnabled = enabled;
                    updateForcedAppStandbyUidPackagesLocked();
                    if (DEBUG) {
                        Slog.d(TAG, "Forced app standby feature flag changed: "
                                + mForcedAppStandbyEnabled);
@@ -277,7 +310,11 @@ public class AppStateTrackerImpl implements AppStateTracker {
            if (!sender.isRunAnyInBackgroundAppOpsAllowed(uid, packageName)) {
                Slog.v(TAG, "Package " + packageName + "/" + uid
                        + " toggled into fg service restriction");
                stopForegroundServicesForUidPackage(uid, packageName);
                updateForceAppStandbyForUidPackage(uid, packageName, true);
            } else {
                Slog.v(TAG, "Package " + packageName + "/" + uid
                        + " toggled out of fg service restriction");
                updateForceAppStandbyForUidPackage(uid, packageName, false);
            }
        }

@@ -342,6 +379,7 @@ public class AppStateTrackerImpl implements AppStateTracker {
        private void onForceAllAppsStandbyChanged(AppStateTrackerImpl sender) {
            updateAllJobs();
            updateAllAlarms();
            updateForcedAppStandbyForAllApps();
        }

        /**
@@ -366,10 +404,17 @@ public class AppStateTrackerImpl implements AppStateTracker {
        }

        /**
         * Called when an app goes into forced app standby and its foreground
         * services need to be removed from that state.
         * Called when an app goes in/out of forced app standby.
         */
        public void stopForegroundServicesForUidPackage(int uid, String packageName) {
        public void updateForceAppStandbyForUidPackage(int uid, String packageName,
                boolean standby) {
        }

        /**
         * Called when all apps' forced-app-standby states need to be re-evaluated due to changes of
         * feature flags such as {@link #mForcedAppStandbyEnabled} or {@link #mForceAllAppsStandby}.
         */
        public void updateForcedAppStandbyForAllApps() {
        }

        /**
@@ -438,10 +483,13 @@ public class AppStateTrackerImpl implements AppStateTracker {
                        final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
                        // No need to notify for state change as all the alarms and jobs should be
                        // removed too.
                        synchronized (mLock) {
                            mExemptedBucketPackages.remove(userId, pkgName);
                            mRunAnyRestrictedPackages.remove(Pair.create(uid, pkgName));
                            updateForcedAppStandbyUidPackagesLocked();
                            mActiveUids.delete(uid);
                        }
                    }
                    break;
            }
        }
@@ -580,6 +628,29 @@ public class AppStateTrackerImpl implements AppStateTracker {
                }
            }
        }
        updateForcedAppStandbyUidPackagesLocked();
    }

    /**
     * Update the {@link #mForcedAppStandbyUidPackages} upon mutations on
     * {@link #mRunAnyRestrictedPackages}, {@link #mForcedAppStandbyEnabled} or
     * {@link #mForceAllAppsStandby}.
     */
    @GuardedBy("mLock")
    private void updateForcedAppStandbyUidPackagesLocked() {
        if (!mForcedAppStandbyEnabled) {
            mForcedAppStandbyUidPackages = Collections.emptySet();
            return;
        }
        if (mForceAllAppsStandby) {
            mForcedAppStandbyUidPackages = null;
            return;
        }
        Set<Pair<Integer, String>> fasUidPkgs = new ArraySet<>();
        for (int i = 0, size = mRunAnyRestrictedPackages.size(); i < size; i++) {
            fasUidPkgs.add(mRunAnyRestrictedPackages.valueAt(i));
        }
        mForcedAppStandbyUidPackages = Collections.unmodifiableSet(fasUidPkgs);
    }

    private void updateForceAllAppStandbyState() {
@@ -601,6 +672,7 @@ public class AppStateTrackerImpl implements AppStateTracker {
            return;
        }
        mForceAllAppsStandby = enable;
        updateForcedAppStandbyUidPackagesLocked();

        mHandler.notifyForceAllAppsStandbyChanged();
    }
@@ -645,6 +717,7 @@ public class AppStateTrackerImpl implements AppStateTracker {
        } else {
            mRunAnyRestrictedPackages.removeAt(index);
        }
        updateForcedAppStandbyUidPackagesLocked();
        return true;
    }

@@ -896,6 +969,7 @@ public class AppStateTrackerImpl implements AppStateTracker {
                        if (unblockAlarms) {
                            l.unblockAllUnrestrictedAlarms();
                        }
                        l.updateForcedAppStandbyForAllApps();
                    }
                    mStatLogger.logDurationStat(
                            Stats.FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED, start);
@@ -966,6 +1040,7 @@ public class AppStateTrackerImpl implements AppStateTracker {
                    mRunAnyRestrictedPackages.removeAt(i);
                }
            }
            updateForcedAppStandbyUidPackagesLocked();
            cleanUpArrayForUser(mActiveUids, removedUserId);
            mExemptedBucketPackages.remove(removedUserId);
        }
+9 −0
Original line number Diff line number Diff line
@@ -325,6 +325,15 @@ public final class ApplicationExitInfo implements Parcelable {
     */
    public static final int SUBREASON_ISOLATED_NOT_NEEDED = 17;

    /**
     * The process was killed because it's in forced-app-standby state, and it's cached and
     * its uid state is idle; this would be set only when the reason is {@link #REASON_OTHER}.
     *
     * For internal use only.
     * @hide
     */
    public static final int SUBREASON_CACHED_IDLE_FORCED_APP_STANDBY = 18;

    // If there is any OEM code which involves additional app kill reasons, it should
    // be categorized in {@link #REASON_OTHER}, with subreason code starting from 1000.

+7 −2
Original line number Diff line number Diff line
@@ -213,10 +213,15 @@ enum AppExitSubReasonCode {
     * The process was killed because it's isolated and was in a cached state.
     */
    SUBREASON_ISOLATED_NOT_NEEDED = 17;
}

    /**
 * The relative importance level that the system places on a process.
     * The process was killed because it's in forced-app-standby state, and it's cached and
     * its uid state is idle; this would be set only when the reason is {@link #REASON_OTHER}.
     */
    SUBREASON_CACHED_IDLE_FORCED_APP_STANDBY = 18;
}

/** * The relative importance level that the system places on a process.
 * Keep sync with the definitions in
 * {@link android.app.ActivityManager.RunningAppProcessInfo}
 */
+16 −4
Original line number Diff line number Diff line
@@ -309,12 +309,24 @@ public final class ActiveServices {
     * Watch for apps being put into forced app standby, so we can step their fg
     * services down.
     */
    class ForcedStandbyListener implements AppStateTracker.ServiceStateListener {
    class ForcedStandbyListener implements AppStateTracker.ForcedAppStandbyListener {
        @Override
        public void stopForegroundServicesForUidPackage(final int uid, final String packageName) {
        public void updateForceAppStandbyForUidPackage(int uid, String packageName,
                boolean standby) {
            synchronized (mAm) {
                if (standby) {
                    stopAllForegroundServicesLocked(uid, packageName);
                }
                mAm.mProcessList.updateForceAppStandbyForUidPackageLocked(
                        uid, packageName, standby);
            }
        }

        @Override
        public void updateForcedAppStandbyForAllApps() {
            synchronized (mAm) {
                mAm.mProcessList.updateForcedAppStandbyForAllAppsLocked();
            }
        }
    }

@@ -499,7 +511,7 @@ public final class ActiveServices {

    void systemServicesReady() {
        AppStateTracker ast = LocalServices.getService(AppStateTracker.class);
        ast.addServiceStateListener(new ForcedStandbyListener());
        ast.addForcedAppStandbyListener(new ForcedStandbyListener());
        mAppWidgetManagerInternal = LocalServices.getService(AppWidgetManagerInternal.class);
        setAllowListWhileInUsePermissionInFgs();
    }
Loading