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