import static android.app.usage.UsageStatsManager.REASON_TIMEOUT;
import static android.app.usage.UsageStatsManager.REASON_USAGE;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_ACTIVE;
+import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_EXEMPTED;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_FREQUENT;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_NEVER;
import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doReturn;
private static final String PACKAGE_1 = "com.example.foo";
private static final int UID_1 = 10000;
+ private static final String PACKAGE_EXEMPTED_1 = "com.android.exempted";
+ private static final int UID_EXEMPTED_1 = 10001;
private static final int USER_ID = 0;
private static final int USER_ID2 = 10;
List<String> mPowerSaveWhitelistExceptIdle = new ArrayList<>();
boolean mDisplayOn;
DisplayManager.DisplayListener mDisplayListener;
- String mBoundWidgetPackage;
+ String mBoundWidgetPackage = PACKAGE_EXEMPTED_1;
MyInjector(Context context, Looper looper) {
super(context, looper);
pi.packageName = PACKAGE_1;
packages.add(pi);
+ PackageInfo pie = new PackageInfo();
+ pie.applicationInfo = new ApplicationInfo();
+ pie.applicationInfo.uid = UID_EXEMPTED_1;
+ pie.packageName = PACKAGE_EXEMPTED_1;
+ packages.add(pie);
+
doReturn(packages).when(mockPm).getInstalledPackagesAsUser(anyInt(), anyInt());
try {
- doReturn(UID_1).when(mockPm).getPackageUidAsUser(anyString(), anyInt(), anyInt());
- doReturn(pi.applicationInfo).when(mockPm).getApplicationInfo(anyString(), anyInt());
+ doReturn(UID_1).when(mockPm).getPackageUidAsUser(eq(PACKAGE_1), anyInt(), anyInt());
+ doReturn(UID_EXEMPTED_1).when(mockPm).getPackageUidAsUser(eq(PACKAGE_EXEMPTED_1),
+ anyInt(), anyInt());
+ doReturn(pi.applicationInfo).when(mockPm).getApplicationInfo(eq(pi.packageName),
+ anyInt());
+ doReturn(pie.applicationInfo).when(mockPm).getApplicationInfo(eq(pie.packageName),
+ anyInt());
} catch (PackageManager.NameNotFoundException nnfe) {}
}
private AppStandbyController setupController() throws Exception {
mInjector.mElapsedRealtime = 0;
+ setupPm(mInjector.getContext().getPackageManager());
AppStandbyController controller = new AppStandbyController(mInjector);
+ controller.initializeDefaultsForSystemApps(USER_ID);
controller.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
controller.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
mInjector.setDisplayOn(false);
mInjector.setDisplayOn(true);
setChargingState(controller, false);
- setupPm(mInjector.getContext().getPackageManager());
controller.checkIdleStates(USER_ID);
+ assertEquals(STANDBY_BUCKET_EXEMPTED,
+ controller.getAppStandbyBucket(PACKAGE_EXEMPTED_1, USER_ID,
+ mInjector.mElapsedRealtime, false));
+ assertNotEquals(STANDBY_BUCKET_EXEMPTED,
+ controller.getAppStandbyBucket(PACKAGE_1, USER_ID,
+ mInjector.mElapsedRealtime, false));
return controller;
}
}
if (timeout > elapsedRealtime) {
// Convert to elapsed timebase
- appUsageHistory.bucketTimeoutTime = mElapsedDuration + (timeout - mElapsedSnapshot);
+ appUsageHistory.bucketTimeoutTime =
+ Math.max(appUsageHistory.bucketTimeoutTime,
+ mElapsedDuration + (timeout - mElapsedSnapshot));
}
}
appUsageHistory.bucketingReason = REASON_USAGE;
boolean mCharging;
private long mLastAppIdleParoledTime;
private boolean mSystemServicesReady = false;
+ // There was a system update, defaults need to be initialized after services are ready
+ private boolean mPendingInitializeDefaults;
private final DeviceStateReceiver mDeviceStateReceiver;
public void onBootPhase(int phase) {
mInjector.onBootPhase(phase);
if (phase == PHASE_SYSTEM_SERVICES_READY) {
+ Slog.d(TAG, "Setting app idle enabled state");
setAppIdleEnabled(mInjector.isAppIdleEnabled());
// Observe changes to the threshold
SettingsObserver settingsObserver = new SettingsObserver(mHandler);
mAppIdleHistory.updateDisplay(isDisplayOn(), mInjector.elapsedRealtime());
}
+ mSystemServicesReady = true;
+
+ if (mPendingInitializeDefaults) {
+ initializeDefaultsForSystemApps(UserHandle.USER_SYSTEM);
+ }
+
if (mPendingOneTimeCheckIdleStates) {
postOneTimeCheckIdleStates();
}
-
- mSystemServicesReady = true;
} else if (phase == PHASE_BOOT_COMPLETED) {
setChargingState(mInjector.isCharging());
}
UserHandle.getAppId(pi.applicationInfo.uid),
userId);
if (DEBUG) {
- Slog.d(TAG, " Checking idle state for " + packageName);
+ Slog.d(TAG, " Checking idle state for " + packageName + " special=" +
+ isSpecial);
}
if (isSpecial) {
synchronized (mAppIdleLock) {
elapsedRealtime, bucket)) {
StandbyUpdateRecord r = StandbyUpdateRecord.obtain(packageName, userId,
bucket, userStartedInteracting);
+ if (DEBUG) Slog.d(TAG, "Standby bucket for " + packageName + "=" + bucket);
mHandler.sendMessage(mHandler.obtainMessage(MSG_INFORM_LISTENERS,
StandbyUpdateRecord.obtain(packageName, userId,
bucket, userStartedInteracting)));
}
void initializeDefaultsForSystemApps(int userId) {
- Slog.d(TAG, "Initializing defaults for system apps on user " + userId);
+ if (!mSystemServicesReady) {
+ // Do it later, since SettingsProvider wasn't queried yet for app_standby_enabled
+ mPendingInitializeDefaults = true;
+ return;
+ }
+ Slog.d(TAG, "Initializing defaults for system apps on user " + userId + ", "
+ + "appIdleEnabled=" + mAppIdleEnabled);
final long elapsedRealtime = mInjector.elapsedRealtime();
List<PackageInfo> packages = mPackageManager.getInstalledPackagesAsUser(
PackageManager.MATCH_DISABLED_COMPONENTS,
// past usage pattern was.
mAppIdleHistory.reportUsage(packageName, userId, STANDBY_BUCKET_ACTIVE, 0,
elapsedRealtime + 4 * ONE_HOUR);
- if (isAppSpecial(packageName, UserHandle.getAppId(pi.applicationInfo.uid),
- userId)) {
- mAppIdleHistory.setAppStandbyBucket(packageName, userId, elapsedRealtime,
- STANDBY_BUCKET_EXEMPTED, REASON_DEFAULT);
- }
}
}
}