FreezeService: keep UsageStats right at locking

to ensure "skipping foreground apps" still works - foreground state
cannot be detected after the screen being locked.
This commit is contained in:
Peter Cai 2019-01-23 11:08:27 +08:00
parent 8e07a2d143
commit bcbab7f7db
No known key found for this signature in database
GPG key ID: 71F5FB4E4F3FD54F

View file

@ -56,6 +56,17 @@ public class FreezeService extends Service {
private BroadcastReceiver mLockReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// Save usage statistics right now!
// We need to use the statics at this moment
// for "skipping foreground apps"
// No app is foreground after the screen is locked.
mScreenLockTime = new Date().getTime();
if (SettingsManager.getInstance().getSkipForegroundEnabled() &&
Utility.checkUsageStatsPermission(FreezeService.this)) {
UsageStatsManager usm = getSystemService(UsageStatsManager.class);
mUsageStats = usm.queryAndAggregateUsageStats(mScreenLockTime - APP_INACTIVE_TIMEOUT, mScreenLockTime);
}
// Delay the work so that it can be canceled if the screen
// gets unlocked before the delay passes
mHandler.postDelayed(mFreezeWork,
@ -73,6 +84,15 @@ public class FreezeService extends Service {
}
};
// Usage statistics when the screen was locked
// We keep it here since we need the data AT THE MOMENT when screen gets locked
// If we don't have the permission to use UsageStats
// or "do not freeze foreground apps" is not enabled,
// then we won't need any usage stats, so we just keep
// it empty in those cases
private Map<String, UsageStats> mUsageStats = new HashMap<>();
private long mScreenLockTime = -1;
// The handler and the delayed work to handle
private Handler mHandler = new Handler(Looper.getMainLooper());
private Runnable mFreezeWork = () -> {
@ -81,26 +101,12 @@ public class FreezeService extends Service {
unregisterReceiver(mUnlockReceiver);
if (sAppToFreeze.size() > 0) {
long now = new Date().getTime();
// Initialize with empty usage stats
// If we don't have the permission to use UsageStats
// or "do not freeze foreground apps" is not enabled,
// then we won't need any usage stats, so we just keep
// it empty in those cases
Map<String, UsageStats> allStats = new HashMap<>();
if (SettingsManager.getInstance().getSkipForegroundEnabled() &&
Utility.checkUsageStatsPermission(FreezeService.this)) {
UsageStatsManager usm = getSystemService(UsageStatsManager.class);
allStats = usm.queryAndAggregateUsageStats(now - APP_INACTIVE_TIMEOUT, now);
}
DevicePolicyManager dpm = getSystemService(DevicePolicyManager.class);
ComponentName adminComponent = new ComponentName(FreezeService.this, ShelterDeviceAdminReceiver.class);
for (String app : sAppToFreeze) {
boolean shouldFreeze = true;
UsageStats stats = allStats.get(app);
if (stats != null && now - stats.getLastTimeUsed() <= APP_INACTIVE_TIMEOUT &&
UsageStats stats = mUsageStats.get(app);
if (stats != null && mScreenLockTime - stats.getLastTimeUsed() <= APP_INACTIVE_TIMEOUT &&
stats.getTotalTimeInForeground() >= APP_INACTIVE_TIMEOUT) {
// Don't freeze foreground apps if requested
shouldFreeze = false;