Loading apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java +1 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,7 @@ public interface AppStandbyInternal { /** * Checks if an app has been idle for a while and filters out apps that are excluded. * It returns false if the current system state allows all apps to be considered active. * This happens if the device is plugged in or otherwise temporarily allowed to make exceptions. * Called by interface impls. */ boolean isAppIdleFiltered(String packageName, int appId, int userId, Loading apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java +44 −9 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RESTRICTED; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_WORKING_SET; import static com.android.server.SystemService.PHASE_BOOT_COMPLETED; import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY; import android.annotation.NonNull; Loading @@ -71,9 +72,8 @@ import android.content.pm.ParceledListSlice; import android.database.ContentObserver; import android.hardware.display.DisplayManager; import android.net.ConnectivityManager; import android.net.Network; import android.net.NetworkRequest; import android.net.NetworkScoreManager; import android.os.BatteryManager; import android.os.BatteryStats; import android.os.Build; import android.os.Environment; Loading Loading @@ -285,6 +285,7 @@ public class AppStandbyController implements AppStandbyInternal { long mInitialForegroundServiceStartTimeoutMillis; private volatile boolean mAppIdleEnabled; private boolean mIsCharging; private boolean mSystemServicesReady = false; // There was a system update, defaults need to be initialized after services are ready private boolean mPendingInitializeDefaults; Loading Loading @@ -360,6 +361,11 @@ public class AppStandbyController implements AppStandbyInternal { mHandler = new AppStandbyHandler(mInjector.getLooper()); mPackageManager = mContext.getPackageManager(); DeviceStateReceiver deviceStateReceiver = new DeviceStateReceiver(); IntentFilter deviceStates = new IntentFilter(BatteryManager.ACTION_CHARGING); deviceStates.addAction(BatteryManager.ACTION_DISCHARGING); mContext.registerReceiver(deviceStateReceiver, deviceStates); synchronized (mAppIdleLock) { mAppIdleHistory = new AppIdleHistory(mInjector.getDataSystemDirectory(), mInjector.elapsedRealtime()); Loading Loading @@ -417,6 +423,8 @@ public class AppStandbyController implements AppStandbyInternal { if (mPendingOneTimeCheckIdleStates) { postOneTimeCheckIdleStates(); } } else if (phase == PHASE_BOOT_COMPLETED) { setChargingState(mInjector.isCharging()); } } Loading Loading @@ -515,6 +523,16 @@ public class AppStandbyController implements AppStandbyInternal { appUsage.bucketingReason, false); } @VisibleForTesting void setChargingState(boolean isCharging) { synchronized (mAppIdleLock) { if (mIsCharging != isCharging) { if (DEBUG) Slog.d(TAG, "Setting mIsCharging to " + isCharging); mIsCharging = isCharging; } } } @Override public void postCheckIdleStates(int userId) { mHandler.sendMessage(mHandler.obtainMessage(MSG_CHECK_IDLE_STATES, userId, 0)); Loading Loading @@ -977,6 +995,11 @@ public class AppStandbyController implements AppStandbyInternal { if (isAppSpecial(packageName, appId, userId)) { return false; } else { synchronized (mAppIdleLock) { if (!mAppIdleEnabled || mIsCharging) { return false; } } return isAppIdleUnfiltered(packageName, userId, elapsedRealtime); } } Loading Loading @@ -1543,6 +1566,8 @@ public class AppStandbyController implements AppStandbyInternal { pw.println(); pw.print("mAppIdleEnabled="); pw.print(mAppIdleEnabled); pw.print(" mIsCharging="); pw.print(mIsCharging); pw.println(); pw.print("mScreenThresholds="); pw.println(Arrays.toString(mAppStandbyScreenThresholds)); pw.print("mElapsedThresholds="); pw.println(Arrays.toString(mAppStandbyElapsedThresholds)); Loading @@ -1560,6 +1585,7 @@ public class AppStandbyController implements AppStandbyInternal { private final Looper mLooper; private IDeviceIdleController mDeviceIdleController; private IBatteryStats mBatteryStats; private BatteryManager mBatteryManager; private PackageManagerInternal mPackageManagerInternal; private DisplayManager mDisplayManager; private PowerManager mPowerManager; Loading Loading @@ -1593,6 +1619,7 @@ public class AppStandbyController implements AppStandbyInternal { mDisplayManager = (DisplayManager) mContext.getSystemService( Context.DISPLAY_SERVICE); mPowerManager = mContext.getSystemService(PowerManager.class); mBatteryManager = mContext.getSystemService(BatteryManager.class); final ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); Loading Loading @@ -1630,6 +1657,10 @@ public class AppStandbyController implements AppStandbyInternal { return buildFlag && runtimeFlag; } boolean isCharging() { return mBatteryManager.isCharging(); } boolean isPowerSaveWhitelistExceptIdleApp(String packageName) throws RemoteException { return mDeviceIdleController.isPowerSaveWhitelistExceptIdleApp(packageName); } Loading Loading @@ -1766,15 +1797,19 @@ public class AppStandbyController implements AppStandbyInternal { } }; private final NetworkRequest mNetworkRequest = new NetworkRequest.Builder().build(); private final ConnectivityManager.NetworkCallback mNetworkCallback = new ConnectivityManager.NetworkCallback() { private class DeviceStateReceiver extends BroadcastReceiver { @Override public void onAvailable(Network network) { mConnectivityManager.unregisterNetworkCallback(this); public void onReceive(Context context, Intent intent) { switch (intent.getAction()) { case BatteryManager.ACTION_CHARGING: setChargingState(true); break; case BatteryManager.ACTION_DISCHARGING: setChargingState(false); break; } } } }; private final DisplayManager.DisplayListener mDisplayListener = new DisplayManager.DisplayListener() { Loading core/java/android/app/usage/UsageStatsManager.java +2 −1 Original line number Diff line number Diff line Loading @@ -599,7 +599,8 @@ public final class UsageStatsManager { /** * Returns whether the specified app is currently considered inactive. This will be true if the * app hasn't been used directly or indirectly for a period of time defined by the system. This * could be of the order of several hours or days. * could be of the order of several hours or days. Apps are not considered inactive when the * device is charging. * @param packageName The package name of the app to query * @return whether the app is currently considered inactive */ Loading services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java +54 −0 Original line number Diff line number Diff line Loading @@ -145,6 +145,7 @@ public class AppStandbyControllerTests { static class MyInjector extends AppStandbyController.Injector { long mElapsedRealtime; boolean mIsAppIdleEnabled = true; boolean mIsCharging; List<String> mPowerSaveWhitelistExceptIdle = new ArrayList<>(); boolean mDisplayOn; DisplayManager.DisplayListener mDisplayListener; Loading Loading @@ -178,6 +179,11 @@ public class AppStandbyControllerTests { return mIsAppIdleEnabled; } @Override boolean isCharging() { return mIsCharging; } @Override boolean isPowerSaveWhitelistExceptIdleApp(String packageName) throws RemoteException { return mPowerSaveWhitelistExceptIdle.contains(packageName); Loading Loading @@ -281,6 +287,13 @@ public class AppStandbyControllerTests { } catch (PackageManager.NameNotFoundException nnfe) {} } private void setChargingState(AppStandbyController controller, boolean charging) { mInjector.mIsCharging = charging; if (controller != null) { controller.setChargingState(charging); } } private void setAppIdleEnabled(AppStandbyController controller, boolean enabled) { mInjector.mIsAppIdleEnabled = enabled; if (controller != null) { Loading @@ -297,6 +310,7 @@ public class AppStandbyControllerTests { controller.onBootPhase(SystemService.PHASE_BOOT_COMPLETED); mInjector.setDisplayOn(false); mInjector.setDisplayOn(true); setChargingState(controller, false); controller.checkIdleStates(USER_ID); assertNotEquals(STANDBY_BUCKET_EXEMPTED, controller.getAppStandbyBucket(PACKAGE_1, USER_ID, Loading Loading @@ -324,6 +338,46 @@ public class AppStandbyControllerTests { mInjector.mElapsedRealtime, false)); } @Test public void testIsAppIdle_Charging() throws Exception { setChargingState(mController, false); mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RARE, REASON_MAIN_FORCED_BY_SYSTEM); assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController, PACKAGE_1)); assertTrue(mController.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, 0)); assertTrue(mController.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, false)); setChargingState(mController, true); assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController, PACKAGE_1)); assertFalse(mController.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, 0)); assertFalse(mController.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, false)); setChargingState(mController, false); assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController, PACKAGE_1)); assertTrue(mController.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, 0)); assertTrue(mController.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, false)); } @Test public void testIsAppIdle_Enabled() throws Exception { setChargingState(mController, false); setAppIdleEnabled(mController, true); mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RARE, REASON_MAIN_FORCED_BY_SYSTEM); assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController, PACKAGE_1)); assertTrue(mController.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, 0)); assertTrue(mController.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, false)); setAppIdleEnabled(mController, false); assertFalse(mController.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, 0)); assertFalse(mController.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, false)); setAppIdleEnabled(mController, true); assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController, PACKAGE_1)); assertTrue(mController.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, 0)); assertTrue(mController.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, false)); } private void assertTimeout(AppStandbyController controller, long elapsedTime, int bucket) { mInjector.mElapsedRealtime = elapsedTime; controller.checkIdleStates(USER_ID); Loading Loading
apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java +1 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,7 @@ public interface AppStandbyInternal { /** * Checks if an app has been idle for a while and filters out apps that are excluded. * It returns false if the current system state allows all apps to be considered active. * This happens if the device is plugged in or otherwise temporarily allowed to make exceptions. * Called by interface impls. */ boolean isAppIdleFiltered(String packageName, int appId, int userId, Loading
apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java +44 −9 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RESTRICTED; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_WORKING_SET; import static com.android.server.SystemService.PHASE_BOOT_COMPLETED; import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY; import android.annotation.NonNull; Loading @@ -71,9 +72,8 @@ import android.content.pm.ParceledListSlice; import android.database.ContentObserver; import android.hardware.display.DisplayManager; import android.net.ConnectivityManager; import android.net.Network; import android.net.NetworkRequest; import android.net.NetworkScoreManager; import android.os.BatteryManager; import android.os.BatteryStats; import android.os.Build; import android.os.Environment; Loading Loading @@ -285,6 +285,7 @@ public class AppStandbyController implements AppStandbyInternal { long mInitialForegroundServiceStartTimeoutMillis; private volatile boolean mAppIdleEnabled; private boolean mIsCharging; private boolean mSystemServicesReady = false; // There was a system update, defaults need to be initialized after services are ready private boolean mPendingInitializeDefaults; Loading Loading @@ -360,6 +361,11 @@ public class AppStandbyController implements AppStandbyInternal { mHandler = new AppStandbyHandler(mInjector.getLooper()); mPackageManager = mContext.getPackageManager(); DeviceStateReceiver deviceStateReceiver = new DeviceStateReceiver(); IntentFilter deviceStates = new IntentFilter(BatteryManager.ACTION_CHARGING); deviceStates.addAction(BatteryManager.ACTION_DISCHARGING); mContext.registerReceiver(deviceStateReceiver, deviceStates); synchronized (mAppIdleLock) { mAppIdleHistory = new AppIdleHistory(mInjector.getDataSystemDirectory(), mInjector.elapsedRealtime()); Loading Loading @@ -417,6 +423,8 @@ public class AppStandbyController implements AppStandbyInternal { if (mPendingOneTimeCheckIdleStates) { postOneTimeCheckIdleStates(); } } else if (phase == PHASE_BOOT_COMPLETED) { setChargingState(mInjector.isCharging()); } } Loading Loading @@ -515,6 +523,16 @@ public class AppStandbyController implements AppStandbyInternal { appUsage.bucketingReason, false); } @VisibleForTesting void setChargingState(boolean isCharging) { synchronized (mAppIdleLock) { if (mIsCharging != isCharging) { if (DEBUG) Slog.d(TAG, "Setting mIsCharging to " + isCharging); mIsCharging = isCharging; } } } @Override public void postCheckIdleStates(int userId) { mHandler.sendMessage(mHandler.obtainMessage(MSG_CHECK_IDLE_STATES, userId, 0)); Loading Loading @@ -977,6 +995,11 @@ public class AppStandbyController implements AppStandbyInternal { if (isAppSpecial(packageName, appId, userId)) { return false; } else { synchronized (mAppIdleLock) { if (!mAppIdleEnabled || mIsCharging) { return false; } } return isAppIdleUnfiltered(packageName, userId, elapsedRealtime); } } Loading Loading @@ -1543,6 +1566,8 @@ public class AppStandbyController implements AppStandbyInternal { pw.println(); pw.print("mAppIdleEnabled="); pw.print(mAppIdleEnabled); pw.print(" mIsCharging="); pw.print(mIsCharging); pw.println(); pw.print("mScreenThresholds="); pw.println(Arrays.toString(mAppStandbyScreenThresholds)); pw.print("mElapsedThresholds="); pw.println(Arrays.toString(mAppStandbyElapsedThresholds)); Loading @@ -1560,6 +1585,7 @@ public class AppStandbyController implements AppStandbyInternal { private final Looper mLooper; private IDeviceIdleController mDeviceIdleController; private IBatteryStats mBatteryStats; private BatteryManager mBatteryManager; private PackageManagerInternal mPackageManagerInternal; private DisplayManager mDisplayManager; private PowerManager mPowerManager; Loading Loading @@ -1593,6 +1619,7 @@ public class AppStandbyController implements AppStandbyInternal { mDisplayManager = (DisplayManager) mContext.getSystemService( Context.DISPLAY_SERVICE); mPowerManager = mContext.getSystemService(PowerManager.class); mBatteryManager = mContext.getSystemService(BatteryManager.class); final ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); Loading Loading @@ -1630,6 +1657,10 @@ public class AppStandbyController implements AppStandbyInternal { return buildFlag && runtimeFlag; } boolean isCharging() { return mBatteryManager.isCharging(); } boolean isPowerSaveWhitelistExceptIdleApp(String packageName) throws RemoteException { return mDeviceIdleController.isPowerSaveWhitelistExceptIdleApp(packageName); } Loading Loading @@ -1766,15 +1797,19 @@ public class AppStandbyController implements AppStandbyInternal { } }; private final NetworkRequest mNetworkRequest = new NetworkRequest.Builder().build(); private final ConnectivityManager.NetworkCallback mNetworkCallback = new ConnectivityManager.NetworkCallback() { private class DeviceStateReceiver extends BroadcastReceiver { @Override public void onAvailable(Network network) { mConnectivityManager.unregisterNetworkCallback(this); public void onReceive(Context context, Intent intent) { switch (intent.getAction()) { case BatteryManager.ACTION_CHARGING: setChargingState(true); break; case BatteryManager.ACTION_DISCHARGING: setChargingState(false); break; } } } }; private final DisplayManager.DisplayListener mDisplayListener = new DisplayManager.DisplayListener() { Loading
core/java/android/app/usage/UsageStatsManager.java +2 −1 Original line number Diff line number Diff line Loading @@ -599,7 +599,8 @@ public final class UsageStatsManager { /** * Returns whether the specified app is currently considered inactive. This will be true if the * app hasn't been used directly or indirectly for a period of time defined by the system. This * could be of the order of several hours or days. * could be of the order of several hours or days. Apps are not considered inactive when the * device is charging. * @param packageName The package name of the app to query * @return whether the app is currently considered inactive */ Loading
services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java +54 −0 Original line number Diff line number Diff line Loading @@ -145,6 +145,7 @@ public class AppStandbyControllerTests { static class MyInjector extends AppStandbyController.Injector { long mElapsedRealtime; boolean mIsAppIdleEnabled = true; boolean mIsCharging; List<String> mPowerSaveWhitelistExceptIdle = new ArrayList<>(); boolean mDisplayOn; DisplayManager.DisplayListener mDisplayListener; Loading Loading @@ -178,6 +179,11 @@ public class AppStandbyControllerTests { return mIsAppIdleEnabled; } @Override boolean isCharging() { return mIsCharging; } @Override boolean isPowerSaveWhitelistExceptIdleApp(String packageName) throws RemoteException { return mPowerSaveWhitelistExceptIdle.contains(packageName); Loading Loading @@ -281,6 +287,13 @@ public class AppStandbyControllerTests { } catch (PackageManager.NameNotFoundException nnfe) {} } private void setChargingState(AppStandbyController controller, boolean charging) { mInjector.mIsCharging = charging; if (controller != null) { controller.setChargingState(charging); } } private void setAppIdleEnabled(AppStandbyController controller, boolean enabled) { mInjector.mIsAppIdleEnabled = enabled; if (controller != null) { Loading @@ -297,6 +310,7 @@ public class AppStandbyControllerTests { controller.onBootPhase(SystemService.PHASE_BOOT_COMPLETED); mInjector.setDisplayOn(false); mInjector.setDisplayOn(true); setChargingState(controller, false); controller.checkIdleStates(USER_ID); assertNotEquals(STANDBY_BUCKET_EXEMPTED, controller.getAppStandbyBucket(PACKAGE_1, USER_ID, Loading Loading @@ -324,6 +338,46 @@ public class AppStandbyControllerTests { mInjector.mElapsedRealtime, false)); } @Test public void testIsAppIdle_Charging() throws Exception { setChargingState(mController, false); mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RARE, REASON_MAIN_FORCED_BY_SYSTEM); assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController, PACKAGE_1)); assertTrue(mController.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, 0)); assertTrue(mController.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, false)); setChargingState(mController, true); assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController, PACKAGE_1)); assertFalse(mController.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, 0)); assertFalse(mController.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, false)); setChargingState(mController, false); assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController, PACKAGE_1)); assertTrue(mController.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, 0)); assertTrue(mController.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, false)); } @Test public void testIsAppIdle_Enabled() throws Exception { setChargingState(mController, false); setAppIdleEnabled(mController, true); mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RARE, REASON_MAIN_FORCED_BY_SYSTEM); assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController, PACKAGE_1)); assertTrue(mController.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, 0)); assertTrue(mController.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, false)); setAppIdleEnabled(mController, false); assertFalse(mController.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, 0)); assertFalse(mController.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, false)); setAppIdleEnabled(mController, true); assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController, PACKAGE_1)); assertTrue(mController.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, 0)); assertTrue(mController.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, false)); } private void assertTimeout(AppStandbyController controller, long elapsedTime, int bucket) { mInjector.mElapsedRealtime = elapsedTime; controller.checkIdleStates(USER_ID); Loading