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) throws RemoteException { 367 // Ignored 368 } 369 370 @Override 371 public void onUidGone(int uid, boolean disabled) throws RemoteException { 372 onUidStateChanged(uid, ActivityManager.PROCESS_STATE_NONEXISTENT, 0); 373 } 374 375 @Override 376 public void onUidActive(int uid) throws RemoteException { 377 // Ignored 378 } 379 }; 380 381 @Override onStatsUpdated()382 public void onStatsUpdated() { 383 mHandler.sendEmptyMessageDelayed(MSG_FLUSH_TO_DISK, FLUSH_INTERVAL); 384 } 385 386 @Override onStatsReloaded()387 public void onStatsReloaded() { 388 postOneTimeCheckIdleStates(); 389 } 390 391 @Override onNewUpdate(int userId)392 public void onNewUpdate(int userId) { 393 initializeDefaultsForSystemApps(userId); 394 } 395 initializeDefaultsForSystemApps(int userId)396 private void initializeDefaultsForSystemApps(int userId) { 397 Slog.d(TAG, "Initializing defaults for system apps on user " + userId); 398 final long elapsedRealtime = SystemClock.elapsedRealtime(); 399 List<PackageInfo> packages = mPackageManager.getInstalledPackagesAsUser( 400 PackageManager.MATCH_DISABLED_COMPONENTS, 401 userId); 402 final int packageCount = packages.size(); 403 synchronized (mAppIdleLock) { 404 for (int i = 0; i < packageCount; i++) { 405 final PackageInfo pi = packages.get(i); 406 String packageName = pi.packageName; 407 if (pi.applicationInfo != null && pi.applicationInfo.isSystemApp()) { 408 mAppIdleHistory.reportUsage(packageName, userId, elapsedRealtime); 409 } 410 } 411 } 412 } 413 shouldObfuscateInstantAppsForCaller(int callingUid, int userId)414 private boolean shouldObfuscateInstantAppsForCaller(int callingUid, int userId) { 415 return !mPackageManagerInternal.canAccessInstantApps(callingUid, userId); 416 } 417 clearAppIdleForPackage(String packageName, int userId)418 void clearAppIdleForPackage(String packageName, int userId) { 419 synchronized (mAppIdleLock) { 420 mAppIdleHistory.clearUsage(packageName, userId); 421 } 422 } 423 cleanUpRemovedUsersLocked()424 private void cleanUpRemovedUsersLocked() { 425 final List<UserInfo> users = mUserManager.getUsers(true); 426 if (users == null || users.size() == 0) { 427 throw new IllegalStateException("There can't be no users"); 428 } 429 430 ArraySet<String> toDelete = new ArraySet<>(); 431 String[] fileNames = mUsageStatsDir.list(); 432 if (fileNames == null) { 433 // No users to delete. 434 return; 435 } 436 437 toDelete.addAll(Arrays.asList(fileNames)); 438 439 final int userCount = users.size(); 440 for (int i = 0; i < userCount; i++) { 441 final UserInfo userInfo = users.get(i); 442 toDelete.remove(Integer.toString(userInfo.id)); 443 } 444 445 final int deleteCount = toDelete.size(); 446 for (int i = 0; i < deleteCount; i++) { 447 deleteRecursively(new File(mUsageStatsDir, toDelete.valueAt(i))); 448 } 449 } 450 setChargingState(boolean charging)451 void setChargingState(boolean charging) { 452 synchronized (mAppIdleLock) { 453 if (mCharging != charging) { 454 mCharging = charging; 455 postParoleStateChanged(); 456 } 457 } 458 } 459 460 /** Paroled here means temporary pardon from being inactive */ setAppIdleParoled(boolean paroled)461 void setAppIdleParoled(boolean paroled) { 462 synchronized (mAppIdleLock) { 463 final long now = System.currentTimeMillis(); 464 if (mAppIdleTempParoled != paroled) { 465 mAppIdleTempParoled = paroled; 466 if (DEBUG) Slog.d(TAG, "Changing paroled to " + mAppIdleTempParoled); 467 if (paroled) { 468 postParoleEndTimeout(); 469 } else { 470 mLastAppIdleParoledTime = now; 471 postNextParoleTimeout(now); 472 } 473 postParoleStateChanged(); 474 } 475 } 476 } 477 isParoledOrCharging()478 boolean isParoledOrCharging() { 479 synchronized (mAppIdleLock) { 480 return mAppIdleTempParoled || mCharging; 481 } 482 } 483 postNextParoleTimeout(long now)484 private void postNextParoleTimeout(long now) { 485 if (DEBUG) Slog.d(TAG, "Posting MSG_CHECK_PAROLE_TIMEOUT"); 486 mHandler.removeMessages(MSG_CHECK_PAROLE_TIMEOUT); 487 // Compute when the next parole needs to happen. We check more frequently than necessary 488 // since the message handler delays are based on elapsedRealTime and not wallclock time. 489 // The comparison is done in wallclock time. 490 long timeLeft = (mLastAppIdleParoledTime + mAppIdleParoleIntervalMillis) - now; 491 if (timeLeft < 0) { 492 timeLeft = 0; 493 } 494 mHandler.sendEmptyMessageDelayed(MSG_CHECK_PAROLE_TIMEOUT, timeLeft); 495 } 496 postParoleEndTimeout()497 private void postParoleEndTimeout() { 498 if (DEBUG) Slog.d(TAG, "Posting MSG_PAROLE_END_TIMEOUT"); 499 mHandler.removeMessages(MSG_PAROLE_END_TIMEOUT); 500 mHandler.sendEmptyMessageDelayed(MSG_PAROLE_END_TIMEOUT, mAppIdleParoleDurationMillis); 501 } 502 postParoleStateChanged()503 private void postParoleStateChanged() { 504 if (DEBUG) Slog.d(TAG, "Posting MSG_PAROLE_STATE_CHANGED"); 505 mHandler.removeMessages(MSG_PAROLE_STATE_CHANGED); 506 mHandler.sendEmptyMessage(MSG_PAROLE_STATE_CHANGED); 507 } 508 postCheckIdleStates(int userId)509 void postCheckIdleStates(int userId) { 510 mHandler.sendMessage(mHandler.obtainMessage(MSG_CHECK_IDLE_STATES, userId, 0)); 511 } 512 513 /** 514 * We send a different message to check idle states once, otherwise we would end up 515 * scheduling a series of repeating checkIdleStates each time we fired off one. 516 */ postOneTimeCheckIdleStates()517 void postOneTimeCheckIdleStates() { 518 if (mDeviceIdleController == null) { 519 // Not booted yet; wait for it! 520 mPendingOneTimeCheckIdleStates = true; 521 } else { 522 mHandler.sendEmptyMessage(MSG_ONE_TIME_CHECK_IDLE_STATES); 523 mPendingOneTimeCheckIdleStates = false; 524 } 525 } 526 527 /** 528 * Check all running users' or specified user's apps to see if they enter an idle state. 529 * @return Returns whether checking should continue periodically. 530 */ checkIdleStates(int checkUserId)531 boolean checkIdleStates(int checkUserId) { 532 if (!mAppIdleEnabled) { 533 return false; 534 } 535 536 final int[] runningUserIds; 537 try { 538 runningUserIds = ActivityManager.getService().getRunningUserIds(); 539 if (checkUserId != UserHandle.USER_ALL 540 && !ArrayUtils.contains(runningUserIds, checkUserId)) { 541 return false; 542 } 543 } catch (RemoteException re) { 544 throw re.rethrowFromSystemServer(); 545 } 546 547 final long elapsedRealtime = SystemClock.elapsedRealtime(); 548 for (int i = 0; i < runningUserIds.length; i++) { 549 final int userId = runningUserIds[i]; 550 if (checkUserId != UserHandle.USER_ALL && checkUserId != userId) { 551 continue; 552 } 553 if (DEBUG) { 554 Slog.d(TAG, "Checking idle state for user " + userId); 555 } 556 List<PackageInfo> packages = mPackageManager.getInstalledPackagesAsUser( 557 PackageManager.MATCH_DISABLED_COMPONENTS, 558 userId); 559 final int packageCount = packages.size(); 560 for (int p = 0; p < packageCount; p++) { 561 final PackageInfo pi = packages.get(p); 562 final String packageName = pi.packageName; 563 final boolean isIdle = isAppIdleFiltered(packageName, 564 UserHandle.getAppId(pi.applicationInfo.uid), 565 userId, elapsedRealtime); 566 mHandler.sendMessage(mHandler.obtainMessage(MSG_INFORM_LISTENERS, 567 userId, isIdle ? 1 : 0, packageName)); 568 if (isIdle) { 569 synchronized (mAppIdleLock) { 570 mAppIdleHistory.setIdle(packageName, userId, elapsedRealtime); 571 } 572 } 573 } 574 } 575 if (DEBUG) { 576 Slog.d(TAG, "checkIdleStates took " 577 + (SystemClock.elapsedRealtime() - elapsedRealtime)); 578 } 579 return true; 580 } 581 582 /** Check if it's been a while since last parole and let idle apps do some work */ checkParoleTimeout()583 void checkParoleTimeout() { 584 boolean setParoled = false; 585 synchronized (mAppIdleLock) { 586 final long now = System.currentTimeMillis(); 587 if (!mAppIdleTempParoled) { 588 final long timeSinceLastParole = now - mLastAppIdleParoledTime; 589 if (timeSinceLastParole > mAppIdleParoleIntervalMillis) { 590 if (DEBUG) Slog.d(TAG, "Crossed default parole interval"); 591 setParoled = true; 592 } else { 593 if (DEBUG) Slog.d(TAG, "Not long enough to go to parole"); 594 postNextParoleTimeout(now); 595 } 596 } 597 } 598 if (setParoled) { 599 setAppIdleParoled(true); 600 } 601 } 602 notifyBatteryStats(String packageName, int userId, boolean idle)603 private void notifyBatteryStats(String packageName, int userId, boolean idle) { 604 try { 605 final int uid = mPackageManager.getPackageUidAsUser(packageName, 606 PackageManager.MATCH_UNINSTALLED_PACKAGES, userId); 607 if (idle) { 608 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_PACKAGE_INACTIVE, 609 packageName, uid); 610 } else { 611 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_PACKAGE_ACTIVE, 612 packageName, uid); 613 } 614 } catch (NameNotFoundException | RemoteException e) { 615 } 616 } 617 onDeviceIdleModeChanged()618 void onDeviceIdleModeChanged() { 619 final boolean deviceIdle = mPowerManager.isDeviceIdleMode(); 620 if (DEBUG) Slog.i(TAG, "DeviceIdleMode changed to " + deviceIdle); 621 boolean paroled = false; 622 synchronized (mAppIdleLock) { 623 final long timeSinceLastParole = System.currentTimeMillis() - mLastAppIdleParoledTime; 624 if (!deviceIdle 625 && timeSinceLastParole >= mAppIdleParoleIntervalMillis) { 626 if (DEBUG) { 627 Slog.i(TAG, "Bringing idle apps out of inactive state due to deviceIdleMode=false"); 628 } 629 paroled = true; 630 } else if (deviceIdle) { 631 if (DEBUG) Slog.i(TAG, "Device idle, back to prison"); 632 paroled = false; 633 } else { 634 return; 635 } 636 } 637 setAppIdleParoled(paroled); 638 } 639 deleteRecursively(File f)640 private static void deleteRecursively(File f) { 641 File[] files = f.listFiles(); 642 if (files != null) { 643 for (File subFile : files) { 644 deleteRecursively(subFile); 645 } 646 } 647 648 if (!f.delete()) { 649 Slog.e(TAG, "Failed to delete " + f); 650 } 651 } 652 getUserDataAndInitializeIfNeededLocked(int userId, long currentTimeMillis)653 private UserUsageStatsService getUserDataAndInitializeIfNeededLocked(int userId, 654 long currentTimeMillis) { 655 UserUsageStatsService service = mUserState.get(userId); 656 if (service == null) { 657 service = new UserUsageStatsService(getContext(), userId, 658 new File(mUsageStatsDir, Integer.toString(userId)), this); 659 service.init(currentTimeMillis); 660 mUserState.put(userId, service); 661 } 662 return service; 663 } 664 665 /** 666 * This should be the only way to get the time from the system. 667 */ checkAndGetTimeLocked()668 private long checkAndGetTimeLocked() { 669 final long actualSystemTime = System.currentTimeMillis(); 670 final long actualRealtime = SystemClock.elapsedRealtime(); 671 final long expectedSystemTime = (actualRealtime - mRealTimeSnapshot) + mSystemTimeSnapshot; 672 final long diffSystemTime = actualSystemTime - expectedSystemTime; 673 if (Math.abs(diffSystemTime) > TIME_CHANGE_THRESHOLD_MILLIS 674 && ENABLE_TIME_CHANGE_CORRECTION) { 675 // The time has changed. 676 Slog.i(TAG, "Time changed in UsageStats by " + (diffSystemTime / 1000) + " seconds"); 677 final int userCount = mUserState.size(); 678 for (int i = 0; i < userCount; i++) { 679 final UserUsageStatsService service = mUserState.valueAt(i); 680 service.onTimeChanged(expectedSystemTime, actualSystemTime); 681 } 682 mRealTimeSnapshot = actualRealtime; 683 mSystemTimeSnapshot = actualSystemTime; 684 } 685 return actualSystemTime; 686 } 687 688 /** 689 * Assuming the event's timestamp is measured in milliseconds since boot, 690 * convert it to a system wall time. 691 */ convertToSystemTimeLocked(UsageEvents.Event event)692 private void convertToSystemTimeLocked(UsageEvents.Event event) { 693 event.mTimeStamp = Math.max(0, event.mTimeStamp - mRealTimeSnapshot) + mSystemTimeSnapshot; 694 } 695 696 /** 697 * Called by the Binder stub 698 */ shutdown()699 void shutdown() { 700 synchronized (mLock) { 701 mHandler.removeMessages(MSG_REPORT_EVENT); 702 flushToDiskLocked(); 703 } 704 } 705 706 /** 707 * Called by the Binder stub. 708 */ reportEvent(UsageEvents.Event event, int userId)709 void reportEvent(UsageEvents.Event event, int userId) { 710 synchronized (mLock) { 711 final long timeNow = checkAndGetTimeLocked(); 712 final long elapsedRealtime = SystemClock.elapsedRealtime(); 713 convertToSystemTimeLocked(event); 714 715 if (event.getPackageName() != null 716 && mPackageManagerInternal.isPackageEphemeral(userId, event.getPackageName())) { 717 event.mFlags |= Event.FLAG_IS_PACKAGE_INSTANT_APP; 718 } 719 720 final UserUsageStatsService service = 721 getUserDataAndInitializeIfNeededLocked(userId, timeNow); 722 service.reportEvent(event); 723 724 synchronized (mAppIdleLock) { 725 // TODO: Ideally this should call isAppIdleFiltered() to avoid calling back 726 // about apps that are on some kind of whitelist anyway. 727 final boolean previouslyIdle = mAppIdleHistory.isIdle( 728 event.mPackage, userId, elapsedRealtime); 729 // Inform listeners if necessary 730 if ((event.mEventType == Event.MOVE_TO_FOREGROUND 731 || event.mEventType == Event.MOVE_TO_BACKGROUND 732 || event.mEventType == Event.SYSTEM_INTERACTION 733 || event.mEventType == Event.USER_INTERACTION)) { 734 mAppIdleHistory.reportUsage(event.mPackage, userId, elapsedRealtime); 735 if (previouslyIdle) { 736 mHandler.sendMessage(mHandler.obtainMessage(MSG_INFORM_LISTENERS, userId, 737 /* idle = */ 0, event.mPackage)); 738 notifyBatteryStats(event.mPackage, userId, false); 739 } 740 } 741 } 742 } 743 } 744 reportContentProviderUsage(String authority, String providerPkgName, int userId)745 void reportContentProviderUsage(String authority, String providerPkgName, int userId) { 746 // Get sync adapters for the authority 747 String[] packages = ContentResolver.getSyncAdapterPackagesForAuthorityAsUser( 748 authority, userId); 749 for (String packageName: packages) { 750 // Only force the sync adapters to active if the provider is not in the same package and 751 // the sync adapter is a system package. 752 try { 753 PackageInfo pi = mPackageManager.getPackageInfoAsUser( 754 packageName, PackageManager.MATCH_SYSTEM_ONLY, userId); 755 if (pi == null || pi.applicationInfo == null) { 756 continue; 757 } 758 if (!packageName.equals(providerPkgName)) { 759 setAppIdleAsync(packageName, false, userId); 760 } 761 } catch (NameNotFoundException e) { 762 // Shouldn't happen 763 } 764 } 765 } 766 767 /** 768 * Forces the app's beginIdleTime and lastUsedTime to reflect idle or active. If idle, 769 * then it rolls back the beginIdleTime and lastUsedTime to a point in time that's behind 770 * the threshold for idle. 771 * 772 * This method is always called from the handler thread, so not much synchronization is 773 * required. 774 */ forceIdleState(String packageName, int userId, boolean idle)775 void forceIdleState(String packageName, int userId, boolean idle) { 776 final int appId = getAppId(packageName); 777 if (appId < 0) return; 778 final long elapsedRealtime = SystemClock.elapsedRealtime(); 779 780 final boolean previouslyIdle = isAppIdleFiltered(packageName, appId, 781 userId, elapsedRealtime); 782 synchronized (mAppIdleLock) { 783 mAppIdleHistory.setIdle(packageName, userId, idle, elapsedRealtime); 784 } 785 final boolean stillIdle = isAppIdleFiltered(packageName, appId, 786 userId, elapsedRealtime); 787 // Inform listeners if necessary 788 if (previouslyIdle != stillIdle) { 789 mHandler.sendMessage(mHandler.obtainMessage(MSG_INFORM_LISTENERS, userId, 790 /* idle = */ stillIdle ? 1 : 0, packageName)); 791 if (!stillIdle) { 792 notifyBatteryStats(packageName, userId, idle); 793 } 794 } 795 } 796 797 /** 798 * Called by the Binder stub. 799 */ flushToDisk()800 void flushToDisk() { 801 synchronized (mLock) { 802 flushToDiskLocked(); 803 } 804 } 805 806 /** 807 * Called by the Binder stub. 808 */ onUserRemoved(int userId)809 void onUserRemoved(int userId) { 810 synchronized (mLock) { 811 Slog.i(TAG, "Removing user " + userId + " and all data."); 812 mUserState.remove(userId); 813 synchronized (mAppIdleLock) { 814 mAppIdleHistory.onUserRemoved(userId); 815 } 816 cleanUpRemovedUsersLocked(); 817 } 818 } 819 820 /** 821 * Called by the Binder stub. 822 */ queryUsageStats(int userId, int bucketType, long beginTime, long endTime, boolean obfuscateInstantApps)823 List<UsageStats> queryUsageStats(int userId, int bucketType, long beginTime, long endTime, 824 boolean obfuscateInstantApps) { 825 synchronized (mLock) { 826 final long timeNow = checkAndGetTimeLocked(); 827 if (!validRange(timeNow, beginTime, endTime)) { 828 return null; 829 } 830 831 final UserUsageStatsService service = 832 getUserDataAndInitializeIfNeededLocked(userId, timeNow); 833 List<UsageStats> list = service.queryUsageStats(bucketType, beginTime, endTime); 834 if (list == null) { 835 return null; 836 } 837 838 // Mangle instant app names *using their current state (not whether they were ephemeral 839 // when the data was recorded)*. 840 if (obfuscateInstantApps) { 841 for (int i = list.size() - 1; i >= 0; i--) { 842 final UsageStats stats = list.get(i); 843 if (mPackageManagerInternal.isPackageEphemeral(userId, stats.mPackageName)) { 844 list.set(i, stats.getObfuscatedForInstantApp()); 845 } 846 } 847 } 848 849 return list; 850 } 851 } 852 853 /** 854 * Called by the Binder stub. 855 */ queryConfigurationStats(int userId, int bucketType, long beginTime, long endTime)856 List<ConfigurationStats> queryConfigurationStats(int userId, int bucketType, long beginTime, 857 long endTime) { 858 synchronized (mLock) { 859 final long timeNow = checkAndGetTimeLocked(); 860 if (!validRange(timeNow, beginTime, endTime)) { 861 return null; 862 } 863 864 final UserUsageStatsService service = 865 getUserDataAndInitializeIfNeededLocked(userId, timeNow); 866 return service.queryConfigurationStats(bucketType, beginTime, endTime); 867 } 868 } 869 870 /** 871 * Called by the Binder stub. 872 */ queryEvents(int userId, long beginTime, long endTime, boolean shouldObfuscateInstantApps)873 UsageEvents queryEvents(int userId, long beginTime, long endTime, 874 boolean shouldObfuscateInstantApps) { 875 synchronized (mLock) { 876 final long timeNow = checkAndGetTimeLocked(); 877 if (!validRange(timeNow, beginTime, endTime)) { 878 return null; 879 } 880 881 final UserUsageStatsService service = 882 getUserDataAndInitializeIfNeededLocked(userId, timeNow); 883 return service.queryEvents(beginTime, endTime, shouldObfuscateInstantApps); 884 } 885 } 886 isAppIdleUnfiltered(String packageName, int userId, long elapsedRealtime)887 private boolean isAppIdleUnfiltered(String packageName, int userId, long elapsedRealtime) { 888 synchronized (mAppIdleLock) { 889 return mAppIdleHistory.isIdle(packageName, userId, elapsedRealtime); 890 } 891 } 892 addListener(AppIdleStateChangeListener listener)893 void addListener(AppIdleStateChangeListener listener) { 894 synchronized (mAppIdleLock) { 895 if (!mPackageAccessListeners.contains(listener)) { 896 mPackageAccessListeners.add(listener); 897 } 898 } 899 } 900 removeListener(AppIdleStateChangeListener listener)901 void removeListener(AppIdleStateChangeListener listener) { 902 synchronized (mAppIdleLock) { 903 mPackageAccessListeners.remove(listener); 904 } 905 } 906 getAppId(String packageName)907 int getAppId(String packageName) { 908 try { 909 ApplicationInfo ai = mPackageManager.getApplicationInfo(packageName, 910 PackageManager.MATCH_ANY_USER 911 | PackageManager.MATCH_DISABLED_COMPONENTS); 912 return ai.uid; 913 } catch (NameNotFoundException re) { 914 return -1; 915 } 916 } 917 isAppIdleFilteredOrParoled(String packageName, int userId, long elapsedRealtime, boolean shouldObfuscateInstantApps)918 boolean isAppIdleFilteredOrParoled(String packageName, int userId, long elapsedRealtime, 919 boolean shouldObfuscateInstantApps) { 920 if (isParoledOrCharging()) { 921 return false; 922 } 923 if (shouldObfuscateInstantApps && 924 mPackageManagerInternal.isPackageEphemeral(userId, packageName)) { 925 return false; 926 } 927 return isAppIdleFiltered(packageName, getAppId(packageName), userId, elapsedRealtime); 928 } 929 930 /** 931 * Checks if an app has been idle for a while and filters out apps that are excluded. 932 * It returns false if the current system state allows all apps to be considered active. 933 * This happens if the device is plugged in or temporarily allowed to make exceptions. 934 * Called by interface impls. 935 */ isAppIdleFiltered(String packageName, int appId, int userId, long elapsedRealtime)936 private boolean isAppIdleFiltered(String packageName, int appId, int userId, 937 long elapsedRealtime) { 938 if (packageName == null) return false; 939 // If not enabled at all, of course nobody is ever idle. 940 if (!mAppIdleEnabled) { 941 return false; 942 } 943 if (appId < Process.FIRST_APPLICATION_UID) { 944 // System uids never go idle. 945 return false; 946 } 947 if (packageName.equals("android")) { 948 // Nor does the framework (which should be redundant with the above, but for MR1 we will 949 // retain this for safety). 950 return false; 951 } 952 if (mSystemServicesReady) { 953 try { 954 // We allow all whitelisted apps, including those that don't want to be whitelisted 955 // for idle mode, because app idle (aka app standby) is really not as big an issue 956 // for controlling who participates vs. doze mode. 957 if (mDeviceIdleController.isPowerSaveWhitelistExceptIdleApp(packageName)) { 958 return false; 959 } 960 } catch (RemoteException re) { 961 throw re.rethrowFromSystemServer(); 962 } 963 964 if (isActiveDeviceAdmin(packageName, userId)) { 965 return false; 966 } 967 968 if (isActiveNetworkScorer(packageName)) { 969 return false; 970 } 971 972 if (mAppWidgetManager != null 973 && mAppWidgetManager.isBoundWidgetPackage(packageName, userId)) { 974 return false; 975 } 976 977 if (isDeviceProvisioningPackage(packageName)) { 978 return false; 979 } 980 } 981 982 if (!isAppIdleUnfiltered(packageName, userId, elapsedRealtime)) { 983 return false; 984 } 985 986 // Check this last, as it is the most expensive check 987 // TODO: Optimize this by fetching the carrier privileged apps ahead of time 988 if (isCarrierApp(packageName)) { 989 return false; 990 } 991 992 return true; 993 } 994 getIdleUidsForUser(int userId)995 int[] getIdleUidsForUser(int userId) { 996 if (!mAppIdleEnabled) { 997 return new int[0]; 998 } 999 1000 final long elapsedRealtime = SystemClock.elapsedRealtime(); 1001 1002 List<ApplicationInfo> apps; 1003 try { 1004 ParceledListSlice<ApplicationInfo> slice = AppGlobals.getPackageManager() 1005 .getInstalledApplications(/* flags= */ 0, userId); 1006 if (slice == null) { 1007 return new int[0]; 1008 } 1009 apps = slice.getList(); 1010 } catch (RemoteException e) { 1011 throw e.rethrowFromSystemServer(); 1012 } 1013 1014 // State of each uid. Key is the uid. Value lower 16 bits is the number of apps 1015 // associated with that uid, upper 16 bits is the number of those apps that is idle. 1016 SparseIntArray uidStates = new SparseIntArray(); 1017 1018 // Now resolve all app state. Iterating over all apps, keeping track of how many 1019 // we find for each uid and how many of those are idle. 1020 for (int i = apps.size() - 1; i >= 0; i--) { 1021 ApplicationInfo ai = apps.get(i); 1022 1023 // Check whether this app is idle. 1024 boolean idle = isAppIdleFiltered(ai.packageName, UserHandle.getAppId(ai.uid), 1025 userId, elapsedRealtime); 1026 1027 int index = uidStates.indexOfKey(ai.uid); 1028 if (index < 0) { 1029 uidStates.put(ai.uid, 1 + (idle ? 1<<16 : 0)); 1030 } else { 1031 int value = uidStates.valueAt(index); 1032 uidStates.setValueAt(index, value + 1 + (idle ? 1<<16 : 0)); 1033 } 1034 } 1035 if (DEBUG) { 1036 Slog.d(TAG, "getIdleUids took " + (SystemClock.elapsedRealtime() - elapsedRealtime)); 1037 } 1038 int numIdle = 0; 1039 for (int i = uidStates.size() - 1; i >= 0; i--) { 1040 int value = uidStates.valueAt(i); 1041 if ((value&0x7fff) == (value>>16)) { 1042 numIdle++; 1043 } 1044 } 1045 1046 int[] res = new int[numIdle]; 1047 numIdle = 0; 1048 for (int i = uidStates.size() - 1; i >= 0; i--) { 1049 int value = uidStates.valueAt(i); 1050 if ((value&0x7fff) == (value>>16)) { 1051 res[numIdle] = uidStates.keyAt(i); 1052 numIdle++; 1053 } 1054 } 1055 1056 return res; 1057 } 1058 setAppIdleAsync(String packageName, boolean idle, int userId)1059 void setAppIdleAsync(String packageName, boolean idle, int userId) { 1060 if (packageName == null) return; 1061 1062 mHandler.obtainMessage(MSG_FORCE_IDLE_STATE, userId, idle ? 1 : 0, packageName) 1063 .sendToTarget(); 1064 } 1065 isActiveDeviceAdmin(String packageName, int userId)1066 private boolean isActiveDeviceAdmin(String packageName, int userId) { 1067 DevicePolicyManager dpm = getContext().getSystemService(DevicePolicyManager.class); 1068 if (dpm == null) return false; 1069 return dpm.packageHasActiveAdmins(packageName, userId); 1070 } 1071 1072 /** 1073 * Returns {@code true} if the supplied package is the device provisioning app. Otherwise, 1074 * returns {@code false}. 1075 */ isDeviceProvisioningPackage(String packageName)1076 private boolean isDeviceProvisioningPackage(String packageName) { 1077 String deviceProvisioningPackage = getContext().getResources().getString( 1078 com.android.internal.R.string.config_deviceProvisioningPackage); 1079 return deviceProvisioningPackage != null && deviceProvisioningPackage.equals(packageName); 1080 } 1081 isCarrierApp(String packageName)1082 private boolean isCarrierApp(String packageName) { 1083 synchronized (mAppIdleLock) { 1084 if (!mHaveCarrierPrivilegedApps) { 1085 fetchCarrierPrivilegedAppsLA(); 1086 } 1087 if (mCarrierPrivilegedApps != null) { 1088 return mCarrierPrivilegedApps.contains(packageName); 1089 } 1090 return false; 1091 } 1092 } 1093 clearCarrierPrivilegedApps()1094 void clearCarrierPrivilegedApps() { 1095 if (DEBUG) { 1096 Slog.i(TAG, "Clearing carrier privileged apps list"); 1097 } 1098 synchronized (mAppIdleLock) { 1099 mHaveCarrierPrivilegedApps = false; 1100 mCarrierPrivilegedApps = null; // Need to be refetched. 1101 } 1102 } 1103 1104 @GuardedBy("mAppIdleLock") fetchCarrierPrivilegedAppsLA()1105 private void fetchCarrierPrivilegedAppsLA() { 1106 TelephonyManager telephonyManager = 1107 getContext().getSystemService(TelephonyManager.class); 1108 mCarrierPrivilegedApps = telephonyManager.getPackagesWithCarrierPrivileges(); 1109 mHaveCarrierPrivilegedApps = true; 1110 if (DEBUG) { 1111 Slog.d(TAG, "apps with carrier privilege " + mCarrierPrivilegedApps); 1112 } 1113 } 1114 isActiveNetworkScorer(String packageName)1115 private boolean isActiveNetworkScorer(String packageName) { 1116 NetworkScoreManager nsm = (NetworkScoreManager) getContext().getSystemService( 1117 Context.NETWORK_SCORE_SERVICE); 1118 return packageName != null && packageName.equals(nsm.getActiveScorerPackage()); 1119 } 1120 informListeners(String packageName, int userId, boolean isIdle)1121 void informListeners(String packageName, int userId, boolean isIdle) { 1122 for (AppIdleStateChangeListener listener : mPackageAccessListeners) { 1123 listener.onAppIdleStateChanged(packageName, userId, isIdle); 1124 } 1125 } 1126 informParoleStateChanged()1127 void informParoleStateChanged() { 1128 final boolean paroled = isParoledOrCharging(); 1129 for (AppIdleStateChangeListener listener : mPackageAccessListeners) { 1130 listener.onParoleStateChanged(paroled); 1131 } 1132 } 1133 validRange(long currentTime, long beginTime, long endTime)1134 private static boolean validRange(long currentTime, long beginTime, long endTime) { 1135 return beginTime <= currentTime && beginTime < endTime; 1136 } 1137 flushToDiskLocked()1138 private void flushToDiskLocked() { 1139 final int userCount = mUserState.size(); 1140 for (int i = 0; i < userCount; i++) { 1141 UserUsageStatsService service = mUserState.valueAt(i); 1142 service.persistActiveStats(); 1143 synchronized (mAppIdleLock) { 1144 mAppIdleHistory.writeAppIdleTimes(mUserState.keyAt(i)); 1145 } 1146 } 1147 // Persist elapsed and screen on time. If this fails for whatever reason, the apps will be 1148 // considered not-idle, which is the safest outcome in such an event. 1149 synchronized (mAppIdleLock) { 1150 mAppIdleHistory.writeAppIdleDurations(); 1151 } 1152 mHandler.removeMessages(MSG_FLUSH_TO_DISK); 1153 } 1154 1155 /** 1156 * Called by the Binder stub. 1157 */ dump(String[] args, PrintWriter pw)1158 void dump(String[] args, PrintWriter pw) { 1159 synchronized (mLock) { 1160 IndentingPrintWriter idpw = new IndentingPrintWriter(pw, " "); 1161 ArraySet<String> argSet = new ArraySet<>(); 1162 argSet.addAll(Arrays.asList(args)); 1163 1164 final int userCount = mUserState.size(); 1165 for (int i = 0; i < userCount; i++) { 1166 idpw.printPair("user", mUserState.keyAt(i)); 1167 idpw.println(); 1168 idpw.increaseIndent(); 1169 if (argSet.contains("--checkin")) { 1170 mUserState.valueAt(i).checkin(idpw); 1171 } else { 1172 mUserState.valueAt(i).dump(idpw); 1173 idpw.println(); 1174 if (args.length > 0) { 1175 if ("history".equals(args[0])) { 1176 synchronized (mAppIdleLock) { 1177 mAppIdleHistory.dumpHistory(idpw, mUserState.keyAt(i)); 1178 } 1179 } else if ("flush".equals(args[0])) { 1180 UsageStatsService.this.flushToDiskLocked(); 1181 pw.println("Flushed stats to disk"); 1182 } 1183 } 1184 } 1185 synchronized (mAppIdleLock) { 1186 mAppIdleHistory.dump(idpw, mUserState.keyAt(i)); 1187 } 1188 idpw.decreaseIndent(); 1189 } 1190 1191 pw.println(); 1192 synchronized (mAppIdleLock) { 1193 pw.println("Carrier privileged apps (have=" + mHaveCarrierPrivilegedApps 1194 + "): " + mCarrierPrivilegedApps); 1195 } 1196 1197 pw.println(); 1198 pw.println("Settings:"); 1199 1200 pw.print(" mAppIdleDurationMillis="); 1201 TimeUtils.formatDuration(mAppIdleScreenThresholdMillis, pw); 1202 pw.println(); 1203 1204 pw.print(" mAppIdleWallclockThresholdMillis="); 1205 TimeUtils.formatDuration(mAppIdleWallclockThresholdMillis, pw); 1206 pw.println(); 1207 1208 pw.print(" mCheckIdleIntervalMillis="); 1209 TimeUtils.formatDuration(mCheckIdleIntervalMillis, pw); 1210 pw.println(); 1211 1212 pw.print(" mAppIdleParoleIntervalMillis="); 1213 TimeUtils.formatDuration(mAppIdleParoleIntervalMillis, pw); 1214 pw.println(); 1215 1216 pw.print(" mAppIdleParoleDurationMillis="); 1217 TimeUtils.formatDuration(mAppIdleParoleDurationMillis, pw); 1218 pw.println(); 1219 1220 pw.println(); 1221 pw.print("mAppIdleEnabled="); pw.print(mAppIdleEnabled); 1222 pw.print(" mAppIdleTempParoled="); pw.print(mAppIdleTempParoled); 1223 pw.print(" mCharging="); pw.print(mCharging); 1224 pw.print(" mLastAppIdleParoledTime="); 1225 TimeUtils.formatDuration(mLastAppIdleParoledTime, pw); 1226 pw.println(); 1227 } 1228 } 1229 1230 class H extends Handler { H(Looper looper)1231 public H(Looper looper) { 1232 super(looper); 1233 } 1234 1235 @Override handleMessage(Message msg)1236 public void handleMessage(Message msg) { 1237 switch (msg.what) { 1238 case MSG_REPORT_EVENT: 1239 reportEvent((UsageEvents.Event) msg.obj, msg.arg1); 1240 break; 1241 1242 case MSG_FLUSH_TO_DISK: 1243 flushToDisk(); 1244 break; 1245 1246 case MSG_REMOVE_USER: 1247 onUserRemoved(msg.arg1); 1248 break; 1249 1250 case MSG_INFORM_LISTENERS: 1251 informListeners((String) msg.obj, msg.arg1, msg.arg2 == 1); 1252 break; 1253 1254 case MSG_FORCE_IDLE_STATE: 1255 forceIdleState((String) msg.obj, msg.arg1, msg.arg2 == 1); 1256 break; 1257 1258 case MSG_CHECK_IDLE_STATES: 1259 if (checkIdleStates(msg.arg1)) { 1260 mHandler.sendMessageDelayed(mHandler.obtainMessage( 1261 MSG_CHECK_IDLE_STATES, msg.arg1, 0), 1262 mCheckIdleIntervalMillis); 1263 } 1264 break; 1265 1266 case MSG_ONE_TIME_CHECK_IDLE_STATES: 1267 mHandler.removeMessages(MSG_ONE_TIME_CHECK_IDLE_STATES); 1268 checkIdleStates(UserHandle.USER_ALL); 1269 break; 1270 1271 case MSG_CHECK_PAROLE_TIMEOUT: 1272 checkParoleTimeout(); 1273 break; 1274 1275 case MSG_PAROLE_END_TIMEOUT: 1276 if (DEBUG) Slog.d(TAG, "Ending parole"); 1277 setAppIdleParoled(false); 1278 break; 1279 1280 case MSG_REPORT_CONTENT_PROVIDER_USAGE: 1281 SomeArgs args = (SomeArgs) msg.obj; 1282 reportContentProviderUsage((String) args.arg1, // authority name 1283 (String) args.arg2, // package name 1284 (int) args.arg3); // userId 1285 args.recycle(); 1286 break; 1287 1288 case MSG_PAROLE_STATE_CHANGED: 1289 if (DEBUG) Slog.d(TAG, "Parole state: " + mAppIdleTempParoled 1290 + ", Charging state:" + mCharging); 1291 informParoleStateChanged(); 1292 break; 1293 1294 default: 1295 super.handleMessage(msg); 1296 break; 1297 } 1298 } 1299 } 1300 1301 /** 1302 * Observe settings changes for {@link Settings.Global#APP_IDLE_CONSTANTS}. 1303 */ 1304 private class SettingsObserver extends ContentObserver { 1305 /** 1306 * This flag has been used to disable app idle on older builds with bug b/26355386. 1307 */ 1308 @Deprecated 1309 private static final String KEY_IDLE_DURATION_OLD = "idle_duration"; 1310 1311 private static final String KEY_IDLE_DURATION = "idle_duration2"; 1312 private static final String KEY_WALLCLOCK_THRESHOLD = "wallclock_threshold"; 1313 private static final String KEY_PAROLE_INTERVAL = "parole_interval"; 1314 private static final String KEY_PAROLE_DURATION = "parole_duration"; 1315 1316 private final KeyValueListParser mParser = new KeyValueListParser(','); 1317 SettingsObserver(Handler handler)1318 SettingsObserver(Handler handler) { 1319 super(handler); 1320 } 1321 registerObserver()1322 void registerObserver() { 1323 getContext().getContentResolver().registerContentObserver(Settings.Global.getUriFor( 1324 Settings.Global.APP_IDLE_CONSTANTS), false, this); 1325 } 1326 1327 @Override onChange(boolean selfChange)1328 public void onChange(boolean selfChange) { 1329 updateSettings(); 1330 postOneTimeCheckIdleStates(); 1331 } 1332 updateSettings()1333 void updateSettings() { 1334 synchronized (mAppIdleLock) { 1335 // Look at global settings for this. 1336 // TODO: Maybe apply different thresholds for different users. 1337 try { 1338 mParser.setString(Settings.Global.getString(getContext().getContentResolver(), 1339 Settings.Global.APP_IDLE_CONSTANTS)); 1340 } catch (IllegalArgumentException e) { 1341 Slog.e(TAG, "Bad value for app idle settings: " + e.getMessage()); 1342 // fallthrough, mParser is empty and all defaults will be returned. 1343 } 1344 1345 // Default: 12 hours of screen-on time sans dream-time 1346 mAppIdleScreenThresholdMillis = mParser.getLong(KEY_IDLE_DURATION, 1347 COMPRESS_TIME ? ONE_MINUTE * 4 : 12 * 60 * ONE_MINUTE); 1348 1349 mAppIdleWallclockThresholdMillis = mParser.getLong(KEY_WALLCLOCK_THRESHOLD, 1350 COMPRESS_TIME ? ONE_MINUTE * 8 : 2L * 24 * 60 * ONE_MINUTE); // 2 days 1351 1352 mCheckIdleIntervalMillis = Math.min(mAppIdleScreenThresholdMillis / 4, 1353 COMPRESS_TIME ? ONE_MINUTE : 8 * 60 * ONE_MINUTE); // 8 hours 1354 1355 // Default: 24 hours between paroles 1356 mAppIdleParoleIntervalMillis = mParser.getLong(KEY_PAROLE_INTERVAL, 1357 COMPRESS_TIME ? ONE_MINUTE * 10 : 24 * 60 * ONE_MINUTE); 1358 1359 mAppIdleParoleDurationMillis = mParser.getLong(KEY_PAROLE_DURATION, 1360 COMPRESS_TIME ? ONE_MINUTE : 10 * ONE_MINUTE); // 10 minutes 1361 mAppIdleHistory.setThresholds(mAppIdleWallclockThresholdMillis, 1362 mAppIdleScreenThresholdMillis); 1363 } 1364 } 1365 } 1366 1367 private final class BinderService extends IUsageStatsManager.Stub { 1368 hasPermission(String callingPackage)1369 private boolean hasPermission(String callingPackage) { 1370 final int callingUid = Binder.getCallingUid(); 1371 if (callingUid == Process.SYSTEM_UID) { 1372 return true; 1373 } 1374 final int mode = mAppOps.checkOp(AppOpsManager.OP_GET_USAGE_STATS, 1375 callingUid, callingPackage); 1376 if (mode == AppOpsManager.MODE_DEFAULT) { 1377 // The default behavior here is to check if PackageManager has given the app 1378 // permission. 1379 return getContext().checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS) 1380 == PackageManager.PERMISSION_GRANTED; 1381 } 1382 return mode == AppOpsManager.MODE_ALLOWED; 1383 } 1384 1385 @Override queryUsageStats(int bucketType, long beginTime, long endTime, String callingPackage)1386 public ParceledListSlice<UsageStats> queryUsageStats(int bucketType, long beginTime, 1387 long endTime, String callingPackage) { 1388 if (!hasPermission(callingPackage)) { 1389 return null; 1390 } 1391 1392 final boolean obfuscateInstantApps = shouldObfuscateInstantAppsForCaller( 1393 Binder.getCallingUid(), UserHandle.getCallingUserId()); 1394 1395 final int userId = UserHandle.getCallingUserId(); 1396 final long token = Binder.clearCallingIdentity(); 1397 try { 1398 final List<UsageStats> results = UsageStatsService.this.queryUsageStats( 1399 userId, bucketType, beginTime, endTime, obfuscateInstantApps); 1400 if (results != null) { 1401 return new ParceledListSlice<>(results); 1402 } 1403 } finally { 1404 Binder.restoreCallingIdentity(token); 1405 } 1406 return null; 1407 } 1408 1409 @Override queryConfigurationStats(int bucketType, long beginTime, long endTime, String callingPackage)1410 public ParceledListSlice<ConfigurationStats> queryConfigurationStats(int bucketType, 1411 long beginTime, long endTime, String callingPackage) throws RemoteException { 1412 if (!hasPermission(callingPackage)) { 1413 return null; 1414 } 1415 1416 final int userId = UserHandle.getCallingUserId(); 1417 final long token = Binder.clearCallingIdentity(); 1418 try { 1419 final List<ConfigurationStats> results = 1420 UsageStatsService.this.queryConfigurationStats(userId, bucketType, 1421 beginTime, endTime); 1422 if (results != null) { 1423 return new ParceledListSlice<>(results); 1424 } 1425 } finally { 1426 Binder.restoreCallingIdentity(token); 1427 } 1428 return null; 1429 } 1430 1431 @Override queryEvents(long beginTime, long endTime, String callingPackage)1432 public UsageEvents queryEvents(long beginTime, long endTime, String callingPackage) { 1433 if (!hasPermission(callingPackage)) { 1434 return null; 1435 } 1436 1437 final boolean obfuscateInstantApps = shouldObfuscateInstantAppsForCaller( 1438 Binder.getCallingUid(), UserHandle.getCallingUserId()); 1439 1440 final int userId = UserHandle.getCallingUserId(); 1441 final long token = Binder.clearCallingIdentity(); 1442 try { 1443 return UsageStatsService.this.queryEvents(userId, beginTime, endTime, 1444 obfuscateInstantApps); 1445 } finally { 1446 Binder.restoreCallingIdentity(token); 1447 } 1448 } 1449 1450 @Override isAppInactive(String packageName, int userId)1451 public boolean isAppInactive(String packageName, int userId) { 1452 try { 1453 userId = ActivityManager.getService().handleIncomingUser(Binder.getCallingPid(), 1454 Binder.getCallingUid(), userId, false, true, "isAppInactive", null); 1455 } catch (RemoteException re) { 1456 throw re.rethrowFromSystemServer(); 1457 } 1458 final boolean obfuscateInstantApps = shouldObfuscateInstantAppsForCaller( 1459 Binder.getCallingUid(), userId); 1460 final long token = Binder.clearCallingIdentity(); 1461 try { 1462 return UsageStatsService.this.isAppIdleFilteredOrParoled(packageName, userId, 1463 SystemClock.elapsedRealtime(), obfuscateInstantApps); 1464 } finally { 1465 Binder.restoreCallingIdentity(token); 1466 } 1467 } 1468 1469 @Override setAppInactive(String packageName, boolean idle, int userId)1470 public void setAppInactive(String packageName, boolean idle, int userId) { 1471 final int callingUid = Binder.getCallingUid(); 1472 try { 1473 userId = ActivityManager.getService().handleIncomingUser( 1474 Binder.getCallingPid(), callingUid, userId, false, true, 1475 "setAppInactive", null); 1476 } catch (RemoteException re) { 1477 throw re.rethrowFromSystemServer(); 1478 } 1479 getContext().enforceCallingPermission(Manifest.permission.CHANGE_APP_IDLE_STATE, 1480 "No permission to change app idle state"); 1481 final long token = Binder.clearCallingIdentity(); 1482 try { 1483 final int appId = getAppId(packageName); 1484 if (appId < 0) return; 1485 UsageStatsService.this.setAppIdleAsync(packageName, idle, userId); 1486 } finally { 1487 Binder.restoreCallingIdentity(token); 1488 } 1489 } 1490 1491 @Override whitelistAppTemporarily(String packageName, long duration, int userId)1492 public void whitelistAppTemporarily(String packageName, long duration, int userId) 1493 throws RemoteException { 1494 StringBuilder reason = new StringBuilder(32); 1495 reason.append("from:"); 1496 UserHandle.formatUid(reason, Binder.getCallingUid()); 1497 mDeviceIdleController.addPowerSaveTempWhitelistApp(packageName, duration, userId, 1498 reason.toString()); 1499 } 1500 1501 @Override onCarrierPrivilegedAppsChanged()1502 public void onCarrierPrivilegedAppsChanged() { 1503 if (DEBUG) { 1504 Slog.i(TAG, "Carrier privileged apps changed"); 1505 } 1506 getContext().enforceCallingOrSelfPermission( 1507 android.Manifest.permission.BIND_CARRIER_SERVICES, 1508 "onCarrierPrivilegedAppsChanged can only be called by privileged apps."); 1509 UsageStatsService.this.clearCarrierPrivilegedApps(); 1510 } 1511 1512 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)1513 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1514 if (!DumpUtils.checkDumpAndUsageStatsPermission(getContext(), TAG, pw)) return; 1515 UsageStatsService.this.dump(args, pw); 1516 } 1517 1518 @Override reportChooserSelection(String packageName, int userId, String contentType, String[] annotations, String action)1519 public void reportChooserSelection(String packageName, int userId, String contentType, 1520 String[] annotations, String action) { 1521 if (packageName == null) { 1522 Slog.w(TAG, "Event report user selecting a null package"); 1523 return; 1524 } 1525 1526 UsageEvents.Event event = new UsageEvents.Event(); 1527 event.mPackage = packageName; 1528 1529 // This will later be converted to system time. 1530 event.mTimeStamp = SystemClock.elapsedRealtime(); 1531 1532 event.mEventType = Event.CHOOSER_ACTION; 1533 1534 event.mAction = action; 1535 1536 event.mContentType = contentType; 1537 1538 event.mContentAnnotations = annotations; 1539 1540 mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget(); 1541 } 1542 } 1543 1544 /** 1545 * This local service implementation is primarily used by ActivityManagerService. 1546 * ActivityManagerService will call these methods holding the 'am' lock, which means we 1547 * shouldn't be doing any IO work or other long running tasks in these methods. 1548 */ 1549 private final class LocalService extends UsageStatsManagerInternal { 1550 1551 @Override reportEvent(ComponentName component, int userId, int eventType)1552 public void reportEvent(ComponentName component, int userId, int eventType) { 1553 if (component == null) { 1554 Slog.w(TAG, "Event reported without a component name"); 1555 return; 1556 } 1557 1558 UsageEvents.Event event = new UsageEvents.Event(); 1559 event.mPackage = component.getPackageName(); 1560 event.mClass = component.getClassName(); 1561 1562 // This will later be converted to system time. 1563 event.mTimeStamp = SystemClock.elapsedRealtime(); 1564 1565 event.mEventType = eventType; 1566 mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget(); 1567 } 1568 1569 @Override reportEvent(String packageName, int userId, int eventType)1570 public void reportEvent(String packageName, int userId, int eventType) { 1571 if (packageName == null) { 1572 Slog.w(TAG, "Event reported without a package name"); 1573 return; 1574 } 1575 1576 UsageEvents.Event event = new UsageEvents.Event(); 1577 event.mPackage = packageName; 1578 1579 // This will later be converted to system time. 1580 event.mTimeStamp = SystemClock.elapsedRealtime(); 1581 1582 event.mEventType = eventType; 1583 mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget(); 1584 } 1585 1586 @Override reportConfigurationChange(Configuration config, int userId)1587 public void reportConfigurationChange(Configuration config, int userId) { 1588 if (config == null) { 1589 Slog.w(TAG, "Configuration event reported with a null config"); 1590 return; 1591 } 1592 1593 UsageEvents.Event event = new UsageEvents.Event(); 1594 event.mPackage = "android"; 1595 1596 // This will later be converted to system time. 1597 event.mTimeStamp = SystemClock.elapsedRealtime(); 1598 1599 event.mEventType = UsageEvents.Event.CONFIGURATION_CHANGE; 1600 event.mConfiguration = new Configuration(config); 1601 mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget(); 1602 } 1603 1604 @Override reportShortcutUsage(String packageName, String shortcutId, int userId)1605 public void reportShortcutUsage(String packageName, String shortcutId, int userId) { 1606 if (packageName == null || shortcutId == null) { 1607 Slog.w(TAG, "Event reported without a package name or a shortcut ID"); 1608 return; 1609 } 1610 1611 UsageEvents.Event event = new UsageEvents.Event(); 1612 event.mPackage = packageName.intern(); 1613 event.mShortcutId = shortcutId.intern(); 1614 1615 // This will later be converted to system time. 1616 event.mTimeStamp = SystemClock.elapsedRealtime(); 1617 1618 event.mEventType = Event.SHORTCUT_INVOCATION; 1619 mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget(); 1620 } 1621 1622 @Override reportContentProviderUsage(String name, String packageName, int userId)1623 public void reportContentProviderUsage(String name, String packageName, int userId) { 1624 SomeArgs args = SomeArgs.obtain(); 1625 args.arg1 = name; 1626 args.arg2 = packageName; 1627 args.arg3 = userId; 1628 mHandler.obtainMessage(MSG_REPORT_CONTENT_PROVIDER_USAGE, args) 1629 .sendToTarget(); 1630 } 1631 1632 @Override isAppIdle(String packageName, int uidForAppId, int userId)1633 public boolean isAppIdle(String packageName, int uidForAppId, int userId) { 1634 return UsageStatsService.this.isAppIdleFiltered(packageName, uidForAppId, userId, 1635 SystemClock.elapsedRealtime()); 1636 } 1637 1638 @Override getIdleUidsForUser(int userId)1639 public int[] getIdleUidsForUser(int userId) { 1640 return UsageStatsService.this.getIdleUidsForUser(userId); 1641 } 1642 1643 @Override isAppIdleParoleOn()1644 public boolean isAppIdleParoleOn() { 1645 return isParoledOrCharging(); 1646 } 1647 1648 @Override prepareShutdown()1649 public void prepareShutdown() { 1650 // This method *WILL* do IO work, but we must block until it is finished or else 1651 // we might not shutdown cleanly. This is ok to do with the 'am' lock held, because 1652 // we are shutting down. 1653 shutdown(); 1654 } 1655 1656 @Override addAppIdleStateChangeListener(AppIdleStateChangeListener listener)1657 public void addAppIdleStateChangeListener(AppIdleStateChangeListener listener) { 1658 UsageStatsService.this.addListener(listener); 1659 listener.onParoleStateChanged(isAppIdleParoleOn()); 1660 } 1661 1662 @Override removeAppIdleStateChangeListener( AppIdleStateChangeListener listener)1663 public void removeAppIdleStateChangeListener( 1664 AppIdleStateChangeListener listener) { 1665 UsageStatsService.this.removeListener(listener); 1666 } 1667 1668 @Override getBackupPayload(int user, String key)1669 public byte[] getBackupPayload(int user, String key) { 1670 // Check to ensure that only user 0's data is b/r for now 1671 synchronized (UsageStatsService.this.mLock) { 1672 if (user == UserHandle.USER_SYSTEM) { 1673 final UserUsageStatsService userStats = 1674 getUserDataAndInitializeIfNeededLocked(user, checkAndGetTimeLocked()); 1675 return userStats.getBackupPayload(key); 1676 } else { 1677 return null; 1678 } 1679 } 1680 } 1681 1682 @Override applyRestoredPayload(int user, String key, byte[] payload)1683 public void applyRestoredPayload(int user, String key, byte[] payload) { 1684 synchronized (UsageStatsService.this.mLock) { 1685 if (user == UserHandle.USER_SYSTEM) { 1686 final UserUsageStatsService userStats = 1687 getUserDataAndInitializeIfNeededLocked(user, checkAndGetTimeLocked()); 1688 userStats.applyRestoredPayload(key, payload); 1689 } 1690 } 1691 } 1692 1693 @Override queryUsageStatsForUser( int userId, int intervalType, long beginTime, long endTime, boolean obfuscateInstantApps)1694 public List<UsageStats> queryUsageStatsForUser( 1695 int userId, int intervalType, long beginTime, long endTime, 1696 boolean obfuscateInstantApps) { 1697 return UsageStatsService.this.queryUsageStats( 1698 userId, intervalType, beginTime, endTime, obfuscateInstantApps); 1699 } 1700 } 1701 } 1702