1 /** 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy 6 * of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations 14 * under the License. 15 */ 16 17 package com.android.server.usage; 18 19 import android.Manifest; 20 import android.app.ActivityManager; 21 import android.app.AppGlobals; 22 import android.app.AppOpsManager; 23 import android.app.IUidObserver; 24 import android.app.admin.DevicePolicyManager; 25 import android.app.usage.ConfigurationStats; 26 import android.app.usage.IUsageStatsManager; 27 import android.app.usage.UsageEvents; 28 import android.app.usage.UsageEvents.Event; 29 import android.app.usage.UsageStats; 30 import android.app.usage.UsageStatsManagerInternal; 31 import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener; 32 import android.appwidget.AppWidgetManager; 33 import android.content.BroadcastReceiver; 34 import android.content.ComponentName; 35 import android.content.ContentResolver; 36 import android.content.Context; 37 import android.content.Intent; 38 import android.content.IntentFilter; 39 import android.content.pm.ApplicationInfo; 40 import android.content.pm.PackageInfo; 41 import android.content.pm.PackageManager; 42 import android.content.pm.PackageManagerInternal; 43 import android.content.pm.PackageManager.NameNotFoundException; 44 import android.content.pm.ParceledListSlice; 45 import android.content.pm.UserInfo; 46 import android.content.res.Configuration; 47 import android.database.ContentObserver; 48 import android.hardware.display.DisplayManager; 49 import android.net.NetworkScoreManager; 50 import android.os.BatteryManager; 51 import android.os.BatteryStats; 52 import android.os.Binder; 53 import android.os.Environment; 54 import android.os.FileUtils; 55 import android.os.Handler; 56 import android.os.IDeviceIdleController; 57 import android.os.Looper; 58 import android.os.Message; 59 import android.os.PowerManager; 60 import android.os.Process; 61 import android.os.RemoteException; 62 import android.os.ServiceManager; 63 import android.os.SystemClock; 64 import android.os.SystemProperties; 65 import android.os.UserHandle; 66 import android.os.UserManager; 67 import android.provider.Settings; 68 import android.telephony.TelephonyManager; 69 import android.util.ArraySet; 70 import android.util.KeyValueListParser; 71 import android.util.Slog; 72 import android.util.SparseArray; 73 import android.util.SparseIntArray; 74 import android.util.TimeUtils; 75 import android.view.Display; 76 77 import com.android.internal.annotations.GuardedBy; 78 import com.android.internal.app.IBatteryStats; 79 import com.android.internal.os.BackgroundThread; 80 import com.android.internal.os.SomeArgs; 81 import com.android.internal.util.ArrayUtils; 82 import com.android.internal.util.DumpUtils; 83 import com.android.internal.util.IndentingPrintWriter; 84 import com.android.server.LocalServices; 85 import com.android.server.SystemService; 86 87 import java.io.File; 88 import java.io.FileDescriptor; 89 import java.io.IOException; 90 import java.io.PrintWriter; 91 import java.util.ArrayList; 92 import java.util.Arrays; 93 import java.util.List; 94 95 /** 96 * A service that collects, aggregates, and persists application usage data. 97 * This data can be queried by apps that have been granted permission by AppOps. 98 */ 99 public class UsageStatsService extends SystemService implements 100 UserUsageStatsService.StatsUpdatedListener { 101 102 static final String TAG = "UsageStatsService"; 103 public static final boolean ENABLE_TIME_CHANGE_CORRECTION 104 = SystemProperties.getBoolean("persist.debug.time_correction", true); 105 106 static final boolean DEBUG = false; // Never submit with true 107 static final boolean COMPRESS_TIME = false; 108 109 private static final long TEN_SECONDS = 10 * 1000; 110 private static final long ONE_MINUTE = 60 * 1000; 111 private static final long TWENTY_MINUTES = 20 * 60 * 1000; 112 private static final long FLUSH_INTERVAL = COMPRESS_TIME ? TEN_SECONDS : TWENTY_MINUTES; 113 private static final long TIME_CHANGE_THRESHOLD_MILLIS = 2 * 1000; // Two seconds. 114 115 private static final boolean ENABLE_KERNEL_UPDATES = true; 116 private static final File KERNEL_COUNTER_FILE = new File("/proc/uid_procstat/set"); 117 118 long mAppIdleScreenThresholdMillis; 119 long mCheckIdleIntervalMillis; 120 long mAppIdleWallclockThresholdMillis; 121 long mAppIdleParoleIntervalMillis; 122 long mAppIdleParoleDurationMillis; 123 124 // Handler message types. 125 static final int MSG_REPORT_EVENT = 0; 126 static final int MSG_FLUSH_TO_DISK = 1; 127 static final int MSG_REMOVE_USER = 2; 128 static final int MSG_INFORM_LISTENERS = 3; 129 static final int MSG_FORCE_IDLE_STATE = 4; 130 static final int MSG_CHECK_IDLE_STATES = 5; 131 static final int MSG_CHECK_PAROLE_TIMEOUT = 6; 132 static final int MSG_PAROLE_END_TIMEOUT = 7; 133 static final int MSG_REPORT_CONTENT_PROVIDER_USAGE = 8; 134 static final int MSG_PAROLE_STATE_CHANGED = 9; 135 static final int MSG_ONE_TIME_CHECK_IDLE_STATES = 10; 136 137 private final Object mLock = new Object(); 138 Handler mHandler; 139 AppOpsManager mAppOps; 140 UserManager mUserManager; 141 PackageManager mPackageManager; 142 PackageManagerInternal mPackageManagerInternal; 143 AppWidgetManager mAppWidgetManager; 144 IDeviceIdleController mDeviceIdleController; 145 private DisplayManager mDisplayManager; 146 private PowerManager mPowerManager; 147 private IBatteryStats mBatteryStats; 148 149 private final SparseArray<UserUsageStatsService> mUserState = new SparseArray<>(); 150 private final SparseIntArray mUidToKernelCounter = new SparseIntArray(); 151 private File mUsageStatsDir; 152 long mRealTimeSnapshot; 153 long mSystemTimeSnapshot; 154 155 boolean mAppIdleEnabled; 156 boolean mAppIdleTempParoled; 157 boolean mCharging; 158 private long mLastAppIdleParoledTime; 159 160 private volatile boolean mPendingOneTimeCheckIdleStates; 161 private boolean mSystemServicesReady = false; 162 163 private final Object mAppIdleLock = new Object(); 164 @GuardedBy("mAppIdleLock") 165 private AppIdleHistory mAppIdleHistory; 166 167 @GuardedBy("mAppIdleLock") 168 private ArrayList<UsageStatsManagerInternal.AppIdleStateChangeListener> 169 mPackageAccessListeners = new ArrayList<>(); 170 171 @GuardedBy("mAppIdleLock") 172 private boolean mHaveCarrierPrivilegedApps; 173 @GuardedBy("mAppIdleLock") 174 private List<String> mCarrierPrivilegedApps; 175 UsageStatsService(Context context)176 public UsageStatsService(Context context) { 177 super(context); 178 } 179 180 @Override onStart()181 public void onStart() { 182 mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE); 183 mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE); 184 mPackageManager = getContext().getPackageManager(); 185 mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class); 186 mHandler = new H(BackgroundThread.get().getLooper()); 187 188 File systemDataDir = new File(Environment.getDataDirectory(), "system"); 189 mUsageStatsDir = new File(systemDataDir, "usagestats"); 190 mUsageStatsDir.mkdirs(); 191 if (!mUsageStatsDir.exists()) { 192 throw new IllegalStateException("Usage stats directory does not exist: " 193 + mUsageStatsDir.getAbsolutePath()); 194 } 195 196 IntentFilter filter = new IntentFilter(Intent.ACTION_USER_REMOVED); 197 filter.addAction(Intent.ACTION_USER_STARTED); 198 getContext().registerReceiverAsUser(new UserActionsReceiver(), UserHandle.ALL, filter, 199 null, mHandler); 200 201 IntentFilter packageFilter = new IntentFilter(); 202 packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED); 203 packageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED); 204 packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 205 packageFilter.addDataScheme("package"); 206 207 getContext().registerReceiverAsUser(new PackageReceiver(), UserHandle.ALL, packageFilter, 208 null, mHandler); 209 210 mAppIdleEnabled = getContext().getResources().getBoolean( 211 com.android.internal.R.bool.config_enableAutoPowerModes); 212 if (mAppIdleEnabled) { 213 IntentFilter deviceStates = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); 214 deviceStates.addAction(BatteryManager.ACTION_DISCHARGING); 215 deviceStates.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); 216 getContext().registerReceiver(new DeviceStateReceiver(), deviceStates); 217 } 218 219 synchronized (mLock) { 220 cleanUpRemovedUsersLocked(); 221 } 222 synchronized (mAppIdleLock) { 223 mAppIdleHistory = new AppIdleHistory(SystemClock.elapsedRealtime()); 224 } 225 226 mRealTimeSnapshot = SystemClock.elapsedRealtime(); 227 mSystemTimeSnapshot = System.currentTimeMillis(); 228 229 publishLocalService(UsageStatsManagerInternal.class, new LocalService()); 230 publishBinderService(Context.USAGE_STATS_SERVICE, new BinderService()); 231 } 232 233 @Override onBootPhase(int phase)234 public void onBootPhase(int phase) { 235 if (phase == PHASE_SYSTEM_SERVICES_READY) { 236 // Observe changes to the threshold 237 SettingsObserver settingsObserver = new SettingsObserver(mHandler); 238 settingsObserver.registerObserver(); 239 settingsObserver.updateSettings(); 240 241 mAppWidgetManager = getContext().getSystemService(AppWidgetManager.class); 242 mDeviceIdleController = IDeviceIdleController.Stub.asInterface( 243 ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER)); 244 mBatteryStats = IBatteryStats.Stub.asInterface( 245 ServiceManager.getService(BatteryStats.SERVICE_NAME)); 246 mDisplayManager = (DisplayManager) getContext().getSystemService( 247 Context.DISPLAY_SERVICE); 248 mPowerManager = getContext().getSystemService(PowerManager.class); 249 250 mDisplayManager.registerDisplayListener(mDisplayListener, mHandler); 251 synchronized (mAppIdleLock) { 252 mAppIdleHistory.updateDisplay(isDisplayOn(), SystemClock.elapsedRealtime()); 253 } 254 255 if (mPendingOneTimeCheckIdleStates) { 256 postOneTimeCheckIdleStates(); 257 } 258 259 if (ENABLE_KERNEL_UPDATES && KERNEL_COUNTER_FILE.exists()) { 260 try { 261 ActivityManager.getService().registerUidObserver(mUidObserver, 262 ActivityManager.UID_OBSERVER_PROCSTATE 263 | ActivityManager.UID_OBSERVER_GONE, 264 ActivityManager.PROCESS_STATE_UNKNOWN, null); 265 } catch (RemoteException e) { 266 throw new RuntimeException(e); 267 } 268 } else { 269 Slog.w(TAG, "Missing procfs interface: " + KERNEL_COUNTER_FILE); 270 } 271 272 mSystemServicesReady = true; 273 } else if (phase == PHASE_BOOT_COMPLETED) { 274 setChargingState(getContext().getSystemService(BatteryManager.class).isCharging()); 275 } 276 } 277 isDisplayOn()278 private boolean isDisplayOn() { 279 return mDisplayManager 280 .getDisplay(Display.DEFAULT_DISPLAY).getState() == Display.STATE_ON; 281 } 282 283 private class UserActionsReceiver extends BroadcastReceiver { 284 @Override onReceive(Context context, Intent intent)285 public void onReceive(Context context, Intent intent) { 286 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 287 final String action = intent.getAction(); 288 if (Intent.ACTION_USER_REMOVED.equals(action)) { 289 if (userId >= 0) { 290 mHandler.obtainMessage(MSG_REMOVE_USER, userId, 0).sendToTarget(); 291 } 292 } else if (Intent.ACTION_USER_STARTED.equals(action)) { 293 if (userId >=0) { 294 postCheckIdleStates(userId); 295 } 296 } 297 } 298 } 299 300 private class PackageReceiver extends BroadcastReceiver { 301 @Override onReceive(Context context, Intent intent)302 public void onReceive(Context context, Intent intent) { 303 final String action = intent.getAction(); 304 if (Intent.ACTION_PACKAGE_ADDED.equals(action) 305 || Intent.ACTION_PACKAGE_CHANGED.equals(action)) { 306 clearCarrierPrivilegedApps(); 307 } 308 if ((Intent.ACTION_PACKAGE_REMOVED.equals(action) || 309 Intent.ACTION_PACKAGE_ADDED.equals(action)) 310 && !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 311 clearAppIdleForPackage(intent.getData().getSchemeSpecificPart(), 312 getSendingUserId()); 313 } 314 } 315 } 316 317 private class DeviceStateReceiver extends BroadcastReceiver { 318 @Override onReceive(Context context, Intent intent)319 public void onReceive(Context context, Intent intent) { 320 final String action = intent.getAction(); 321 if (Intent.ACTION_BATTERY_CHANGED.equals(action)) { 322 setChargingState(intent.getIntExtra("plugged", 0) != 0); 323 } else if (PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED.equals(action)) { 324 onDeviceIdleModeChanged(); 325 } 326 } 327 } 328 329 private final DisplayManager.DisplayListener mDisplayListener 330 = new DisplayManager.DisplayListener() { 331 332 @Override public void onDisplayAdded(int displayId) { 333 } 334 335 @Override public void onDisplayRemoved(int displayId) { 336 } 337 338 @Override public void onDisplayChanged(int displayId) { 339 if (displayId == Display.DEFAULT_DISPLAY) { 340 final boolean displayOn = isDisplayOn(); 341 synchronized (UsageStatsService.this.mAppIdleLock) { 342 mAppIdleHistory.updateDisplay(displayOn, SystemClock.elapsedRealtime()); 343 } 344 } 345 } 346 }; 347 348 private final IUidObserver mUidObserver = new IUidObserver.Stub() { 349 @Override 350 public void onUidStateChanged(int uid, int procState, long procStateSeq) { 351 final int newCounter = (procState <= ActivityManager.PROCESS_STATE_TOP) ? 0 : 1; 352 synchronized (mUidToKernelCounter) { 353 final int oldCounter = mUidToKernelCounter.get(uid, 0); 354 if (newCounter != oldCounter) { 355 mUidToKernelCounter.put(uid, newCounter); 356 try { 357 FileUtils.stringToFile(KERNEL_COUNTER_FILE, uid + " " + newCounter); 358 } catch (IOException e) { 359 Slog.w(TAG, "Failed to update counter set: " + e); 360 } 361 } 362 } 363 } 364 365 @Override 366 public void onUidIdle(int uid, boolean disabled) { 367 // Ignored 368 } 369 370 @Override 371 public void onUidGone(int uid, boolean disabled) { 372 onUidStateChanged(uid, ActivityManager.PROCESS_STATE_NONEXISTENT, 0); 373 } 374 375 @Override 376 public void onUidActive(int uid) { 377 // Ignored 378 } 379 380 @Override public void onUidCachedChanged(int uid, boolean cached) { 381 } 382 }; 383 384 @Override onStatsUpdated()385 public void onStatsUpdated() { 386 mHandler.sendEmptyMessageDelayed(MSG_FLUSH_TO_DISK, FLUSH_INTERVAL); 387 } 388 389 @Override onStatsReloaded()390 public void onStatsReloaded() { 391 postOneTimeCheckIdleStates(); 392 } 393 394 @Override onNewUpdate(int userId)395 public void onNewUpdate(int userId) { 396 initializeDefaultsForSystemApps(userId); 397 } 398 initializeDefaultsForSystemApps(int userId)399 private void initializeDefaultsForSystemApps(int userId) { 400 Slog.d(TAG, "Initializing defaults for system apps on user " + userId); 401 final long elapsedRealtime = SystemClock.elapsedRealtime(); 402 List<PackageInfo> packages = mPackageManager.getInstalledPackagesAsUser( 403 PackageManager.MATCH_DISABLED_COMPONENTS, 404 userId); 405 final int packageCount = packages.size(); 406 synchronized (mAppIdleLock) { 407 for (int i = 0; i < packageCount; i++) { 408 final PackageInfo pi = packages.get(i); 409 String packageName = pi.packageName; 410 if (pi.applicationInfo != null && pi.applicationInfo.isSystemApp()) { 411 mAppIdleHistory.reportUsage(packageName, userId, elapsedRealtime); 412 } 413 } 414 } 415 } 416 shouldObfuscateInstantAppsForCaller(int callingUid, int userId)417 private boolean shouldObfuscateInstantAppsForCaller(int callingUid, int userId) { 418 return !mPackageManagerInternal.canAccessInstantApps(callingUid, userId); 419 } 420 clearAppIdleForPackage(String packageName, int userId)421 void clearAppIdleForPackage(String packageName, int userId) { 422 synchronized (mAppIdleLock) { 423 mAppIdleHistory.clearUsage(packageName, userId); 424 } 425 } 426 cleanUpRemovedUsersLocked()427 private void cleanUpRemovedUsersLocked() { 428 final List<UserInfo> users = mUserManager.getUsers(true); 429 if (users == null || users.size() == 0) { 430 throw new IllegalStateException("There can't be no users"); 431 } 432 433 ArraySet<String> toDelete = new ArraySet<>(); 434 String[] fileNames = mUsageStatsDir.list(); 435 if (fileNames == null) { 436 // No users to delete. 437 return; 438 } 439 440 toDelete.addAll(Arrays.asList(fileNames)); 441 442 final int userCount = users.size(); 443 for (int i = 0; i < userCount; i++) { 444 final UserInfo userInfo = users.get(i); 445 toDelete.remove(Integer.toString(userInfo.id)); 446 } 447 448 final int deleteCount = toDelete.size(); 449 for (int i = 0; i < deleteCount; i++) { 450 deleteRecursively(new File(mUsageStatsDir, toDelete.valueAt(i))); 451 } 452 } 453 setChargingState(boolean charging)454 void setChargingState(boolean charging) { 455 synchronized (mAppIdleLock) { 456 if (mCharging != charging) { 457 mCharging = charging; 458 postParoleStateChanged(); 459 } 460 } 461 } 462 463 /** Paroled here means temporary pardon from being inactive */ setAppIdleParoled(boolean paroled)464 void setAppIdleParoled(boolean paroled) { 465 synchronized (mAppIdleLock) { 466 final long now = System.currentTimeMillis(); 467 if (mAppIdleTempParoled != paroled) { 468 mAppIdleTempParoled = paroled; 469 if (DEBUG) Slog.d(TAG, "Changing paroled to " + mAppIdleTempParoled); 470 if (paroled) { 471 postParoleEndTimeout(); 472 } else { 473 mLastAppIdleParoledTime = now; 474 postNextParoleTimeout(now); 475 } 476 postParoleStateChanged(); 477 } 478 } 479 } 480 isParoledOrCharging()481 boolean isParoledOrCharging() { 482 synchronized (mAppIdleLock) { 483 return mAppIdleTempParoled || mCharging; 484 } 485 } 486 postNextParoleTimeout(long now)487 private void postNextParoleTimeout(long now) { 488 if (DEBUG) Slog.d(TAG, "Posting MSG_CHECK_PAROLE_TIMEOUT"); 489 mHandler.removeMessages(MSG_CHECK_PAROLE_TIMEOUT); 490 // Compute when the next parole needs to happen. We check more frequently than necessary 491 // since the message handler delays are based on elapsedRealTime and not wallclock time. 492 // The comparison is done in wallclock time. 493 long timeLeft = (mLastAppIdleParoledTime + mAppIdleParoleIntervalMillis) - now; 494 if (timeLeft < 0) { 495 timeLeft = 0; 496 } 497 mHandler.sendEmptyMessageDelayed(MSG_CHECK_PAROLE_TIMEOUT, timeLeft); 498 } 499 postParoleEndTimeout()500 private void postParoleEndTimeout() { 501 if (DEBUG) Slog.d(TAG, "Posting MSG_PAROLE_END_TIMEOUT"); 502 mHandler.removeMessages(MSG_PAROLE_END_TIMEOUT); 503 mHandler.sendEmptyMessageDelayed(MSG_PAROLE_END_TIMEOUT, mAppIdleParoleDurationMillis); 504 } 505 postParoleStateChanged()506 private void postParoleStateChanged() { 507 if (DEBUG) Slog.d(TAG, "Posting MSG_PAROLE_STATE_CHANGED"); 508 mHandler.removeMessages(MSG_PAROLE_STATE_CHANGED); 509 mHandler.sendEmptyMessage(MSG_PAROLE_STATE_CHANGED); 510 } 511 postCheckIdleStates(int userId)512 void postCheckIdleStates(int userId) { 513 mHandler.sendMessage(mHandler.obtainMessage(MSG_CHECK_IDLE_STATES, userId, 0)); 514 } 515 516 /** 517 * We send a different message to check idle states once, otherwise we would end up 518 * scheduling a series of repeating checkIdleStates each time we fired off one. 519 */ postOneTimeCheckIdleStates()520 void postOneTimeCheckIdleStates() { 521 if (mDeviceIdleController == null) { 522 // Not booted yet; wait for it! 523 mPendingOneTimeCheckIdleStates = true; 524 } else { 525 mHandler.sendEmptyMessage(MSG_ONE_TIME_CHECK_IDLE_STATES); 526 mPendingOneTimeCheckIdleStates = false; 527 } 528 } 529 530 /** 531 * Check all running users' or specified user's apps to see if they enter an idle state. 532 * @return Returns whether checking should continue periodically. 533 */ checkIdleStates(int checkUserId)534 boolean checkIdleStates(int checkUserId) { 535 if (!mAppIdleEnabled) { 536 return false; 537 } 538 539 final int[] runningUserIds; 540 try { 541 runningUserIds = ActivityManager.getService().getRunningUserIds(); 542 if (checkUserId != UserHandle.USER_ALL 543 && !ArrayUtils.contains(runningUserIds, checkUserId)) { 544 return false; 545 } 546 } catch (RemoteException re) { 547 throw re.rethrowFromSystemServer(); 548 } 549 550 final long elapsedRealtime = SystemClock.elapsedRealtime(); 551 for (int i = 0; i < runningUserIds.length; i++) { 552 final int userId = runningUserIds[i]; 553 if (checkUserId != UserHandle.USER_ALL && checkUserId != userId) { 554 continue; 555 } 556 if (DEBUG) { 557 Slog.d(TAG, "Checking idle state for user " + userId); 558 } 559 List<PackageInfo> packages = mPackageManager.getInstalledPackagesAsUser( 560 PackageManager.MATCH_DISABLED_COMPONENTS, 561 userId); 562 final int packageCount = packages.size(); 563 for (int p = 0; p < packageCount; p++) { 564 final PackageInfo pi = packages.get(p); 565 final String packageName = pi.packageName; 566 final boolean isIdle = isAppIdleFiltered(packageName, 567 UserHandle.getAppId(pi.applicationInfo.uid), 568 userId, elapsedRealtime); 569 mHandler.sendMessage(mHandler.obtainMessage(MSG_INFORM_LISTENERS, 570 userId, isIdle ? 1 : 0, packageName)); 571 if (isIdle) { 572 synchronized (mAppIdleLock) { 573 mAppIdleHistory.setIdle(packageName, userId, elapsedRealtime); 574 } 575 } 576 } 577 } 578 if (DEBUG) { 579 Slog.d(TAG, "checkIdleStates took " 580 + (SystemClock.elapsedRealtime() - elapsedRealtime)); 581 } 582 return true; 583 } 584 585 /** Check if it's been a while since last parole and let idle apps do some work */ checkParoleTimeout()586 void checkParoleTimeout() { 587 boolean setParoled = false; 588 synchronized (mAppIdleLock) { 589 final long now = System.currentTimeMillis(); 590 if (!mAppIdleTempParoled) { 591 final long timeSinceLastParole = now - mLastAppIdleParoledTime; 592 if (timeSinceLastParole > mAppIdleParoleIntervalMillis) { 593 if (DEBUG) Slog.d(TAG, "Crossed default parole interval"); 594 setParoled = true; 595 } else { 596 if (DEBUG) Slog.d(TAG, "Not long enough to go to parole"); 597 postNextParoleTimeout(now); 598 } 599 } 600 } 601 if (setParoled) { 602 setAppIdleParoled(true); 603 } 604 } 605 notifyBatteryStats(String packageName, int userId, boolean idle)606 private void notifyBatteryStats(String packageName, int userId, boolean idle) { 607 try { 608 final int uid = mPackageManager.getPackageUidAsUser(packageName, 609 PackageManager.MATCH_UNINSTALLED_PACKAGES, userId); 610 if (idle) { 611 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_PACKAGE_INACTIVE, 612 packageName, uid); 613 } else { 614 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_PACKAGE_ACTIVE, 615 packageName, uid); 616 } 617 } catch (NameNotFoundException | RemoteException e) { 618 } 619 } 620 onDeviceIdleModeChanged()621 void onDeviceIdleModeChanged() { 622 final boolean deviceIdle = mPowerManager.isDeviceIdleMode(); 623 if (DEBUG) Slog.i(TAG, "DeviceIdleMode changed to " + deviceIdle); 624 boolean paroled = false; 625 synchronized (mAppIdleLock) { 626 final long timeSinceLastParole = System.currentTimeMillis() - mLastAppIdleParoledTime; 627 if (!deviceIdle 628 && timeSinceLastParole >= mAppIdleParoleIntervalMillis) { 629 if (DEBUG) { 630 Slog.i(TAG, "Bringing idle apps out of inactive state due to deviceIdleMode=false"); 631 } 632 paroled = true; 633 } else if (deviceIdle) { 634 if (DEBUG) Slog.i(TAG, "Device idle, back to prison"); 635 paroled = false; 636 } else { 637 return; 638 } 639 } 640 setAppIdleParoled(paroled); 641 } 642 deleteRecursively(File f)643 private static void deleteRecursively(File f) { 644 File[] files = f.listFiles(); 645 if (files != null) { 646 for (File subFile : files) { 647 deleteRecursively(subFile); 648 } 649 } 650 651 if (!f.delete()) { 652 Slog.e(TAG, "Failed to delete " + f); 653 } 654 } 655 getUserDataAndInitializeIfNeededLocked(int userId, long currentTimeMillis)656 private UserUsageStatsService getUserDataAndInitializeIfNeededLocked(int userId, 657 long currentTimeMillis) { 658 UserUsageStatsService service = mUserState.get(userId); 659 if (service == null) { 660 service = new UserUsageStatsService(getContext(), userId, 661 new File(mUsageStatsDir, Integer.toString(userId)), this); 662 service.init(currentTimeMillis); 663 mUserState.put(userId, service); 664 } 665 return service; 666 } 667 668 /** 669 * This should be the only way to get the time from the system. 670 */ checkAndGetTimeLocked()671 private long checkAndGetTimeLocked() { 672 final long actualSystemTime = System.currentTimeMillis(); 673 final long actualRealtime = SystemClock.elapsedRealtime(); 674 final long expectedSystemTime = (actualRealtime - mRealTimeSnapshot) + mSystemTimeSnapshot; 675 final long diffSystemTime = actualSystemTime - expectedSystemTime; 676 if (Math.abs(diffSystemTime) > TIME_CHANGE_THRESHOLD_MILLIS 677 && ENABLE_TIME_CHANGE_CORRECTION) { 678 // The time has changed. 679 Slog.i(TAG, "Time changed in UsageStats by " + (diffSystemTime / 1000) + " seconds"); 680 final int userCount = mUserState.size(); 681 for (int i = 0; i < userCount; i++) { 682 final UserUsageStatsService service = mUserState.valueAt(i); 683 service.onTimeChanged(expectedSystemTime, actualSystemTime); 684 } 685 mRealTimeSnapshot = actualRealtime; 686 mSystemTimeSnapshot = actualSystemTime; 687 } 688 return actualSystemTime; 689 } 690 691 /** 692 * Assuming the event's timestamp is measured in milliseconds since boot, 693 * convert it to a system wall time. 694 */ convertToSystemTimeLocked(UsageEvents.Event event)695 private void convertToSystemTimeLocked(UsageEvents.Event event) { 696 event.mTimeStamp = Math.max(0, event.mTimeStamp - mRealTimeSnapshot) + mSystemTimeSnapshot; 697 } 698 699 /** 700 * Called by the Binder stub 701 */ shutdown()702 void shutdown() { 703 synchronized (mLock) { 704 mHandler.removeMessages(MSG_REPORT_EVENT); 705 flushToDiskLocked(); 706 } 707 } 708 709 /** 710 * Called by the Binder stub. 711 */ reportEvent(UsageEvents.Event event, int userId)712 void reportEvent(UsageEvents.Event event, int userId) { 713 synchronized (mLock) { 714 final long timeNow = checkAndGetTimeLocked(); 715 final long elapsedRealtime = SystemClock.elapsedRealtime(); 716 convertToSystemTimeLocked(event); 717 718 if (event.getPackageName() != null 719 && mPackageManagerInternal.isPackageEphemeral(userId, event.getPackageName())) { 720 event.mFlags |= Event.FLAG_IS_PACKAGE_INSTANT_APP; 721 } 722 723 final UserUsageStatsService service = 724 getUserDataAndInitializeIfNeededLocked(userId, timeNow); 725 service.reportEvent(event); 726 727 synchronized (mAppIdleLock) { 728 // TODO: Ideally this should call isAppIdleFiltered() to avoid calling back 729 // about apps that are on some kind of whitelist anyway. 730 final boolean previouslyIdle = mAppIdleHistory.isIdle( 731 event.mPackage, userId, elapsedRealtime); 732 // Inform listeners if necessary 733 if ((event.mEventType == Event.MOVE_TO_FOREGROUND 734 || event.mEventType == Event.MOVE_TO_BACKGROUND 735 || event.mEventType == Event.SYSTEM_INTERACTION 736 || event.mEventType == Event.USER_INTERACTION)) { 737 mAppIdleHistory.reportUsage(event.mPackage, userId, elapsedRealtime); 738 if (previouslyIdle) { 739 mHandler.sendMessage(mHandler.obtainMessage(MSG_INFORM_LISTENERS, userId, 740 /* idle = */ 0, event.mPackage)); 741 notifyBatteryStats(event.mPackage, userId, false); 742 } 743 } 744 } 745 } 746 } 747 reportContentProviderUsage(String authority, String providerPkgName, int userId)748 void reportContentProviderUsage(String authority, String providerPkgName, int userId) { 749 // Get sync adapters for the authority 750 String[] packages = ContentResolver.getSyncAdapterPackagesForAuthorityAsUser( 751 authority, userId); 752 for (String packageName: packages) { 753 // Only force the sync adapters to active if the provider is not in the same package and 754 // the sync adapter is a system package. 755 try { 756 PackageInfo pi = mPackageManager.getPackageInfoAsUser( 757 packageName, PackageManager.MATCH_SYSTEM_ONLY, userId); 758 if (pi == null || pi.applicationInfo == null) { 759 continue; 760 } 761 if (!packageName.equals(providerPkgName)) { 762 setAppIdleAsync(packageName, false, userId); 763 } 764 } catch (NameNotFoundException e) { 765 // Shouldn't happen 766 } 767 } 768 } 769 770 /** 771 * Forces the app's beginIdleTime and lastUsedTime to reflect idle or active. If idle, 772 * then it rolls back the beginIdleTime and lastUsedTime to a point in time that's behind 773 * the threshold for idle. 774 * 775 * This method is always called from the handler thread, so not much synchronization is 776 * required. 777 */ forceIdleState(String packageName, int userId, boolean idle)778 void forceIdleState(String packageName, int userId, boolean idle) { 779 final int appId = getAppId(packageName); 780 if (appId < 0) return; 781 final long elapsedRealtime = SystemClock.elapsedRealtime(); 782 783 final boolean previouslyIdle = isAppIdleFiltered(packageName, appId, 784 userId, elapsedRealtime); 785 synchronized (mAppIdleLock) { 786 mAppIdleHistory.setIdle(packageName, userId, idle, elapsedRealtime); 787 } 788 final boolean stillIdle = isAppIdleFiltered(packageName, appId, 789 userId, elapsedRealtime); 790 // Inform listeners if necessary 791 if (previouslyIdle != stillIdle) { 792 mHandler.sendMessage(mHandler.obtainMessage(MSG_INFORM_LISTENERS, userId, 793 /* idle = */ stillIdle ? 1 : 0, packageName)); 794 if (!stillIdle) { 795 notifyBatteryStats(packageName, userId, idle); 796 } 797 } 798 } 799 800 /** 801 * Called by the Binder stub. 802 */ flushToDisk()803 void flushToDisk() { 804 synchronized (mLock) { 805 flushToDiskLocked(); 806 } 807 } 808 809 /** 810 * Called by the Binder stub. 811 */ onUserRemoved(int userId)812 void onUserRemoved(int userId) { 813 synchronized (mLock) { 814 Slog.i(TAG, "Removing user " + userId + " and all data."); 815 mUserState.remove(userId); 816 synchronized (mAppIdleLock) { 817 mAppIdleHistory.onUserRemoved(userId); 818 } 819 cleanUpRemovedUsersLocked(); 820 } 821 } 822 823 /** 824 * Called by the Binder stub. 825 */ queryUsageStats(int userId, int bucketType, long beginTime, long endTime, boolean obfuscateInstantApps)826 List<UsageStats> queryUsageStats(int userId, int bucketType, long beginTime, long endTime, 827 boolean obfuscateInstantApps) { 828 synchronized (mLock) { 829 final long timeNow = checkAndGetTimeLocked(); 830 if (!validRange(timeNow, beginTime, endTime)) { 831 return null; 832 } 833 834 final UserUsageStatsService service = 835 getUserDataAndInitializeIfNeededLocked(userId, timeNow); 836 List<UsageStats> list = service.queryUsageStats(bucketType, beginTime, endTime); 837 if (list == null) { 838 return null; 839 } 840 841 // Mangle instant app names *using their current state (not whether they were ephemeral 842 // when the data was recorded)*. 843 if (obfuscateInstantApps) { 844 for (int i = list.size() - 1; i >= 0; i--) { 845 final UsageStats stats = list.get(i); 846 if (mPackageManagerInternal.isPackageEphemeral(userId, stats.mPackageName)) { 847 list.set(i, stats.getObfuscatedForInstantApp()); 848 } 849 } 850 } 851 852 return list; 853 } 854 } 855 856 /** 857 * Called by the Binder stub. 858 */ queryConfigurationStats(int userId, int bucketType, long beginTime, long endTime)859 List<ConfigurationStats> queryConfigurationStats(int userId, int bucketType, long beginTime, 860 long endTime) { 861 synchronized (mLock) { 862 final long timeNow = checkAndGetTimeLocked(); 863 if (!validRange(timeNow, beginTime, endTime)) { 864 return null; 865 } 866 867 final UserUsageStatsService service = 868 getUserDataAndInitializeIfNeededLocked(userId, timeNow); 869 return service.queryConfigurationStats(bucketType, beginTime, endTime); 870 } 871 } 872 873 /** 874 * Called by the Binder stub. 875 */ queryEvents(int userId, long beginTime, long endTime, boolean shouldObfuscateInstantApps)876 UsageEvents queryEvents(int userId, long beginTime, long endTime, 877 boolean shouldObfuscateInstantApps) { 878 synchronized (mLock) { 879 final long timeNow = checkAndGetTimeLocked(); 880 if (!validRange(timeNow, beginTime, endTime)) { 881 return null; 882 } 883 884 final UserUsageStatsService service = 885 getUserDataAndInitializeIfNeededLocked(userId, timeNow); 886 return service.queryEvents(beginTime, endTime, shouldObfuscateInstantApps); 887 } 888 } 889 isAppIdleUnfiltered(String packageName, int userId, long elapsedRealtime)890 private boolean isAppIdleUnfiltered(String packageName, int userId, long elapsedRealtime) { 891 synchronized (mAppIdleLock) { 892 return mAppIdleHistory.isIdle(packageName, userId, elapsedRealtime); 893 } 894 } 895 addListener(AppIdleStateChangeListener listener)896 void addListener(AppIdleStateChangeListener listener) { 897 synchronized (mAppIdleLock) { 898 if (!mPackageAccessListeners.contains(listener)) { 899 mPackageAccessListeners.add(listener); 900 } 901 } 902 } 903 removeListener(AppIdleStateChangeListener listener)904 void removeListener(AppIdleStateChangeListener listener) { 905 synchronized (mAppIdleLock) { 906 mPackageAccessListeners.remove(listener); 907 } 908 } 909 getAppId(String packageName)910 int getAppId(String packageName) { 911 try { 912 ApplicationInfo ai = mPackageManager.getApplicationInfo(packageName, 913 PackageManager.MATCH_ANY_USER 914 | PackageManager.MATCH_DISABLED_COMPONENTS); 915 return ai.uid; 916 } catch (NameNotFoundException re) { 917 return -1; 918 } 919 } 920 isAppIdleFilteredOrParoled(String packageName, int userId, long elapsedRealtime, boolean shouldObfuscateInstantApps)921 boolean isAppIdleFilteredOrParoled(String packageName, int userId, long elapsedRealtime, 922 boolean shouldObfuscateInstantApps) { 923 if (isParoledOrCharging()) { 924 return false; 925 } 926 if (shouldObfuscateInstantApps && 927 mPackageManagerInternal.isPackageEphemeral(userId, packageName)) { 928 return false; 929 } 930 return isAppIdleFiltered(packageName, getAppId(packageName), userId, elapsedRealtime); 931 } 932 933 /** 934 * Checks if an app has been idle for a while and filters out apps that are excluded. 935 * It returns false if the current system state allows all apps to be considered active. 936 * This happens if the device is plugged in or temporarily allowed to make exceptions. 937 * Called by interface impls. 938 */ isAppIdleFiltered(String packageName, int appId, int userId, long elapsedRealtime)939 private boolean isAppIdleFiltered(String packageName, int appId, int userId, 940 long elapsedRealtime) { 941 if (packageName == null) return false; 942 // If not enabled at all, of course nobody is ever idle. 943 if (!mAppIdleEnabled) { 944 return false; 945 } 946 if (appId < Process.FIRST_APPLICATION_UID) { 947 // System uids never go idle. 948 return false; 949 } 950 if (packageName.equals("android")) { 951 // Nor does the framework (which should be redundant with the above, but for MR1 we will 952 // retain this for safety). 953 return false; 954 } 955 if (mSystemServicesReady) { 956 try { 957 // We allow all whitelisted apps, including those that don't want to be whitelisted 958 // for idle mode, because app idle (aka app standby) is really not as big an issue 959 // for controlling who participates vs. doze mode. 960 if (mDeviceIdleController.isPowerSaveWhitelistExceptIdleApp(packageName)) { 961 return false; 962 } 963 } catch (RemoteException re) { 964 throw re.rethrowFromSystemServer(); 965 } 966 967 if (isActiveDeviceAdmin(packageName, userId)) { 968 return false; 969 } 970 971 if (isActiveNetworkScorer(packageName)) { 972 return false; 973 } 974 975 if (mAppWidgetManager != null 976 && mAppWidgetManager.isBoundWidgetPackage(packageName, userId)) { 977 return false; 978 } 979 980 if (isDeviceProvisioningPackage(packageName)) { 981 return false; 982 } 983 } 984 985 if (!isAppIdleUnfiltered(packageName, userId, elapsedRealtime)) { 986 return false; 987 } 988 989 // Check this last, as it is the most expensive check 990 // TODO: Optimize this by fetching the carrier privileged apps ahead of time 991 if (isCarrierApp(packageName)) { 992 return false; 993 } 994 995 return true; 996 } 997 getIdleUidsForUser(int userId)998 int[] getIdleUidsForUser(int userId) { 999 if (!mAppIdleEnabled) { 1000 return new int[0]; 1001 } 1002 1003 final long elapsedRealtime = SystemClock.elapsedRealtime(); 1004 1005 List<ApplicationInfo> apps; 1006 try { 1007 ParceledListSlice<ApplicationInfo> slice = AppGlobals.getPackageManager() 1008 .getInstalledApplications(/* flags= */ 0, userId); 1009 if (slice == null) { 1010 return new int[0]; 1011 } 1012 apps = slice.getList(); 1013 } catch (RemoteException e) { 1014 throw e.rethrowFromSystemServer(); 1015 } 1016 1017 // State of each uid. Key is the uid. Value lower 16 bits is the number of apps 1018 // associated with that uid, upper 16 bits is the number of those apps that is idle. 1019 SparseIntArray uidStates = new SparseIntArray(); 1020 1021 // Now resolve all app state. Iterating over all apps, keeping track of how many 1022 // we find for each uid and how many of those are idle. 1023 for (int i = apps.size() - 1; i >= 0; i--) { 1024 ApplicationInfo ai = apps.get(i); 1025 1026 // Check whether this app is idle. 1027 boolean idle = isAppIdleFiltered(ai.packageName, UserHandle.getAppId(ai.uid), 1028 userId, elapsedRealtime); 1029 1030 int index = uidStates.indexOfKey(ai.uid); 1031 if (index < 0) { 1032 uidStates.put(ai.uid, 1 + (idle ? 1<<16 : 0)); 1033 } else { 1034 int value = uidStates.valueAt(index); 1035 uidStates.setValueAt(index, value + 1 + (idle ? 1<<16 : 0)); 1036 } 1037 } 1038 if (DEBUG) { 1039 Slog.d(TAG, "getIdleUids took " + (SystemClock.elapsedRealtime() - elapsedRealtime)); 1040 } 1041 int numIdle = 0; 1042 for (int i = uidStates.size() - 1; i >= 0; i--) { 1043 int value = uidStates.valueAt(i); 1044 if ((value&0x7fff) == (value>>16)) { 1045 numIdle++; 1046 } 1047 } 1048 1049 int[] res = new int[numIdle]; 1050 numIdle = 0; 1051 for (int i = uidStates.size() - 1; i >= 0; i--) { 1052 int value = uidStates.valueAt(i); 1053 if ((value&0x7fff) == (value>>16)) { 1054 res[numIdle] = uidStates.keyAt(i); 1055 numIdle++; 1056 } 1057 } 1058 1059 return res; 1060 } 1061 setAppIdleAsync(String packageName, boolean idle, int userId)1062 void setAppIdleAsync(String packageName, boolean idle, int userId) { 1063 if (packageName == null) return; 1064 1065 mHandler.obtainMessage(MSG_FORCE_IDLE_STATE, userId, idle ? 1 : 0, packageName) 1066 .sendToTarget(); 1067 } 1068 isActiveDeviceAdmin(String packageName, int userId)1069 private boolean isActiveDeviceAdmin(String packageName, int userId) { 1070 DevicePolicyManager dpm = getContext().getSystemService(DevicePolicyManager.class); 1071 if (dpm == null) return false; 1072 return dpm.packageHasActiveAdmins(packageName, userId); 1073 } 1074 1075 /** 1076 * Returns {@code true} if the supplied package is the device provisioning app. Otherwise, 1077 * returns {@code false}. 1078 */ isDeviceProvisioningPackage(String packageName)1079 private boolean isDeviceProvisioningPackage(String packageName) { 1080 String deviceProvisioningPackage = getContext().getResources().getString( 1081 com.android.internal.R.string.config_deviceProvisioningPackage); 1082 return deviceProvisioningPackage != null && deviceProvisioningPackage.equals(packageName); 1083 } 1084 isCarrierApp(String packageName)1085 private boolean isCarrierApp(String packageName) { 1086 synchronized (mAppIdleLock) { 1087 if (!mHaveCarrierPrivilegedApps) { 1088 fetchCarrierPrivilegedAppsLA(); 1089 } 1090 if (mCarrierPrivilegedApps != null) { 1091 return mCarrierPrivilegedApps.contains(packageName); 1092 } 1093 return false; 1094 } 1095 } 1096 clearCarrierPrivilegedApps()1097 void clearCarrierPrivilegedApps() { 1098 if (DEBUG) { 1099 Slog.i(TAG, "Clearing carrier privileged apps list"); 1100 } 1101 synchronized (mAppIdleLock) { 1102 mHaveCarrierPrivilegedApps = false; 1103 mCarrierPrivilegedApps = null; // Need to be refetched. 1104 } 1105 } 1106 1107 @GuardedBy("mAppIdleLock") fetchCarrierPrivilegedAppsLA()1108 private void fetchCarrierPrivilegedAppsLA() { 1109 TelephonyManager telephonyManager = 1110 getContext().getSystemService(TelephonyManager.class); 1111 mCarrierPrivilegedApps = telephonyManager.getPackagesWithCarrierPrivileges(); 1112 mHaveCarrierPrivilegedApps = true; 1113 if (DEBUG) { 1114 Slog.d(TAG, "apps with carrier privilege " + mCarrierPrivilegedApps); 1115 } 1116 } 1117 isActiveNetworkScorer(String packageName)1118 private boolean isActiveNetworkScorer(String packageName) { 1119 NetworkScoreManager nsm = (NetworkScoreManager) getContext().getSystemService( 1120 Context.NETWORK_SCORE_SERVICE); 1121 return packageName != null && packageName.equals(nsm.getActiveScorerPackage()); 1122 } 1123 informListeners(String packageName, int userId, boolean isIdle)1124 void informListeners(String packageName, int userId, boolean isIdle) { 1125 for (AppIdleStateChangeListener listener : mPackageAccessListeners) { 1126 listener.onAppIdleStateChanged(packageName, userId, isIdle); 1127 } 1128 } 1129 informParoleStateChanged()1130 void informParoleStateChanged() { 1131 final boolean paroled = isParoledOrCharging(); 1132 for (AppIdleStateChangeListener listener : mPackageAccessListeners) { 1133 listener.onParoleStateChanged(paroled); 1134 } 1135 } 1136 validRange(long currentTime, long beginTime, long endTime)1137 private static boolean validRange(long currentTime, long beginTime, long endTime) { 1138 return beginTime <= currentTime && beginTime < endTime; 1139 } 1140 flushToDiskLocked()1141 private void flushToDiskLocked() { 1142 final int userCount = mUserState.size(); 1143 for (int i = 0; i < userCount; i++) { 1144 UserUsageStatsService service = mUserState.valueAt(i); 1145 service.persistActiveStats(); 1146 synchronized (mAppIdleLock) { 1147 mAppIdleHistory.writeAppIdleTimes(mUserState.keyAt(i)); 1148 } 1149 } 1150 // Persist elapsed and screen on time. If this fails for whatever reason, the apps will be 1151 // considered not-idle, which is the safest outcome in such an event. 1152 synchronized (mAppIdleLock) { 1153 mAppIdleHistory.writeAppIdleDurations(); 1154 } 1155 mHandler.removeMessages(MSG_FLUSH_TO_DISK); 1156 } 1157 1158 /** 1159 * Called by the Binder stub. 1160 */ dump(String[] args, PrintWriter pw)1161 void dump(String[] args, PrintWriter pw) { 1162 synchronized (mLock) { 1163 IndentingPrintWriter idpw = new IndentingPrintWriter(pw, " "); 1164 ArraySet<String> argSet = new ArraySet<>(); 1165 argSet.addAll(Arrays.asList(args)); 1166 1167 final int userCount = mUserState.size(); 1168 for (int i = 0; i < userCount; i++) { 1169 idpw.printPair("user", mUserState.keyAt(i)); 1170 idpw.println(); 1171 idpw.increaseIndent(); 1172 if (argSet.contains("--checkin")) { 1173 mUserState.valueAt(i).checkin(idpw); 1174 } else { 1175 mUserState.valueAt(i).dump(idpw); 1176 idpw.println(); 1177 if (args.length > 0) { 1178 if ("history".equals(args[0])) { 1179 synchronized (mAppIdleLock) { 1180 mAppIdleHistory.dumpHistory(idpw, mUserState.keyAt(i)); 1181 } 1182 } else if ("flush".equals(args[0])) { 1183 UsageStatsService.this.flushToDiskLocked(); 1184 pw.println("Flushed stats to disk"); 1185 } 1186 } 1187 } 1188 synchronized (mAppIdleLock) { 1189 mAppIdleHistory.dump(idpw, mUserState.keyAt(i)); 1190 } 1191 idpw.decreaseIndent(); 1192 } 1193 1194 pw.println(); 1195 synchronized (mAppIdleLock) { 1196 pw.println("Carrier privileged apps (have=" + mHaveCarrierPrivilegedApps 1197 + "): " + mCarrierPrivilegedApps); 1198 } 1199 1200 pw.println(); 1201 pw.println("Settings:"); 1202 1203 pw.print(" mAppIdleDurationMillis="); 1204 TimeUtils.formatDuration(mAppIdleScreenThresholdMillis, pw); 1205 pw.println(); 1206 1207 pw.print(" mAppIdleWallclockThresholdMillis="); 1208 TimeUtils.formatDuration(mAppIdleWallclockThresholdMillis, pw); 1209 pw.println(); 1210 1211 pw.print(" mCheckIdleIntervalMillis="); 1212 TimeUtils.formatDuration(mCheckIdleIntervalMillis, pw); 1213 pw.println(); 1214 1215 pw.print(" mAppIdleParoleIntervalMillis="); 1216 TimeUtils.formatDuration(mAppIdleParoleIntervalMillis, pw); 1217 pw.println(); 1218 1219 pw.print(" mAppIdleParoleDurationMillis="); 1220 TimeUtils.formatDuration(mAppIdleParoleDurationMillis, pw); 1221 pw.println(); 1222 1223 pw.println(); 1224 pw.print("mAppIdleEnabled="); pw.print(mAppIdleEnabled); 1225 pw.print(" mAppIdleTempParoled="); pw.print(mAppIdleTempParoled); 1226 pw.print(" mCharging="); pw.print(mCharging); 1227 pw.print(" mLastAppIdleParoledTime="); 1228 TimeUtils.formatDuration(mLastAppIdleParoledTime, pw); 1229 pw.println(); 1230 } 1231 } 1232 1233 class H extends Handler { H(Looper looper)1234 public H(Looper looper) { 1235 super(looper); 1236 } 1237 1238 @Override handleMessage(Message msg)1239 public void handleMessage(Message msg) { 1240 switch (msg.what) { 1241 case MSG_REPORT_EVENT: 1242 reportEvent((UsageEvents.Event) msg.obj, msg.arg1); 1243 break; 1244 1245 case MSG_FLUSH_TO_DISK: 1246 flushToDisk(); 1247 break; 1248 1249 case MSG_REMOVE_USER: 1250 onUserRemoved(msg.arg1); 1251 break; 1252 1253 case MSG_INFORM_LISTENERS: 1254 informListeners((String) msg.obj, msg.arg1, msg.arg2 == 1); 1255 break; 1256 1257 case MSG_FORCE_IDLE_STATE: 1258 forceIdleState((String) msg.obj, msg.arg1, msg.arg2 == 1); 1259 break; 1260 1261 case MSG_CHECK_IDLE_STATES: 1262 if (checkIdleStates(msg.arg1)) { 1263 mHandler.sendMessageDelayed(mHandler.obtainMessage( 1264 MSG_CHECK_IDLE_STATES, msg.arg1, 0), 1265 mCheckIdleIntervalMillis); 1266 } 1267 break; 1268 1269 case MSG_ONE_TIME_CHECK_IDLE_STATES: 1270 mHandler.removeMessages(MSG_ONE_TIME_CHECK_IDLE_STATES); 1271 checkIdleStates(UserHandle.USER_ALL); 1272 break; 1273 1274 case MSG_CHECK_PAROLE_TIMEOUT: 1275 checkParoleTimeout(); 1276 break; 1277 1278 case MSG_PAROLE_END_TIMEOUT: 1279 if (DEBUG) Slog.d(TAG, "Ending parole"); 1280 setAppIdleParoled(false); 1281 break; 1282 1283 case MSG_REPORT_CONTENT_PROVIDER_USAGE: 1284 SomeArgs args = (SomeArgs) msg.obj; 1285 reportContentProviderUsage((String) args.arg1, // authority name 1286 (String) args.arg2, // package name 1287 (int) args.arg3); // userId 1288 args.recycle(); 1289 break; 1290 1291 case MSG_PAROLE_STATE_CHANGED: 1292 if (DEBUG) Slog.d(TAG, "Parole state: " + mAppIdleTempParoled 1293 + ", Charging state:" + mCharging); 1294 informParoleStateChanged(); 1295 break; 1296 1297 default: 1298 super.handleMessage(msg); 1299 break; 1300 } 1301 } 1302 } 1303 1304 /** 1305 * Observe settings changes for {@link Settings.Global#APP_IDLE_CONSTANTS}. 1306 */ 1307 private class SettingsObserver extends ContentObserver { 1308 /** 1309 * This flag has been used to disable app idle on older builds with bug b/26355386. 1310 */ 1311 @Deprecated 1312 private static final String KEY_IDLE_DURATION_OLD = "idle_duration"; 1313 1314 private static final String KEY_IDLE_DURATION = "idle_duration2"; 1315 private static final String KEY_WALLCLOCK_THRESHOLD = "wallclock_threshold"; 1316 private static final String KEY_PAROLE_INTERVAL = "parole_interval"; 1317 private static final String KEY_PAROLE_DURATION = "parole_duration"; 1318 1319 private final KeyValueListParser mParser = new KeyValueListParser(','); 1320 SettingsObserver(Handler handler)1321 SettingsObserver(Handler handler) { 1322 super(handler); 1323 } 1324 registerObserver()1325 void registerObserver() { 1326 getContext().getContentResolver().registerContentObserver(Settings.Global.getUriFor( 1327 Settings.Global.APP_IDLE_CONSTANTS), false, this); 1328 } 1329 1330 @Override onChange(boolean selfChange)1331 public void onChange(boolean selfChange) { 1332 updateSettings(); 1333 postOneTimeCheckIdleStates(); 1334 } 1335 updateSettings()1336 void updateSettings() { 1337 synchronized (mAppIdleLock) { 1338 // Look at global settings for this. 1339 // TODO: Maybe apply different thresholds for different users. 1340 try { 1341 mParser.setString(Settings.Global.getString(getContext().getContentResolver(), 1342 Settings.Global.APP_IDLE_CONSTANTS)); 1343 } catch (IllegalArgumentException e) { 1344 Slog.e(TAG, "Bad value for app idle settings: " + e.getMessage()); 1345 // fallthrough, mParser is empty and all defaults will be returned. 1346 } 1347 1348 // Default: 12 hours of screen-on time sans dream-time 1349 mAppIdleScreenThresholdMillis = mParser.getLong(KEY_IDLE_DURATION, 1350 COMPRESS_TIME ? ONE_MINUTE * 4 : 12 * 60 * ONE_MINUTE); 1351 1352 mAppIdleWallclockThresholdMillis = mParser.getLong(KEY_WALLCLOCK_THRESHOLD, 1353 COMPRESS_TIME ? ONE_MINUTE * 8 : 2L * 24 * 60 * ONE_MINUTE); // 2 days 1354 1355 mCheckIdleIntervalMillis = Math.min(mAppIdleScreenThresholdMillis / 4, 1356 COMPRESS_TIME ? ONE_MINUTE : 8 * 60 * ONE_MINUTE); // 8 hours 1357 1358 // Default: 24 hours between paroles 1359 mAppIdleParoleIntervalMillis = mParser.getLong(KEY_PAROLE_INTERVAL, 1360 COMPRESS_TIME ? ONE_MINUTE * 10 : 24 * 60 * ONE_MINUTE); 1361 1362 mAppIdleParoleDurationMillis = mParser.getLong(KEY_PAROLE_DURATION, 1363 COMPRESS_TIME ? ONE_MINUTE : 10 * ONE_MINUTE); // 10 minutes 1364 mAppIdleHistory.setThresholds(mAppIdleWallclockThresholdMillis, 1365 mAppIdleScreenThresholdMillis); 1366 } 1367 } 1368 } 1369 1370 private final class BinderService extends IUsageStatsManager.Stub { 1371 hasPermission(String callingPackage)1372 private boolean hasPermission(String callingPackage) { 1373 final int callingUid = Binder.getCallingUid(); 1374 if (callingUid == Process.SYSTEM_UID) { 1375 return true; 1376 } 1377 final int mode = mAppOps.checkOp(AppOpsManager.OP_GET_USAGE_STATS, 1378 callingUid, callingPackage); 1379 if (mode == AppOpsManager.MODE_DEFAULT) { 1380 // The default behavior here is to check if PackageManager has given the app 1381 // permission. 1382 return getContext().checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS) 1383 == PackageManager.PERMISSION_GRANTED; 1384 } 1385 return mode == AppOpsManager.MODE_ALLOWED; 1386 } 1387 1388 @Override queryUsageStats(int bucketType, long beginTime, long endTime, String callingPackage)1389 public ParceledListSlice<UsageStats> queryUsageStats(int bucketType, long beginTime, 1390 long endTime, String callingPackage) { 1391 if (!hasPermission(callingPackage)) { 1392 return null; 1393 } 1394 1395 final boolean obfuscateInstantApps = shouldObfuscateInstantAppsForCaller( 1396 Binder.getCallingUid(), UserHandle.getCallingUserId()); 1397 1398 final int userId = UserHandle.getCallingUserId(); 1399 final long token = Binder.clearCallingIdentity(); 1400 try { 1401 final List<UsageStats> results = UsageStatsService.this.queryUsageStats( 1402 userId, bucketType, beginTime, endTime, obfuscateInstantApps); 1403 if (results != null) { 1404 return new ParceledListSlice<>(results); 1405 } 1406 } finally { 1407 Binder.restoreCallingIdentity(token); 1408 } 1409 return null; 1410 } 1411 1412 @Override queryConfigurationStats(int bucketType, long beginTime, long endTime, String callingPackage)1413 public ParceledListSlice<ConfigurationStats> queryConfigurationStats(int bucketType, 1414 long beginTime, long endTime, String callingPackage) throws RemoteException { 1415 if (!hasPermission(callingPackage)) { 1416 return null; 1417 } 1418 1419 final int userId = UserHandle.getCallingUserId(); 1420 final long token = Binder.clearCallingIdentity(); 1421 try { 1422 final List<ConfigurationStats> results = 1423 UsageStatsService.this.queryConfigurationStats(userId, bucketType, 1424 beginTime, endTime); 1425 if (results != null) { 1426 return new ParceledListSlice<>(results); 1427 } 1428 } finally { 1429 Binder.restoreCallingIdentity(token); 1430 } 1431 return null; 1432 } 1433 1434 @Override queryEvents(long beginTime, long endTime, String callingPackage)1435 public UsageEvents queryEvents(long beginTime, long endTime, String callingPackage) { 1436 if (!hasPermission(callingPackage)) { 1437 return null; 1438 } 1439 1440 final boolean obfuscateInstantApps = shouldObfuscateInstantAppsForCaller( 1441 Binder.getCallingUid(), UserHandle.getCallingUserId()); 1442 1443 final int userId = UserHandle.getCallingUserId(); 1444 final long token = Binder.clearCallingIdentity(); 1445 try { 1446 return UsageStatsService.this.queryEvents(userId, beginTime, endTime, 1447 obfuscateInstantApps); 1448 } finally { 1449 Binder.restoreCallingIdentity(token); 1450 } 1451 } 1452 1453 @Override isAppInactive(String packageName, int userId)1454 public boolean isAppInactive(String packageName, int userId) { 1455 try { 1456 userId = ActivityManager.getService().handleIncomingUser(Binder.getCallingPid(), 1457 Binder.getCallingUid(), userId, false, true, "isAppInactive", null); 1458 } catch (RemoteException re) { 1459 throw re.rethrowFromSystemServer(); 1460 } 1461 final boolean obfuscateInstantApps = shouldObfuscateInstantAppsForCaller( 1462 Binder.getCallingUid(), userId); 1463 final long token = Binder.clearCallingIdentity(); 1464 try { 1465 return UsageStatsService.this.isAppIdleFilteredOrParoled(packageName, userId, 1466 SystemClock.elapsedRealtime(), obfuscateInstantApps); 1467 } finally { 1468 Binder.restoreCallingIdentity(token); 1469 } 1470 } 1471 1472 @Override setAppInactive(String packageName, boolean idle, int userId)1473 public void setAppInactive(String packageName, boolean idle, int userId) { 1474 final int callingUid = Binder.getCallingUid(); 1475 try { 1476 userId = ActivityManager.getService().handleIncomingUser( 1477 Binder.getCallingPid(), callingUid, userId, false, true, 1478 "setAppInactive", null); 1479 } catch (RemoteException re) { 1480 throw re.rethrowFromSystemServer(); 1481 } 1482 getContext().enforceCallingPermission(Manifest.permission.CHANGE_APP_IDLE_STATE, 1483 "No permission to change app idle state"); 1484 final long token = Binder.clearCallingIdentity(); 1485 try { 1486 final int appId = getAppId(packageName); 1487 if (appId < 0) return; 1488 UsageStatsService.this.setAppIdleAsync(packageName, idle, userId); 1489 } finally { 1490 Binder.restoreCallingIdentity(token); 1491 } 1492 } 1493 1494 @Override whitelistAppTemporarily(String packageName, long duration, int userId)1495 public void whitelistAppTemporarily(String packageName, long duration, int userId) 1496 throws RemoteException { 1497 StringBuilder reason = new StringBuilder(32); 1498 reason.append("from:"); 1499 UserHandle.formatUid(reason, Binder.getCallingUid()); 1500 mDeviceIdleController.addPowerSaveTempWhitelistApp(packageName, duration, userId, 1501 reason.toString()); 1502 } 1503 1504 @Override onCarrierPrivilegedAppsChanged()1505 public void onCarrierPrivilegedAppsChanged() { 1506 if (DEBUG) { 1507 Slog.i(TAG, "Carrier privileged apps changed"); 1508 } 1509 getContext().enforceCallingOrSelfPermission( 1510 android.Manifest.permission.BIND_CARRIER_SERVICES, 1511 "onCarrierPrivilegedAppsChanged can only be called by privileged apps."); 1512 UsageStatsService.this.clearCarrierPrivilegedApps(); 1513 } 1514 1515 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)1516 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1517 if (!DumpUtils.checkDumpAndUsageStatsPermission(getContext(), TAG, pw)) return; 1518 UsageStatsService.this.dump(args, pw); 1519 } 1520 1521 @Override reportChooserSelection(String packageName, int userId, String contentType, String[] annotations, String action)1522 public void reportChooserSelection(String packageName, int userId, String contentType, 1523 String[] annotations, String action) { 1524 if (packageName == null) { 1525 Slog.w(TAG, "Event report user selecting a null package"); 1526 return; 1527 } 1528 1529 UsageEvents.Event event = new UsageEvents.Event(); 1530 event.mPackage = packageName; 1531 1532 // This will later be converted to system time. 1533 event.mTimeStamp = SystemClock.elapsedRealtime(); 1534 1535 event.mEventType = Event.CHOOSER_ACTION; 1536 1537 event.mAction = action; 1538 1539 event.mContentType = contentType; 1540 1541 event.mContentAnnotations = annotations; 1542 1543 mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget(); 1544 } 1545 } 1546 1547 /** 1548 * This local service implementation is primarily used by ActivityManagerService. 1549 * ActivityManagerService will call these methods holding the 'am' lock, which means we 1550 * shouldn't be doing any IO work or other long running tasks in these methods. 1551 */ 1552 private final class LocalService extends UsageStatsManagerInternal { 1553 1554 @Override reportEvent(ComponentName component, int userId, int eventType)1555 public void reportEvent(ComponentName component, int userId, int eventType) { 1556 if (component == null) { 1557 Slog.w(TAG, "Event reported without a component name"); 1558 return; 1559 } 1560 1561 UsageEvents.Event event = new UsageEvents.Event(); 1562 event.mPackage = component.getPackageName(); 1563 event.mClass = component.getClassName(); 1564 1565 // This will later be converted to system time. 1566 event.mTimeStamp = SystemClock.elapsedRealtime(); 1567 1568 event.mEventType = eventType; 1569 mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget(); 1570 } 1571 1572 @Override reportEvent(String packageName, int userId, int eventType)1573 public void reportEvent(String packageName, int userId, int eventType) { 1574 if (packageName == null) { 1575 Slog.w(TAG, "Event reported without a package name"); 1576 return; 1577 } 1578 1579 UsageEvents.Event event = new UsageEvents.Event(); 1580 event.mPackage = packageName; 1581 1582 // This will later be converted to system time. 1583 event.mTimeStamp = SystemClock.elapsedRealtime(); 1584 1585 event.mEventType = eventType; 1586 mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget(); 1587 } 1588 1589 @Override reportConfigurationChange(Configuration config, int userId)1590 public void reportConfigurationChange(Configuration config, int userId) { 1591 if (config == null) { 1592 Slog.w(TAG, "Configuration event reported with a null config"); 1593 return; 1594 } 1595 1596 UsageEvents.Event event = new UsageEvents.Event(); 1597 event.mPackage = "android"; 1598 1599 // This will later be converted to system time. 1600 event.mTimeStamp = SystemClock.elapsedRealtime(); 1601 1602 event.mEventType = UsageEvents.Event.CONFIGURATION_CHANGE; 1603 event.mConfiguration = new Configuration(config); 1604 mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget(); 1605 } 1606 1607 @Override reportShortcutUsage(String packageName, String shortcutId, int userId)1608 public void reportShortcutUsage(String packageName, String shortcutId, int userId) { 1609 if (packageName == null || shortcutId == null) { 1610 Slog.w(TAG, "Event reported without a package name or a shortcut ID"); 1611 return; 1612 } 1613 1614 UsageEvents.Event event = new UsageEvents.Event(); 1615 event.mPackage = packageName.intern(); 1616 event.mShortcutId = shortcutId.intern(); 1617 1618 // This will later be converted to system time. 1619 event.mTimeStamp = SystemClock.elapsedRealtime(); 1620 1621 event.mEventType = Event.SHORTCUT_INVOCATION; 1622 mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget(); 1623 } 1624 1625 @Override reportContentProviderUsage(String name, String packageName, int userId)1626 public void reportContentProviderUsage(String name, String packageName, int userId) { 1627 SomeArgs args = SomeArgs.obtain(); 1628 args.arg1 = name; 1629 args.arg2 = packageName; 1630 args.arg3 = userId; 1631 mHandler.obtainMessage(MSG_REPORT_CONTENT_PROVIDER_USAGE, args) 1632 .sendToTarget(); 1633 } 1634 1635 @Override isAppIdle(String packageName, int uidForAppId, int userId)1636 public boolean isAppIdle(String packageName, int uidForAppId, int userId) { 1637 return UsageStatsService.this.isAppIdleFiltered(packageName, uidForAppId, userId, 1638 SystemClock.elapsedRealtime()); 1639 } 1640 1641 @Override getIdleUidsForUser(int userId)1642 public int[] getIdleUidsForUser(int userId) { 1643 return UsageStatsService.this.getIdleUidsForUser(userId); 1644 } 1645 1646 @Override isAppIdleParoleOn()1647 public boolean isAppIdleParoleOn() { 1648 return isParoledOrCharging(); 1649 } 1650 1651 @Override prepareShutdown()1652 public void prepareShutdown() { 1653 // This method *WILL* do IO work, but we must block until it is finished or else 1654 // we might not shutdown cleanly. This is ok to do with the 'am' lock held, because 1655 // we are shutting down. 1656 shutdown(); 1657 } 1658 1659 @Override addAppIdleStateChangeListener(AppIdleStateChangeListener listener)1660 public void addAppIdleStateChangeListener(AppIdleStateChangeListener listener) { 1661 UsageStatsService.this.addListener(listener); 1662 listener.onParoleStateChanged(isAppIdleParoleOn()); 1663 } 1664 1665 @Override removeAppIdleStateChangeListener( AppIdleStateChangeListener listener)1666 public void removeAppIdleStateChangeListener( 1667 AppIdleStateChangeListener listener) { 1668 UsageStatsService.this.removeListener(listener); 1669 } 1670 1671 @Override getBackupPayload(int user, String key)1672 public byte[] getBackupPayload(int user, String key) { 1673 // Check to ensure that only user 0's data is b/r for now 1674 synchronized (UsageStatsService.this.mLock) { 1675 if (user == UserHandle.USER_SYSTEM) { 1676 final UserUsageStatsService userStats = 1677 getUserDataAndInitializeIfNeededLocked(user, checkAndGetTimeLocked()); 1678 return userStats.getBackupPayload(key); 1679 } else { 1680 return null; 1681 } 1682 } 1683 } 1684 1685 @Override applyRestoredPayload(int user, String key, byte[] payload)1686 public void applyRestoredPayload(int user, String key, byte[] payload) { 1687 synchronized (UsageStatsService.this.mLock) { 1688 if (user == UserHandle.USER_SYSTEM) { 1689 final UserUsageStatsService userStats = 1690 getUserDataAndInitializeIfNeededLocked(user, checkAndGetTimeLocked()); 1691 userStats.applyRestoredPayload(key, payload); 1692 } 1693 } 1694 } 1695 1696 @Override queryUsageStatsForUser( int userId, int intervalType, long beginTime, long endTime, boolean obfuscateInstantApps)1697 public List<UsageStats> queryUsageStatsForUser( 1698 int userId, int intervalType, long beginTime, long endTime, 1699 boolean obfuscateInstantApps) { 1700 return UsageStatsService.this.queryUsageStats( 1701 userId, intervalType, beginTime, endTime, obfuscateInstantApps); 1702 } 1703 } 1704 } 1705