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 static android.app.usage.UsageEvents.Event.CHOOSER_ACTION; 20 import static android.app.usage.UsageEvents.Event.CONFIGURATION_CHANGE; 21 import static android.app.usage.UsageEvents.Event.DEVICE_SHUTDOWN; 22 import static android.app.usage.UsageEvents.Event.FLUSH_TO_DISK; 23 import static android.app.usage.UsageEvents.Event.NOTIFICATION_INTERRUPTION; 24 import static android.app.usage.UsageEvents.Event.SHORTCUT_INVOCATION; 25 import static android.app.usage.UsageStatsManager.USAGE_SOURCE_CURRENT_ACTIVITY; 26 import static android.app.usage.UsageStatsManager.USAGE_SOURCE_TASK_ROOT_ACTIVITY; 27 28 import android.Manifest; 29 import android.app.ActivityManager; 30 import android.app.AppOpsManager; 31 import android.app.IUidObserver; 32 import android.app.PendingIntent; 33 import android.app.admin.DeviceAdminInfo; 34 import android.app.admin.DevicePolicyManagerInternal; 35 import android.app.usage.AppStandbyInfo; 36 import android.app.usage.ConfigurationStats; 37 import android.app.usage.EventStats; 38 import android.app.usage.IUsageStatsManager; 39 import android.app.usage.UsageEvents; 40 import android.app.usage.UsageEvents.Event; 41 import android.app.usage.UsageStats; 42 import android.app.usage.UsageStatsManager; 43 import android.app.usage.UsageStatsManager.StandbyBuckets; 44 import android.app.usage.UsageStatsManager.UsageSource; 45 import android.app.usage.UsageStatsManagerInternal; 46 import android.content.BroadcastReceiver; 47 import android.content.ComponentName; 48 import android.content.Context; 49 import android.content.Intent; 50 import android.content.IntentFilter; 51 import android.content.pm.PackageManager; 52 import android.content.pm.PackageManagerInternal; 53 import android.content.pm.ParceledListSlice; 54 import android.content.pm.UserInfo; 55 import android.content.res.Configuration; 56 import android.os.Binder; 57 import android.os.Environment; 58 import android.os.FileUtils; 59 import android.os.Handler; 60 import android.os.IBinder; 61 import android.os.IDeviceIdleController; 62 import android.os.Looper; 63 import android.os.Message; 64 import android.os.Process; 65 import android.os.RemoteException; 66 import android.os.ServiceManager; 67 import android.os.SystemClock; 68 import android.os.SystemProperties; 69 import android.os.UserHandle; 70 import android.os.UserManager; 71 import android.provider.Settings; 72 import android.util.ArraySet; 73 import android.util.Slog; 74 import android.util.SparseArray; 75 import android.util.SparseIntArray; 76 77 import com.android.internal.content.PackageMonitor; 78 import com.android.internal.os.BackgroundThread; 79 import com.android.internal.util.DumpUtils; 80 import com.android.internal.util.IndentingPrintWriter; 81 import com.android.server.LocalServices; 82 import com.android.server.SystemService; 83 84 import java.io.File; 85 import java.io.FileDescriptor; 86 import java.io.IOException; 87 import java.io.PrintWriter; 88 import java.util.Arrays; 89 import java.util.List; 90 import java.util.Set; 91 92 /** 93 * A service that collects, aggregates, and persists application usage data. 94 * This data can be queried by apps that have been granted permission by AppOps. 95 */ 96 public class UsageStatsService extends SystemService implements 97 UserUsageStatsService.StatsUpdatedListener { 98 99 static final String TAG = "UsageStatsService"; 100 public static final boolean ENABLE_TIME_CHANGE_CORRECTION 101 = SystemProperties.getBoolean("persist.debug.time_correction", true); 102 103 static final boolean DEBUG = false; // Never submit with true 104 static final boolean COMPRESS_TIME = false; 105 106 private static final long TEN_SECONDS = 10 * 1000; 107 private static final long TWENTY_MINUTES = 20 * 60 * 1000; 108 private static final long FLUSH_INTERVAL = COMPRESS_TIME ? TEN_SECONDS : TWENTY_MINUTES; 109 private static final long TIME_CHANGE_THRESHOLD_MILLIS = 2 * 1000; // Two seconds. 110 111 private static final boolean ENABLE_KERNEL_UPDATES = true; 112 private static final File KERNEL_COUNTER_FILE = new File("/proc/uid_procstat/set"); 113 114 private static final char TOKEN_DELIMITER = '/'; 115 116 // Handler message types. 117 static final int MSG_REPORT_EVENT = 0; 118 static final int MSG_FLUSH_TO_DISK = 1; 119 static final int MSG_REMOVE_USER = 2; 120 static final int MSG_UID_STATE_CHANGED = 3; 121 static final int MSG_REPORT_EVENT_TO_ALL_USERID = 4; 122 123 private final Object mLock = new Object(); 124 Handler mHandler; 125 AppOpsManager mAppOps; 126 UserManager mUserManager; 127 PackageManager mPackageManager; 128 PackageManagerInternal mPackageManagerInternal; 129 PackageMonitor mPackageMonitor; 130 IDeviceIdleController mDeviceIdleController; 131 // Do not use directly. Call getDpmInternal() instead 132 DevicePolicyManagerInternal mDpmInternal; 133 134 private final SparseArray<UserUsageStatsService> mUserState = new SparseArray<>(); 135 private final SparseIntArray mUidToKernelCounter = new SparseIntArray(); 136 private File mUsageStatsDir; 137 long mRealTimeSnapshot; 138 long mSystemTimeSnapshot; 139 int mUsageSource; 140 141 /** Manages the standby state of apps. */ 142 AppStandbyController mAppStandby; 143 144 /** Manages app time limit observers */ 145 AppTimeLimitController mAppTimeLimit; 146 147 final SparseArray<ArraySet<String>> mUsageReporters = new SparseArray(); 148 final SparseArray<ActivityData> mVisibleActivities = new SparseArray(); 149 150 private static class ActivityData { 151 private final String mTaskRootPackage; 152 private final String mTaskRootClass; ActivityData(String taskRootPackage, String taskRootClass)153 private ActivityData(String taskRootPackage, String taskRootClass) { 154 mTaskRootPackage = taskRootPackage; 155 mTaskRootClass = taskRootClass; 156 } 157 } 158 159 private UsageStatsManagerInternal.AppIdleStateChangeListener mStandbyChangeListener = 160 new UsageStatsManagerInternal.AppIdleStateChangeListener() { 161 @Override 162 public void onAppIdleStateChanged(String packageName, int userId, boolean idle, 163 int bucket, int reason) { 164 Event event = new Event(Event.STANDBY_BUCKET_CHANGED, 165 SystemClock.elapsedRealtime()); 166 event.mBucketAndReason = (bucket << 16) | (reason & 0xFFFF); 167 event.mPackage = packageName; 168 mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget(); 169 } 170 171 @Override 172 public void onParoleStateChanged(boolean isParoleOn) { 173 174 } 175 }; 176 UsageStatsService(Context context)177 public UsageStatsService(Context context) { 178 super(context); 179 } 180 181 @Override onStart()182 public void onStart() { 183 mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE); 184 mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE); 185 mPackageManager = getContext().getPackageManager(); 186 mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class); 187 mHandler = new H(BackgroundThread.get().getLooper()); 188 189 mAppStandby = new AppStandbyController(getContext(), BackgroundThread.get().getLooper()); 190 191 mAppTimeLimit = new AppTimeLimitController( 192 new AppTimeLimitController.TimeLimitCallbackListener() { 193 @Override 194 public void onLimitReached(int observerId, int userId, long timeLimit, 195 long timeElapsed, PendingIntent callbackIntent) { 196 if (callbackIntent == null) return; 197 Intent intent = new Intent(); 198 intent.putExtra(UsageStatsManager.EXTRA_OBSERVER_ID, observerId); 199 intent.putExtra(UsageStatsManager.EXTRA_TIME_LIMIT, timeLimit); 200 intent.putExtra(UsageStatsManager.EXTRA_TIME_USED, timeElapsed); 201 try { 202 callbackIntent.send(getContext(), 0, intent); 203 } catch (PendingIntent.CanceledException e) { 204 Slog.w(TAG, "Couldn't deliver callback: " 205 + callbackIntent); 206 } 207 } 208 209 @Override 210 public void onSessionEnd(int observerId, int userId, long timeElapsed, 211 PendingIntent callbackIntent) { 212 if (callbackIntent == null) return; 213 Intent intent = new Intent(); 214 intent.putExtra(UsageStatsManager.EXTRA_OBSERVER_ID, observerId); 215 intent.putExtra(UsageStatsManager.EXTRA_TIME_USED, timeElapsed); 216 try { 217 callbackIntent.send(getContext(), 0, intent); 218 } catch (PendingIntent.CanceledException e) { 219 Slog.w(TAG, "Couldn't deliver callback: " 220 + callbackIntent); 221 } 222 } 223 }, mHandler.getLooper()); 224 225 mAppStandby.addListener(mStandbyChangeListener); 226 File systemDataDir = new File(Environment.getDataDirectory(), "system"); 227 mUsageStatsDir = new File(systemDataDir, "usagestats"); 228 mUsageStatsDir.mkdirs(); 229 if (!mUsageStatsDir.exists()) { 230 throw new IllegalStateException("Usage stats directory does not exist: " 231 + mUsageStatsDir.getAbsolutePath()); 232 } 233 234 IntentFilter filter = new IntentFilter(Intent.ACTION_USER_REMOVED); 235 filter.addAction(Intent.ACTION_USER_STARTED); 236 getContext().registerReceiverAsUser(new UserActionsReceiver(), UserHandle.ALL, filter, 237 null, mHandler); 238 239 synchronized (mLock) { 240 cleanUpRemovedUsersLocked(); 241 } 242 243 mRealTimeSnapshot = SystemClock.elapsedRealtime(); 244 mSystemTimeSnapshot = System.currentTimeMillis(); 245 246 publishLocalService(UsageStatsManagerInternal.class, new LocalService()); 247 publishBinderService(Context.USAGE_STATS_SERVICE, new BinderService()); 248 // Make sure we initialize the data, in case job scheduler needs it early. 249 getUserDataAndInitializeIfNeededLocked(UserHandle.USER_SYSTEM, mSystemTimeSnapshot); 250 } 251 252 @Override onBootPhase(int phase)253 public void onBootPhase(int phase) { 254 mAppStandby.onBootPhase(phase); 255 if (phase == PHASE_SYSTEM_SERVICES_READY) { 256 // initialize mDpmInternal 257 getDpmInternal(); 258 259 mDeviceIdleController = IDeviceIdleController.Stub.asInterface( 260 ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER)); 261 262 if (ENABLE_KERNEL_UPDATES && KERNEL_COUNTER_FILE.exists()) { 263 try { 264 ActivityManager.getService().registerUidObserver(mUidObserver, 265 ActivityManager.UID_OBSERVER_PROCSTATE 266 | ActivityManager.UID_OBSERVER_GONE, 267 ActivityManager.PROCESS_STATE_UNKNOWN, null); 268 } catch (RemoteException e) { 269 throw new RuntimeException(e); 270 } 271 } else { 272 Slog.w(TAG, "Missing procfs interface: " + KERNEL_COUNTER_FILE); 273 } 274 readUsageSourceSetting(); 275 } 276 } 277 getDpmInternal()278 private DevicePolicyManagerInternal getDpmInternal() { 279 if (mDpmInternal == null) { 280 mDpmInternal = LocalServices.getService(DevicePolicyManagerInternal.class); 281 } 282 return mDpmInternal; 283 } 284 readUsageSourceSetting()285 private void readUsageSourceSetting() { 286 synchronized (mLock) { 287 mUsageSource = Settings.Global.getInt(getContext().getContentResolver(), 288 Settings.Global.APP_TIME_LIMIT_USAGE_SOURCE, USAGE_SOURCE_TASK_ROOT_ACTIVITY); 289 } 290 } 291 292 private class UserActionsReceiver extends BroadcastReceiver { 293 @Override onReceive(Context context, Intent intent)294 public void onReceive(Context context, Intent intent) { 295 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 296 final String action = intent.getAction(); 297 if (Intent.ACTION_USER_REMOVED.equals(action)) { 298 if (userId >= 0) { 299 mHandler.obtainMessage(MSG_REMOVE_USER, userId, 0).sendToTarget(); 300 } 301 } else if (Intent.ACTION_USER_STARTED.equals(action)) { 302 if (userId >= 0) { 303 mAppStandby.postCheckIdleStates(userId); 304 } 305 } 306 } 307 } 308 309 private final IUidObserver mUidObserver = new IUidObserver.Stub() { 310 @Override 311 public void onUidStateChanged(int uid, int procState, long procStateSeq) { 312 mHandler.obtainMessage(MSG_UID_STATE_CHANGED, uid, procState).sendToTarget(); 313 } 314 315 @Override 316 public void onUidIdle(int uid, boolean disabled) { 317 // Ignored 318 } 319 320 @Override 321 public void onUidGone(int uid, boolean disabled) { 322 onUidStateChanged(uid, ActivityManager.PROCESS_STATE_NONEXISTENT, 0); 323 } 324 325 @Override 326 public void onUidActive(int uid) { 327 // Ignored 328 } 329 330 @Override public void onUidCachedChanged(int uid, boolean cached) { 331 } 332 }; 333 334 @Override onStatsUpdated()335 public void onStatsUpdated() { 336 mHandler.sendEmptyMessageDelayed(MSG_FLUSH_TO_DISK, FLUSH_INTERVAL); 337 } 338 339 @Override onStatsReloaded()340 public void onStatsReloaded() { 341 mAppStandby.postOneTimeCheckIdleStates(); 342 } 343 344 @Override onNewUpdate(int userId)345 public void onNewUpdate(int userId) { 346 mAppStandby.initializeDefaultsForSystemApps(userId); 347 } 348 shouldObfuscateInstantAppsForCaller(int callingUid, int userId)349 private boolean shouldObfuscateInstantAppsForCaller(int callingUid, int userId) { 350 return !mPackageManagerInternal.canAccessInstantApps(callingUid, userId); 351 } 352 cleanUpRemovedUsersLocked()353 private void cleanUpRemovedUsersLocked() { 354 final List<UserInfo> users = mUserManager.getUsers(true); 355 if (users == null || users.size() == 0) { 356 throw new IllegalStateException("There can't be no users"); 357 } 358 359 ArraySet<String> toDelete = new ArraySet<>(); 360 String[] fileNames = mUsageStatsDir.list(); 361 if (fileNames == null) { 362 // No users to delete. 363 return; 364 } 365 366 toDelete.addAll(Arrays.asList(fileNames)); 367 368 final int userCount = users.size(); 369 for (int i = 0; i < userCount; i++) { 370 final UserInfo userInfo = users.get(i); 371 toDelete.remove(Integer.toString(userInfo.id)); 372 } 373 374 final int deleteCount = toDelete.size(); 375 for (int i = 0; i < deleteCount; i++) { 376 deleteRecursively(new File(mUsageStatsDir, toDelete.valueAt(i))); 377 } 378 } 379 deleteRecursively(File f)380 private static void deleteRecursively(File f) { 381 File[] files = f.listFiles(); 382 if (files != null) { 383 for (File subFile : files) { 384 deleteRecursively(subFile); 385 } 386 } 387 388 if (!f.delete()) { 389 Slog.e(TAG, "Failed to delete " + f); 390 } 391 } 392 getUserDataAndInitializeIfNeededLocked(int userId, long currentTimeMillis)393 private UserUsageStatsService getUserDataAndInitializeIfNeededLocked(int userId, 394 long currentTimeMillis) { 395 UserUsageStatsService service = mUserState.get(userId); 396 if (service == null) { 397 service = new UserUsageStatsService(getContext(), userId, 398 new File(mUsageStatsDir, Integer.toString(userId)), this); 399 service.init(currentTimeMillis); 400 mUserState.put(userId, service); 401 } 402 return service; 403 } 404 405 /** 406 * This should be the only way to get the time from the system. 407 */ checkAndGetTimeLocked()408 private long checkAndGetTimeLocked() { 409 final long actualSystemTime = System.currentTimeMillis(); 410 final long actualRealtime = SystemClock.elapsedRealtime(); 411 final long expectedSystemTime = (actualRealtime - mRealTimeSnapshot) + mSystemTimeSnapshot; 412 final long diffSystemTime = actualSystemTime - expectedSystemTime; 413 if (Math.abs(diffSystemTime) > TIME_CHANGE_THRESHOLD_MILLIS 414 && ENABLE_TIME_CHANGE_CORRECTION) { 415 // The time has changed. 416 Slog.i(TAG, "Time changed in UsageStats by " + (diffSystemTime / 1000) + " seconds"); 417 final int userCount = mUserState.size(); 418 for (int i = 0; i < userCount; i++) { 419 final UserUsageStatsService service = mUserState.valueAt(i); 420 service.onTimeChanged(expectedSystemTime, actualSystemTime); 421 } 422 mRealTimeSnapshot = actualRealtime; 423 mSystemTimeSnapshot = actualSystemTime; 424 } 425 return actualSystemTime; 426 } 427 428 /** 429 * Assuming the event's timestamp is measured in milliseconds since boot, 430 * convert it to a system wall time. 431 */ convertToSystemTimeLocked(Event event)432 private void convertToSystemTimeLocked(Event event) { 433 event.mTimeStamp = Math.max(0, event.mTimeStamp - mRealTimeSnapshot) + mSystemTimeSnapshot; 434 } 435 436 /** 437 * Called by the Binder stub 438 */ shutdown()439 void shutdown() { 440 synchronized (mLock) { 441 mHandler.removeMessages(MSG_REPORT_EVENT); 442 Event event = new Event(DEVICE_SHUTDOWN, SystemClock.elapsedRealtime()); 443 event.mPackage = Event.DEVICE_EVENT_PACKAGE_NAME; 444 // orderly shutdown, the last event is DEVICE_SHUTDOWN. 445 reportEventToAllUserId(event); 446 flushToDiskLocked(); 447 } 448 } 449 450 /** 451 * After power button is pressed for 3.5 seconds 452 * (as defined in {@link com.android.internal.R.integer#config_veryLongPressTimeout}), 453 * report DEVICE_SHUTDOWN event and persist the database. If the power button is pressed for 10 454 * seconds and the device is shutdown, the database is already persisted and we are not losing 455 * data. 456 * This method is called from PhoneWindowManager, do not synchronize on mLock otherwise 457 * PhoneWindowManager may be blocked. 458 */ prepareForPossibleShutdown()459 void prepareForPossibleShutdown() { 460 Event event = new Event(DEVICE_SHUTDOWN, SystemClock.elapsedRealtime()); 461 event.mPackage = Event.DEVICE_EVENT_PACKAGE_NAME; 462 mHandler.obtainMessage(MSG_REPORT_EVENT_TO_ALL_USERID, event).sendToTarget(); 463 mHandler.sendEmptyMessage(MSG_FLUSH_TO_DISK); 464 } 465 466 /** 467 * Called by the Binder stub. 468 */ reportEvent(Event event, int userId)469 void reportEvent(Event event, int userId) { 470 synchronized (mLock) { 471 final long timeNow = checkAndGetTimeLocked(); 472 final long elapsedRealtime = SystemClock.elapsedRealtime(); 473 convertToSystemTimeLocked(event); 474 475 if (event.mPackage != null 476 && mPackageManagerInternal.isPackageEphemeral(userId, event.mPackage)) { 477 event.mFlags |= Event.FLAG_IS_PACKAGE_INSTANT_APP; 478 } 479 480 switch (event.mEventType) { 481 case Event.ACTIVITY_RESUMED: 482 // check if this activity has already been resumed 483 if (mVisibleActivities.get(event.mInstanceId) != null) break; 484 mVisibleActivities.put(event.mInstanceId, 485 new ActivityData(event.mTaskRootPackage, event.mTaskRootClass)); 486 try { 487 switch(mUsageSource) { 488 case USAGE_SOURCE_CURRENT_ACTIVITY: 489 mAppTimeLimit.noteUsageStart(event.mPackage, userId); 490 break; 491 case USAGE_SOURCE_TASK_ROOT_ACTIVITY: 492 default: 493 mAppTimeLimit.noteUsageStart(event.mTaskRootPackage, userId); 494 break; 495 } 496 } catch (IllegalArgumentException iae) { 497 Slog.e(TAG, "Failed to note usage start", iae); 498 } 499 break; 500 case Event.ACTIVITY_PAUSED: 501 if (event.mTaskRootPackage == null) { 502 // Task Root info is missing. Repair the event based on previous data 503 final ActivityData prevData = mVisibleActivities.get(event.mInstanceId); 504 if (prevData == null) { 505 Slog.w(TAG, "Unexpected activity event reported! (" + event.mPackage 506 + "/" + event.mClass + " event : " + event.mEventType 507 + " instanceId : " + event.mInstanceId + ")"); 508 } else { 509 event.mTaskRootPackage = prevData.mTaskRootPackage; 510 event.mTaskRootClass = prevData.mTaskRootClass; 511 } 512 } 513 break; 514 case Event.ACTIVITY_DESTROYED: 515 // Treat activity destroys like activity stops. 516 event.mEventType = Event.ACTIVITY_STOPPED; 517 // Fallthrough 518 case Event.ACTIVITY_STOPPED: 519 final ActivityData prevData = 520 mVisibleActivities.removeReturnOld(event.mInstanceId); 521 if (prevData == null) { 522 // The activity stop was already handled. 523 return; 524 } 525 526 ArraySet<String> tokens; 527 synchronized (mUsageReporters) { 528 tokens = mUsageReporters.removeReturnOld(event.mInstanceId); 529 } 530 if (tokens != null) { 531 synchronized (tokens) { 532 final int size = tokens.size(); 533 // Stop usage on behalf of a UsageReporter that stopped 534 for (int i = 0; i < size; i++) { 535 final String token = tokens.valueAt(i); 536 try { 537 mAppTimeLimit.noteUsageStop( 538 buildFullToken(event.mPackage, token), userId); 539 } catch (IllegalArgumentException iae) { 540 Slog.w(TAG, "Failed to stop usage for during reporter death: " 541 + iae); 542 } 543 } 544 } 545 } 546 if (event.mTaskRootPackage == null) { 547 // Task Root info is missing. Repair the event based on previous data 548 event.mTaskRootPackage = prevData.mTaskRootPackage; 549 event.mTaskRootClass = prevData.mTaskRootClass; 550 } 551 try { 552 switch(mUsageSource) { 553 case USAGE_SOURCE_CURRENT_ACTIVITY: 554 mAppTimeLimit.noteUsageStop(event.mPackage, userId); 555 break; 556 case USAGE_SOURCE_TASK_ROOT_ACTIVITY: 557 default: 558 mAppTimeLimit.noteUsageStop(event.mTaskRootPackage, userId); 559 break; 560 } 561 } catch (IllegalArgumentException iae) { 562 Slog.w(TAG, "Failed to note usage stop", iae); 563 } 564 break; 565 } 566 567 final UserUsageStatsService service = 568 getUserDataAndInitializeIfNeededLocked(userId, timeNow); 569 service.reportEvent(event); 570 571 mAppStandby.reportEvent(event, elapsedRealtime, userId); 572 } 573 } 574 575 /** 576 * Some events like FLUSH_TO_DISK need to be sent to all userId. 577 * @param event 578 */ reportEventToAllUserId(Event event)579 void reportEventToAllUserId(Event event) { 580 synchronized (mLock) { 581 final int userCount = mUserState.size(); 582 for (int i = 0; i < userCount; i++) { 583 Event copy = new Event(event); 584 reportEvent(copy, mUserState.keyAt(i)); 585 } 586 } 587 } 588 589 /** 590 * Called by the Handler for message MSG_FLUSH_TO_DISK. 591 */ flushToDisk()592 void flushToDisk() { 593 synchronized (mLock) { 594 // Before flush to disk, report FLUSH_TO_DISK event to signal UsageStats to update app 595 // usage. In case of abrupt power shutdown like battery drain or cold temperature, 596 // all UsageStats has correct data up to last flush to disk. 597 // The FLUSH_TO_DISK event is an internal event, it will not show up in IntervalStats' 598 // EventList. 599 Event event = new Event(FLUSH_TO_DISK, SystemClock.elapsedRealtime()); 600 reportEventToAllUserId(event); 601 flushToDiskLocked(); 602 } 603 } 604 605 /** 606 * Called by the Binder stub. 607 */ onUserRemoved(int userId)608 void onUserRemoved(int userId) { 609 synchronized (mLock) { 610 Slog.i(TAG, "Removing user " + userId + " and all data."); 611 mUserState.remove(userId); 612 mAppStandby.onUserRemoved(userId); 613 mAppTimeLimit.onUserRemoved(userId); 614 cleanUpRemovedUsersLocked(); 615 } 616 } 617 618 /** 619 * Called by the Binder stub. 620 */ queryUsageStats(int userId, int bucketType, long beginTime, long endTime, boolean obfuscateInstantApps)621 List<UsageStats> queryUsageStats(int userId, int bucketType, long beginTime, long endTime, 622 boolean obfuscateInstantApps) { 623 synchronized (mLock) { 624 final long timeNow = checkAndGetTimeLocked(); 625 if (!validRange(timeNow, beginTime, endTime)) { 626 return null; 627 } 628 629 final UserUsageStatsService service = 630 getUserDataAndInitializeIfNeededLocked(userId, timeNow); 631 List<UsageStats> list = service.queryUsageStats(bucketType, beginTime, endTime); 632 if (list == null) { 633 return null; 634 } 635 636 // Mangle instant app names *using their current state (not whether they were ephemeral 637 // when the data was recorded)*. 638 if (obfuscateInstantApps) { 639 for (int i = list.size() - 1; i >= 0; i--) { 640 final UsageStats stats = list.get(i); 641 if (mPackageManagerInternal.isPackageEphemeral(userId, stats.mPackageName)) { 642 list.set(i, stats.getObfuscatedForInstantApp()); 643 } 644 } 645 } 646 647 return list; 648 } 649 } 650 651 /** 652 * Called by the Binder stub. 653 */ queryConfigurationStats(int userId, int bucketType, long beginTime, long endTime)654 List<ConfigurationStats> queryConfigurationStats(int userId, int bucketType, long beginTime, 655 long endTime) { 656 synchronized (mLock) { 657 final long timeNow = checkAndGetTimeLocked(); 658 if (!validRange(timeNow, beginTime, endTime)) { 659 return null; 660 } 661 662 final UserUsageStatsService service = 663 getUserDataAndInitializeIfNeededLocked(userId, timeNow); 664 return service.queryConfigurationStats(bucketType, beginTime, endTime); 665 } 666 } 667 668 /** 669 * Called by the Binder stub. 670 */ queryEventStats(int userId, int bucketType, long beginTime, long endTime)671 List<EventStats> queryEventStats(int userId, int bucketType, long beginTime, 672 long endTime) { 673 synchronized (mLock) { 674 final long timeNow = checkAndGetTimeLocked(); 675 if (!validRange(timeNow, beginTime, endTime)) { 676 return null; 677 } 678 679 final UserUsageStatsService service = 680 getUserDataAndInitializeIfNeededLocked(userId, timeNow); 681 return service.queryEventStats(bucketType, beginTime, endTime); 682 } 683 } 684 685 /** 686 * Called by the Binder stub. 687 */ queryEvents(int userId, long beginTime, long endTime, boolean shouldObfuscateInstantApps)688 UsageEvents queryEvents(int userId, long beginTime, long endTime, 689 boolean shouldObfuscateInstantApps) { 690 synchronized (mLock) { 691 final long timeNow = checkAndGetTimeLocked(); 692 if (!validRange(timeNow, beginTime, endTime)) { 693 return null; 694 } 695 696 final UserUsageStatsService service = 697 getUserDataAndInitializeIfNeededLocked(userId, timeNow); 698 return service.queryEvents(beginTime, endTime, shouldObfuscateInstantApps); 699 } 700 } 701 702 /** 703 * Called by the Binder stub. 704 */ queryEventsForPackage(int userId, long beginTime, long endTime, String packageName, boolean includeTaskRoot)705 UsageEvents queryEventsForPackage(int userId, long beginTime, long endTime, 706 String packageName, boolean includeTaskRoot) { 707 synchronized (mLock) { 708 final long timeNow = checkAndGetTimeLocked(); 709 if (!validRange(timeNow, beginTime, endTime)) { 710 return null; 711 } 712 713 final UserUsageStatsService service = 714 getUserDataAndInitializeIfNeededLocked(userId, timeNow); 715 return service.queryEventsForPackage(beginTime, endTime, packageName, includeTaskRoot); 716 } 717 } 718 validRange(long currentTime, long beginTime, long endTime)719 private static boolean validRange(long currentTime, long beginTime, long endTime) { 720 return beginTime <= currentTime && beginTime < endTime; 721 } 722 buildFullToken(String packageName, String token)723 private String buildFullToken(String packageName, String token) { 724 final StringBuilder sb = new StringBuilder(packageName.length() + token.length() + 1); 725 sb.append(packageName); 726 sb.append(TOKEN_DELIMITER); 727 sb.append(token); 728 return sb.toString(); 729 } 730 flushToDiskLocked()731 private void flushToDiskLocked() { 732 final int userCount = mUserState.size(); 733 for (int i = 0; i < userCount; i++) { 734 UserUsageStatsService service = mUserState.valueAt(i); 735 service.persistActiveStats(); 736 mAppStandby.flushToDisk(mUserState.keyAt(i)); 737 } 738 mAppStandby.flushDurationsToDisk(); 739 740 mHandler.removeMessages(MSG_FLUSH_TO_DISK); 741 } 742 743 /** 744 * Called by the Binder stub. 745 */ dump(String[] args, PrintWriter pw)746 void dump(String[] args, PrintWriter pw) { 747 synchronized (mLock) { 748 IndentingPrintWriter idpw = new IndentingPrintWriter(pw, " "); 749 750 boolean checkin = false; 751 boolean compact = false; 752 String pkg = null; 753 754 if (args != null) { 755 for (int i = 0; i < args.length; i++) { 756 String arg = args[i]; 757 if ("--checkin".equals(arg)) { 758 checkin = true; 759 } else if ("-c".equals(arg)) { 760 compact = true; 761 } else if ("flush".equals(arg)) { 762 flushToDiskLocked(); 763 pw.println("Flushed stats to disk"); 764 return; 765 } else if ("is-app-standby-enabled".equals(arg)) { 766 pw.println(mAppStandby.mAppIdleEnabled); 767 return; 768 } else if ("apptimelimit".equals(arg)) { 769 if (i + 1 >= args.length) { 770 mAppTimeLimit.dump(null, pw); 771 } else { 772 final String[] remainingArgs = 773 Arrays.copyOfRange(args, i + 1, args.length); 774 mAppTimeLimit.dump(remainingArgs, pw); 775 } 776 return; 777 } else if ("file".equals(arg)) { 778 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); 779 if (i + 1 >= args.length) { 780 // dump everything for all users 781 final int numUsers = mUserState.size(); 782 for (int user = 0; user < numUsers; user++) { 783 ipw.println("user=" + mUserState.keyAt(user)); 784 ipw.increaseIndent(); 785 mUserState.valueAt(user).dumpFile(ipw, null); 786 ipw.decreaseIndent(); 787 } 788 } else { 789 final int user; 790 try { 791 user = Integer.valueOf(args[i + 1]); 792 } catch (NumberFormatException nfe) { 793 ipw.println("invalid user specified."); 794 return; 795 } 796 if (mUserState.indexOfKey(user) < 0) { 797 ipw.println("the specified user does not exist."); 798 return; 799 } 800 final String[] remainingArgs = Arrays.copyOfRange( 801 args, i + 2, args.length); 802 // dump everything for the specified user 803 mUserState.get(user).dumpFile(ipw, remainingArgs); 804 } 805 return; 806 } else if ("database-info".equals(arg)) { 807 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); 808 if (i + 1 >= args.length) { 809 // dump info for all users 810 final int numUsers = mUserState.size(); 811 for (int user = 0; user < numUsers; user++) { 812 ipw.println("user=" + mUserState.keyAt(user)); 813 ipw.increaseIndent(); 814 mUserState.valueAt(user).dumpDatabaseInfo(ipw); 815 ipw.decreaseIndent(); 816 } 817 } else { 818 final int user; 819 try { 820 user = Integer.valueOf(args[i + 1]); 821 } catch (NumberFormatException nfe) { 822 ipw.println("invalid user specified."); 823 return; 824 } 825 if (mUserState.indexOfKey(user) < 0) { 826 ipw.println("the specified user does not exist."); 827 return; 828 } 829 // dump info only for the specified user 830 mUserState.get(user).dumpDatabaseInfo(ipw); 831 } 832 return; 833 } else if (arg != null && !arg.startsWith("-")) { 834 // Anything else that doesn't start with '-' is a pkg to filter 835 pkg = arg; 836 break; 837 } 838 } 839 } 840 841 final int userCount = mUserState.size(); 842 for (int i = 0; i < userCount; i++) { 843 int userId = mUserState.keyAt(i); 844 idpw.printPair("user", userId); 845 idpw.println(); 846 idpw.increaseIndent(); 847 if (checkin) { 848 mUserState.valueAt(i).checkin(idpw); 849 } else { 850 mUserState.valueAt(i).dump(idpw, pkg, compact); 851 idpw.println(); 852 } 853 mAppStandby.dumpUser(idpw, userId, pkg); 854 idpw.decreaseIndent(); 855 } 856 857 if (pkg == null) { 858 pw.println(); 859 mAppStandby.dumpState(args, pw); 860 } 861 862 idpw.println(); 863 idpw.printPair("Usage Source", UsageStatsManager.usageSourceToString(mUsageSource)); 864 idpw.println(); 865 866 mAppTimeLimit.dump(null, pw); 867 } 868 } 869 870 class H extends Handler { H(Looper looper)871 public H(Looper looper) { 872 super(looper); 873 } 874 875 @Override handleMessage(Message msg)876 public void handleMessage(Message msg) { 877 switch (msg.what) { 878 case MSG_REPORT_EVENT: 879 reportEvent((Event) msg.obj, msg.arg1); 880 break; 881 case MSG_REPORT_EVENT_TO_ALL_USERID: 882 reportEventToAllUserId((Event) msg.obj); 883 break; 884 case MSG_FLUSH_TO_DISK: 885 flushToDisk(); 886 break; 887 888 case MSG_REMOVE_USER: 889 onUserRemoved(msg.arg1); 890 break; 891 892 case MSG_UID_STATE_CHANGED: { 893 final int uid = msg.arg1; 894 final int procState = msg.arg2; 895 896 final int newCounter = (procState <= ActivityManager.PROCESS_STATE_TOP) ? 0 : 1; 897 synchronized (mUidToKernelCounter) { 898 final int oldCounter = mUidToKernelCounter.get(uid, 0); 899 if (newCounter != oldCounter) { 900 mUidToKernelCounter.put(uid, newCounter); 901 try { 902 FileUtils.stringToFile(KERNEL_COUNTER_FILE, uid + " " + newCounter); 903 } catch (IOException e) { 904 Slog.w(TAG, "Failed to update counter set: " + e); 905 } 906 } 907 } 908 break; 909 } 910 911 default: 912 super.handleMessage(msg); 913 break; 914 } 915 } 916 } 917 918 private final class BinderService extends IUsageStatsManager.Stub { 919 hasPermission(String callingPackage)920 private boolean hasPermission(String callingPackage) { 921 final int callingUid = Binder.getCallingUid(); 922 if (callingUid == Process.SYSTEM_UID) { 923 return true; 924 } 925 final int mode = mAppOps.noteOp(AppOpsManager.OP_GET_USAGE_STATS, 926 callingUid, callingPackage); 927 if (mode == AppOpsManager.MODE_DEFAULT) { 928 // The default behavior here is to check if PackageManager has given the app 929 // permission. 930 return getContext().checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS) 931 == PackageManager.PERMISSION_GRANTED; 932 } 933 return mode == AppOpsManager.MODE_ALLOWED; 934 } 935 hasObserverPermission()936 private boolean hasObserverPermission() { 937 final int callingUid = Binder.getCallingUid(); 938 DevicePolicyManagerInternal dpmInternal = getDpmInternal(); 939 if (callingUid == Process.SYSTEM_UID 940 || (dpmInternal != null 941 && dpmInternal.isActiveAdminWithPolicy(callingUid, 942 DeviceAdminInfo.USES_POLICY_PROFILE_OWNER))) { 943 // Caller is the system or the profile owner, so proceed. 944 return true; 945 } 946 return getContext().checkCallingPermission(Manifest.permission.OBSERVE_APP_USAGE) 947 == PackageManager.PERMISSION_GRANTED; 948 } 949 hasPermissions(String callingPackage, String... permissions)950 private boolean hasPermissions(String callingPackage, String... permissions) { 951 final int callingUid = Binder.getCallingUid(); 952 if (callingUid == Process.SYSTEM_UID) { 953 // Caller is the system, so proceed. 954 return true; 955 } 956 957 boolean hasPermissions = true; 958 final Context context = getContext(); 959 for (int i = 0; i < permissions.length; i++) { 960 hasPermissions = hasPermissions && (context.checkCallingPermission(permissions[i]) 961 == PackageManager.PERMISSION_GRANTED); 962 } 963 return hasPermissions; 964 } 965 checkCallerIsSystemOrSameApp(String pkg)966 private void checkCallerIsSystemOrSameApp(String pkg) { 967 if (isCallingUidSystem()) { 968 return; 969 } 970 checkCallerIsSameApp(pkg); 971 } 972 checkCallerIsSameApp(String pkg)973 private void checkCallerIsSameApp(String pkg) { 974 final int callingUid = Binder.getCallingUid(); 975 final int callingUserId = UserHandle.getUserId(callingUid); 976 977 if (mPackageManagerInternal.getPackageUid(pkg, /*flags=*/ 0, 978 callingUserId) != callingUid) { 979 throw new SecurityException("Calling uid " + callingUid + " cannot query events" 980 + "for package " + pkg); 981 } 982 } 983 isCallingUidSystem()984 private boolean isCallingUidSystem() { 985 final int uid = UserHandle.getAppId(Binder.getCallingUid()); // ignores user 986 return uid == Process.SYSTEM_UID; 987 } 988 989 @Override queryUsageStats(int bucketType, long beginTime, long endTime, String callingPackage)990 public ParceledListSlice<UsageStats> queryUsageStats(int bucketType, long beginTime, 991 long endTime, String callingPackage) { 992 if (!hasPermission(callingPackage)) { 993 return null; 994 } 995 996 final boolean obfuscateInstantApps = shouldObfuscateInstantAppsForCaller( 997 Binder.getCallingUid(), UserHandle.getCallingUserId()); 998 999 final int userId = UserHandle.getCallingUserId(); 1000 final long token = Binder.clearCallingIdentity(); 1001 try { 1002 final List<UsageStats> results = UsageStatsService.this.queryUsageStats( 1003 userId, bucketType, beginTime, endTime, obfuscateInstantApps); 1004 if (results != null) { 1005 return new ParceledListSlice<>(results); 1006 } 1007 } finally { 1008 Binder.restoreCallingIdentity(token); 1009 } 1010 return null; 1011 } 1012 1013 @Override queryConfigurationStats(int bucketType, long beginTime, long endTime, String callingPackage)1014 public ParceledListSlice<ConfigurationStats> queryConfigurationStats(int bucketType, 1015 long beginTime, long endTime, String callingPackage) throws RemoteException { 1016 if (!hasPermission(callingPackage)) { 1017 return null; 1018 } 1019 1020 final int userId = UserHandle.getCallingUserId(); 1021 final long token = Binder.clearCallingIdentity(); 1022 try { 1023 final List<ConfigurationStats> results = 1024 UsageStatsService.this.queryConfigurationStats(userId, bucketType, 1025 beginTime, endTime); 1026 if (results != null) { 1027 return new ParceledListSlice<>(results); 1028 } 1029 } finally { 1030 Binder.restoreCallingIdentity(token); 1031 } 1032 return null; 1033 } 1034 1035 @Override queryEventStats(int bucketType, long beginTime, long endTime, String callingPackage)1036 public ParceledListSlice<EventStats> queryEventStats(int bucketType, 1037 long beginTime, long endTime, String callingPackage) throws RemoteException { 1038 if (!hasPermission(callingPackage)) { 1039 return null; 1040 } 1041 1042 final int userId = UserHandle.getCallingUserId(); 1043 final long token = Binder.clearCallingIdentity(); 1044 try { 1045 final List<EventStats> results = 1046 UsageStatsService.this.queryEventStats(userId, bucketType, 1047 beginTime, endTime); 1048 if (results != null) { 1049 return new ParceledListSlice<>(results); 1050 } 1051 } finally { 1052 Binder.restoreCallingIdentity(token); 1053 } 1054 return null; 1055 } 1056 1057 @Override queryEvents(long beginTime, long endTime, String callingPackage)1058 public UsageEvents queryEvents(long beginTime, long endTime, String callingPackage) { 1059 if (!hasPermission(callingPackage)) { 1060 return null; 1061 } 1062 1063 final boolean obfuscateInstantApps = shouldObfuscateInstantAppsForCaller( 1064 Binder.getCallingUid(), UserHandle.getCallingUserId()); 1065 1066 final int userId = UserHandle.getCallingUserId(); 1067 final long token = Binder.clearCallingIdentity(); 1068 try { 1069 return UsageStatsService.this.queryEvents(userId, beginTime, endTime, 1070 obfuscateInstantApps); 1071 } finally { 1072 Binder.restoreCallingIdentity(token); 1073 } 1074 } 1075 1076 @Override queryEventsForPackage(long beginTime, long endTime, String callingPackage)1077 public UsageEvents queryEventsForPackage(long beginTime, long endTime, 1078 String callingPackage) { 1079 final int callingUid = Binder.getCallingUid(); 1080 final int callingUserId = UserHandle.getUserId(callingUid); 1081 1082 checkCallerIsSameApp(callingPackage); 1083 final boolean includeTaskRoot = hasPermission(callingPackage); 1084 1085 final long token = Binder.clearCallingIdentity(); 1086 try { 1087 return UsageStatsService.this.queryEventsForPackage(callingUserId, beginTime, 1088 endTime, callingPackage, includeTaskRoot); 1089 } finally { 1090 Binder.restoreCallingIdentity(token); 1091 } 1092 } 1093 1094 @Override queryEventsForUser(long beginTime, long endTime, int userId, String callingPackage)1095 public UsageEvents queryEventsForUser(long beginTime, long endTime, int userId, 1096 String callingPackage) { 1097 if (!hasPermission(callingPackage)) { 1098 return null; 1099 } 1100 1101 if (userId != UserHandle.getCallingUserId()) { 1102 getContext().enforceCallingPermission( 1103 Manifest.permission.INTERACT_ACROSS_USERS_FULL, 1104 "No permission to query usage stats for this user"); 1105 } 1106 1107 final boolean obfuscateInstantApps = shouldObfuscateInstantAppsForCaller( 1108 Binder.getCallingUid(), UserHandle.getCallingUserId()); 1109 1110 final long token = Binder.clearCallingIdentity(); 1111 try { 1112 return UsageStatsService.this.queryEvents(userId, beginTime, endTime, 1113 obfuscateInstantApps); 1114 } finally { 1115 Binder.restoreCallingIdentity(token); 1116 } 1117 } 1118 1119 @Override queryEventsForPackageForUser(long beginTime, long endTime, int userId, String pkg, String callingPackage)1120 public UsageEvents queryEventsForPackageForUser(long beginTime, long endTime, 1121 int userId, String pkg, String callingPackage) { 1122 if (!hasPermission(callingPackage)) { 1123 return null; 1124 } 1125 if (userId != UserHandle.getCallingUserId()) { 1126 getContext().enforceCallingPermission( 1127 Manifest.permission.INTERACT_ACROSS_USERS_FULL, 1128 "No permission to query usage stats for this user"); 1129 } 1130 checkCallerIsSystemOrSameApp(pkg); 1131 1132 final long token = Binder.clearCallingIdentity(); 1133 try { 1134 return UsageStatsService.this.queryEventsForPackage(userId, beginTime, 1135 endTime, pkg, true); 1136 } finally { 1137 Binder.restoreCallingIdentity(token); 1138 } 1139 } 1140 1141 @Override isAppInactive(String packageName, int userId)1142 public boolean isAppInactive(String packageName, int userId) { 1143 try { 1144 userId = ActivityManager.getService().handleIncomingUser(Binder.getCallingPid(), 1145 Binder.getCallingUid(), userId, false, false, "isAppInactive", null); 1146 } catch (RemoteException re) { 1147 throw re.rethrowFromSystemServer(); 1148 } 1149 final boolean obfuscateInstantApps = shouldObfuscateInstantAppsForCaller( 1150 Binder.getCallingUid(), userId); 1151 final long token = Binder.clearCallingIdentity(); 1152 try { 1153 return mAppStandby.isAppIdleFilteredOrParoled( 1154 packageName, userId, 1155 SystemClock.elapsedRealtime(), obfuscateInstantApps); 1156 } finally { 1157 Binder.restoreCallingIdentity(token); 1158 } 1159 } 1160 1161 @Override setAppInactive(String packageName, boolean idle, int userId)1162 public void setAppInactive(String packageName, boolean idle, int userId) { 1163 final int callingUid = Binder.getCallingUid(); 1164 try { 1165 userId = ActivityManager.getService().handleIncomingUser( 1166 Binder.getCallingPid(), callingUid, userId, false, true, 1167 "setAppInactive", null); 1168 } catch (RemoteException re) { 1169 throw re.rethrowFromSystemServer(); 1170 } 1171 getContext().enforceCallingPermission(Manifest.permission.CHANGE_APP_IDLE_STATE, 1172 "No permission to change app idle state"); 1173 final long token = Binder.clearCallingIdentity(); 1174 try { 1175 final int appId = mAppStandby.getAppId(packageName); 1176 if (appId < 0) return; 1177 mAppStandby.setAppIdleAsync(packageName, idle, userId); 1178 } finally { 1179 Binder.restoreCallingIdentity(token); 1180 } 1181 } 1182 1183 @Override getAppStandbyBucket(String packageName, String callingPackage, int userId)1184 public int getAppStandbyBucket(String packageName, String callingPackage, int userId) { 1185 final int callingUid = Binder.getCallingUid(); 1186 try { 1187 userId = ActivityManager.getService().handleIncomingUser( 1188 Binder.getCallingPid(), callingUid, userId, false, false, 1189 "getAppStandbyBucket", null); 1190 } catch (RemoteException re) { 1191 throw re.rethrowFromSystemServer(); 1192 } 1193 final int packageUid = mPackageManagerInternal.getPackageUid(packageName, 0, userId); 1194 // If the calling app is asking about itself, continue, else check for permission. 1195 if (packageUid != callingUid) { 1196 if (!hasPermission(callingPackage)) { 1197 throw new SecurityException( 1198 "Don't have permission to query app standby bucket"); 1199 } 1200 } 1201 if (packageUid < 0) { 1202 throw new IllegalArgumentException( 1203 "Cannot get standby bucket for non existent package (" + packageName + ")"); 1204 } 1205 final boolean obfuscateInstantApps = shouldObfuscateInstantAppsForCaller(callingUid, 1206 userId); 1207 final long token = Binder.clearCallingIdentity(); 1208 try { 1209 return mAppStandby.getAppStandbyBucket(packageName, userId, 1210 SystemClock.elapsedRealtime(), obfuscateInstantApps); 1211 } finally { 1212 Binder.restoreCallingIdentity(token); 1213 } 1214 } 1215 1216 @Override setAppStandbyBucket(String packageName, int bucket, int userId)1217 public void setAppStandbyBucket(String packageName, 1218 int bucket, int userId) { 1219 getContext().enforceCallingPermission(Manifest.permission.CHANGE_APP_IDLE_STATE, 1220 "No permission to change app standby state"); 1221 1222 if (bucket < UsageStatsManager.STANDBY_BUCKET_ACTIVE 1223 || bucket > UsageStatsManager.STANDBY_BUCKET_NEVER) { 1224 throw new IllegalArgumentException("Cannot set the standby bucket to " + bucket); 1225 } 1226 final int callingUid = Binder.getCallingUid(); 1227 try { 1228 userId = ActivityManager.getService().handleIncomingUser( 1229 Binder.getCallingPid(), callingUid, userId, false, true, 1230 "setAppStandbyBucket", null); 1231 } catch (RemoteException re) { 1232 throw re.rethrowFromSystemServer(); 1233 } 1234 final boolean shellCaller = callingUid == 0 || callingUid == Process.SHELL_UID; 1235 final boolean systemCaller = UserHandle.isCore(callingUid); 1236 final int reason = systemCaller 1237 ? UsageStatsManager.REASON_MAIN_FORCED 1238 : UsageStatsManager.REASON_MAIN_PREDICTED; 1239 final long token = Binder.clearCallingIdentity(); 1240 try { 1241 final int packageUid = mPackageManagerInternal.getPackageUid(packageName, 1242 PackageManager.MATCH_ANY_USER | PackageManager.MATCH_DIRECT_BOOT_UNAWARE 1243 | PackageManager.MATCH_DIRECT_BOOT_AWARE, userId); 1244 // Caller cannot set their own standby state 1245 if (packageUid == callingUid) { 1246 throw new IllegalArgumentException("Cannot set your own standby bucket"); 1247 } 1248 if (packageUid < 0) { 1249 throw new IllegalArgumentException( 1250 "Cannot set standby bucket for non existent package (" + packageName 1251 + ")"); 1252 } 1253 mAppStandby.setAppStandbyBucket(packageName, userId, bucket, reason, 1254 SystemClock.elapsedRealtime(), shellCaller); 1255 } finally { 1256 Binder.restoreCallingIdentity(token); 1257 } 1258 } 1259 1260 @Override getAppStandbyBuckets(String callingPackageName, int userId)1261 public ParceledListSlice<AppStandbyInfo> getAppStandbyBuckets(String callingPackageName, 1262 int userId) { 1263 final int callingUid = Binder.getCallingUid(); 1264 try { 1265 userId = ActivityManager.getService().handleIncomingUser( 1266 Binder.getCallingPid(), callingUid, userId, false, false, 1267 "getAppStandbyBucket", null); 1268 } catch (RemoteException re) { 1269 throw re.rethrowFromSystemServer(); 1270 } 1271 if (!hasPermission(callingPackageName)) { 1272 throw new SecurityException( 1273 "Don't have permission to query app standby bucket"); 1274 } 1275 final long token = Binder.clearCallingIdentity(); 1276 try { 1277 final List<AppStandbyInfo> standbyBucketList = 1278 mAppStandby.getAppStandbyBuckets(userId); 1279 return (standbyBucketList == null) ? ParceledListSlice.emptyList() 1280 : new ParceledListSlice<>(standbyBucketList); 1281 } finally { 1282 Binder.restoreCallingIdentity(token); 1283 } 1284 } 1285 1286 @Override setAppStandbyBuckets(ParceledListSlice appBuckets, int userId)1287 public void setAppStandbyBuckets(ParceledListSlice appBuckets, int userId) { 1288 getContext().enforceCallingPermission(Manifest.permission.CHANGE_APP_IDLE_STATE, 1289 "No permission to change app standby state"); 1290 1291 final int callingUid = Binder.getCallingUid(); 1292 try { 1293 userId = ActivityManager.getService().handleIncomingUser( 1294 Binder.getCallingPid(), callingUid, userId, false, true, 1295 "setAppStandbyBucket", null); 1296 } catch (RemoteException re) { 1297 throw re.rethrowFromSystemServer(); 1298 } 1299 final boolean shellCaller = callingUid == 0 || callingUid == Process.SHELL_UID; 1300 final int reason = shellCaller 1301 ? UsageStatsManager.REASON_MAIN_FORCED 1302 : UsageStatsManager.REASON_MAIN_PREDICTED; 1303 final long token = Binder.clearCallingIdentity(); 1304 try { 1305 final long elapsedRealtime = SystemClock.elapsedRealtime(); 1306 List<AppStandbyInfo> bucketList = appBuckets.getList(); 1307 for (AppStandbyInfo bucketInfo : bucketList) { 1308 final String packageName = bucketInfo.mPackageName; 1309 final int bucket = bucketInfo.mStandbyBucket; 1310 if (bucket < UsageStatsManager.STANDBY_BUCKET_ACTIVE 1311 || bucket > UsageStatsManager.STANDBY_BUCKET_NEVER) { 1312 throw new IllegalArgumentException( 1313 "Cannot set the standby bucket to " + bucket); 1314 } 1315 // Caller cannot set their own standby state 1316 if (mPackageManagerInternal.getPackageUid(packageName, 1317 PackageManager.MATCH_ANY_USER, userId) == callingUid) { 1318 throw new IllegalArgumentException("Cannot set your own standby bucket"); 1319 } 1320 mAppStandby.setAppStandbyBucket(packageName, userId, bucket, reason, 1321 elapsedRealtime, shellCaller); 1322 } 1323 } finally { 1324 Binder.restoreCallingIdentity(token); 1325 } 1326 } 1327 1328 @Override whitelistAppTemporarily(String packageName, long duration, int userId)1329 public void whitelistAppTemporarily(String packageName, long duration, int userId) 1330 throws RemoteException { 1331 StringBuilder reason = new StringBuilder(32); 1332 reason.append("from:"); 1333 UserHandle.formatUid(reason, Binder.getCallingUid()); 1334 mDeviceIdleController.addPowerSaveTempWhitelistApp(packageName, duration, userId, 1335 reason.toString()); 1336 } 1337 1338 @Override onCarrierPrivilegedAppsChanged()1339 public void onCarrierPrivilegedAppsChanged() { 1340 if (DEBUG) { 1341 Slog.i(TAG, "Carrier privileged apps changed"); 1342 } 1343 getContext().enforceCallingOrSelfPermission( 1344 android.Manifest.permission.BIND_CARRIER_SERVICES, 1345 "onCarrierPrivilegedAppsChanged can only be called by privileged apps."); 1346 mAppStandby.clearCarrierPrivilegedApps(); 1347 } 1348 1349 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)1350 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1351 if (!DumpUtils.checkDumpAndUsageStatsPermission(getContext(), TAG, pw)) return; 1352 UsageStatsService.this.dump(args, pw); 1353 } 1354 1355 @Override reportChooserSelection(String packageName, int userId, String contentType, String[] annotations, String action)1356 public void reportChooserSelection(String packageName, int userId, String contentType, 1357 String[] annotations, String action) { 1358 if (packageName == null) { 1359 Slog.w(TAG, "Event report user selecting a null package"); 1360 return; 1361 } 1362 1363 Event event = new Event(CHOOSER_ACTION, SystemClock.elapsedRealtime()); 1364 event.mPackage = packageName; 1365 event.mAction = action; 1366 event.mContentType = contentType; 1367 event.mContentAnnotations = annotations; 1368 mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget(); 1369 } 1370 1371 @Override registerAppUsageObserver(int observerId, String[] packages, long timeLimitMs, PendingIntent callbackIntent, String callingPackage)1372 public void registerAppUsageObserver(int observerId, 1373 String[] packages, long timeLimitMs, PendingIntent 1374 callbackIntent, String callingPackage) { 1375 if (!hasObserverPermission()) { 1376 throw new SecurityException("Caller doesn't have OBSERVE_APP_USAGE permission"); 1377 } 1378 1379 if (packages == null || packages.length == 0) { 1380 throw new IllegalArgumentException("Must specify at least one package"); 1381 } 1382 if (callbackIntent == null) { 1383 throw new NullPointerException("callbackIntent can't be null"); 1384 } 1385 final int callingUid = Binder.getCallingUid(); 1386 final int userId = UserHandle.getUserId(callingUid); 1387 final long token = Binder.clearCallingIdentity(); 1388 try { 1389 UsageStatsService.this.registerAppUsageObserver(callingUid, observerId, 1390 packages, timeLimitMs, callbackIntent, userId); 1391 } finally { 1392 Binder.restoreCallingIdentity(token); 1393 } 1394 } 1395 1396 @Override unregisterAppUsageObserver(int observerId, String callingPackage)1397 public void unregisterAppUsageObserver(int observerId, String callingPackage) { 1398 if (!hasObserverPermission()) { 1399 throw new SecurityException("Caller doesn't have OBSERVE_APP_USAGE permission"); 1400 } 1401 1402 final int callingUid = Binder.getCallingUid(); 1403 final int userId = UserHandle.getUserId(callingUid); 1404 final long token = Binder.clearCallingIdentity(); 1405 try { 1406 UsageStatsService.this.unregisterAppUsageObserver(callingUid, observerId, userId); 1407 } finally { 1408 Binder.restoreCallingIdentity(token); 1409 } 1410 } 1411 1412 @Override registerUsageSessionObserver(int sessionObserverId, String[] observed, long timeLimitMs, long sessionThresholdTimeMs, PendingIntent limitReachedCallbackIntent, PendingIntent sessionEndCallbackIntent, String callingPackage)1413 public void registerUsageSessionObserver(int sessionObserverId, String[] observed, 1414 long timeLimitMs, long sessionThresholdTimeMs, 1415 PendingIntent limitReachedCallbackIntent, PendingIntent sessionEndCallbackIntent, 1416 String callingPackage) { 1417 if (!hasObserverPermission()) { 1418 throw new SecurityException("Caller doesn't have OBSERVE_APP_USAGE permission"); 1419 } 1420 1421 if (observed == null || observed.length == 0) { 1422 throw new IllegalArgumentException("Must specify at least one observed entity"); 1423 } 1424 if (limitReachedCallbackIntent == null) { 1425 throw new NullPointerException("limitReachedCallbackIntent can't be null"); 1426 } 1427 final int callingUid = Binder.getCallingUid(); 1428 final int userId = UserHandle.getUserId(callingUid); 1429 final long token = Binder.clearCallingIdentity(); 1430 try { 1431 UsageStatsService.this.registerUsageSessionObserver(callingUid, sessionObserverId, 1432 observed, timeLimitMs, sessionThresholdTimeMs, limitReachedCallbackIntent, 1433 sessionEndCallbackIntent, userId); 1434 } finally { 1435 Binder.restoreCallingIdentity(token); 1436 } 1437 } 1438 1439 @Override unregisterUsageSessionObserver(int sessionObserverId, String callingPackage)1440 public void unregisterUsageSessionObserver(int sessionObserverId, String callingPackage) { 1441 if (!hasObserverPermission()) { 1442 throw new SecurityException("Caller doesn't have OBSERVE_APP_USAGE permission"); 1443 } 1444 1445 final int callingUid = Binder.getCallingUid(); 1446 final int userId = UserHandle.getUserId(callingUid); 1447 final long token = Binder.clearCallingIdentity(); 1448 try { 1449 UsageStatsService.this.unregisterUsageSessionObserver(callingUid, sessionObserverId, 1450 userId); 1451 } finally { 1452 Binder.restoreCallingIdentity(token); 1453 } 1454 } 1455 1456 @Override registerAppUsageLimitObserver(int observerId, String[] packages, long timeLimitMs, long timeUsedMs, PendingIntent callbackIntent, String callingPackage)1457 public void registerAppUsageLimitObserver(int observerId, String[] packages, 1458 long timeLimitMs, long timeUsedMs, PendingIntent callbackIntent, 1459 String callingPackage) { 1460 if (!hasPermissions(callingPackage, 1461 Manifest.permission.SUSPEND_APPS, Manifest.permission.OBSERVE_APP_USAGE)) { 1462 throw new SecurityException("Caller doesn't have both SUSPEND_APPS and " 1463 + "OBSERVE_APP_USAGE permissions"); 1464 } 1465 1466 if (packages == null || packages.length == 0) { 1467 throw new IllegalArgumentException("Must specify at least one package"); 1468 } 1469 if (callbackIntent == null && timeUsedMs < timeLimitMs) { 1470 throw new NullPointerException("callbackIntent can't be null"); 1471 } 1472 final int callingUid = Binder.getCallingUid(); 1473 final int userId = UserHandle.getUserId(callingUid); 1474 final long token = Binder.clearCallingIdentity(); 1475 try { 1476 UsageStatsService.this.registerAppUsageLimitObserver(callingUid, observerId, 1477 packages, timeLimitMs, timeUsedMs, callbackIntent, userId); 1478 } finally { 1479 Binder.restoreCallingIdentity(token); 1480 } 1481 } 1482 1483 @Override unregisterAppUsageLimitObserver(int observerId, String callingPackage)1484 public void unregisterAppUsageLimitObserver(int observerId, String callingPackage) { 1485 if (!hasPermissions(callingPackage, 1486 Manifest.permission.SUSPEND_APPS, Manifest.permission.OBSERVE_APP_USAGE)) { 1487 throw new SecurityException("Caller doesn't have both SUSPEND_APPS and " 1488 + "OBSERVE_APP_USAGE permissions"); 1489 } 1490 1491 final int callingUid = Binder.getCallingUid(); 1492 final int userId = UserHandle.getUserId(callingUid); 1493 final long token = Binder.clearCallingIdentity(); 1494 try { 1495 UsageStatsService.this.unregisterAppUsageLimitObserver( 1496 callingUid, observerId, userId); 1497 } finally { 1498 Binder.restoreCallingIdentity(token); 1499 } 1500 } 1501 1502 @Override reportUsageStart(IBinder activity, String token, String callingPackage)1503 public void reportUsageStart(IBinder activity, String token, String callingPackage) { 1504 reportPastUsageStart(activity, token, 0, callingPackage); 1505 } 1506 1507 @Override reportPastUsageStart(IBinder activity, String token, long timeAgoMs, String callingPackage)1508 public void reportPastUsageStart(IBinder activity, String token, long timeAgoMs, 1509 String callingPackage) { 1510 1511 final int callingUid = Binder.getCallingUid(); 1512 final int userId = UserHandle.getUserId(callingUid); 1513 final long binderToken = Binder.clearCallingIdentity(); 1514 try { 1515 ArraySet<String> tokens; 1516 synchronized (mUsageReporters) { 1517 tokens = mUsageReporters.get(activity.hashCode()); 1518 if (tokens == null) { 1519 tokens = new ArraySet(); 1520 mUsageReporters.put(activity.hashCode(), tokens); 1521 } 1522 } 1523 1524 synchronized (tokens) { 1525 if (!tokens.add(token)) { 1526 throw new IllegalArgumentException(token + " for " + callingPackage 1527 + " is already reported as started for this activity"); 1528 } 1529 } 1530 1531 mAppTimeLimit.noteUsageStart(buildFullToken(callingPackage, token), 1532 userId, timeAgoMs); 1533 } finally { 1534 Binder.restoreCallingIdentity(binderToken); 1535 } 1536 } 1537 1538 @Override reportUsageStop(IBinder activity, String token, String callingPackage)1539 public void reportUsageStop(IBinder activity, String token, String callingPackage) { 1540 final int callingUid = Binder.getCallingUid(); 1541 final int userId = UserHandle.getUserId(callingUid); 1542 final long binderToken = Binder.clearCallingIdentity(); 1543 try { 1544 ArraySet<String> tokens; 1545 synchronized (mUsageReporters) { 1546 tokens = mUsageReporters.get(activity.hashCode()); 1547 if (tokens == null) { 1548 throw new IllegalArgumentException( 1549 "Unknown reporter trying to stop token " + token + " for " 1550 + callingPackage); 1551 } 1552 } 1553 1554 synchronized (tokens) { 1555 if (!tokens.remove(token)) { 1556 throw new IllegalArgumentException(token + " for " + callingPackage 1557 + " is already reported as stopped for this activity"); 1558 } 1559 } 1560 mAppTimeLimit.noteUsageStop(buildFullToken(callingPackage, token), userId); 1561 } finally { 1562 Binder.restoreCallingIdentity(binderToken); 1563 } 1564 } 1565 1566 @Override getUsageSource()1567 public @UsageSource int getUsageSource() { 1568 if (!hasObserverPermission()) { 1569 throw new SecurityException("Caller doesn't have OBSERVE_APP_USAGE permission"); 1570 } 1571 synchronized (mLock) { 1572 return mUsageSource; 1573 } 1574 } 1575 1576 @Override forceUsageSourceSettingRead()1577 public void forceUsageSourceSettingRead() { 1578 readUsageSourceSetting(); 1579 } 1580 } 1581 registerAppUsageObserver(int callingUid, int observerId, String[] packages, long timeLimitMs, PendingIntent callbackIntent, int userId)1582 void registerAppUsageObserver(int callingUid, int observerId, String[] packages, 1583 long timeLimitMs, PendingIntent callbackIntent, int userId) { 1584 mAppTimeLimit.addAppUsageObserver(callingUid, observerId, packages, timeLimitMs, 1585 callbackIntent, 1586 userId); 1587 } 1588 unregisterAppUsageObserver(int callingUid, int observerId, int userId)1589 void unregisterAppUsageObserver(int callingUid, int observerId, int userId) { 1590 mAppTimeLimit.removeAppUsageObserver(callingUid, observerId, userId); 1591 } 1592 registerUsageSessionObserver(int callingUid, int observerId, String[] observed, long timeLimitMs, long sessionThresholdTime, PendingIntent limitReachedCallbackIntent, PendingIntent sessionEndCallbackIntent, int userId)1593 void registerUsageSessionObserver(int callingUid, int observerId, String[] observed, 1594 long timeLimitMs, long sessionThresholdTime, PendingIntent limitReachedCallbackIntent, 1595 PendingIntent sessionEndCallbackIntent, int userId) { 1596 mAppTimeLimit.addUsageSessionObserver(callingUid, observerId, observed, timeLimitMs, 1597 sessionThresholdTime, limitReachedCallbackIntent, sessionEndCallbackIntent, userId); 1598 } 1599 unregisterUsageSessionObserver(int callingUid, int sessionObserverId, int userId)1600 void unregisterUsageSessionObserver(int callingUid, int sessionObserverId, int userId) { 1601 mAppTimeLimit.removeUsageSessionObserver(callingUid, sessionObserverId, userId); 1602 } 1603 registerAppUsageLimitObserver(int callingUid, int observerId, String[] packages, long timeLimitMs, long timeUsedMs, PendingIntent callbackIntent, int userId)1604 void registerAppUsageLimitObserver(int callingUid, int observerId, String[] packages, 1605 long timeLimitMs, long timeUsedMs, PendingIntent callbackIntent, int userId) { 1606 mAppTimeLimit.addAppUsageLimitObserver(callingUid, observerId, packages, 1607 timeLimitMs, timeUsedMs, callbackIntent, userId); 1608 } 1609 unregisterAppUsageLimitObserver(int callingUid, int observerId, int userId)1610 void unregisterAppUsageLimitObserver(int callingUid, int observerId, int userId) { 1611 mAppTimeLimit.removeAppUsageLimitObserver(callingUid, observerId, userId); 1612 } 1613 1614 /** 1615 * This local service implementation is primarily used by ActivityManagerService. 1616 * ActivityManagerService will call these methods holding the 'am' lock, which means we 1617 * shouldn't be doing any IO work or other long running tasks in these methods. 1618 */ 1619 private final class LocalService extends UsageStatsManagerInternal { 1620 1621 @Override reportEvent(ComponentName component, int userId, int eventType, int instanceId, ComponentName taskRoot)1622 public void reportEvent(ComponentName component, int userId, int eventType, 1623 int instanceId, ComponentName taskRoot) { 1624 if (component == null) { 1625 Slog.w(TAG, "Event reported without a component name"); 1626 return; 1627 } 1628 1629 Event event = new Event(eventType, SystemClock.elapsedRealtime()); 1630 event.mPackage = component.getPackageName(); 1631 event.mClass = component.getClassName(); 1632 event.mInstanceId = instanceId; 1633 if (taskRoot == null) { 1634 event.mTaskRootPackage = null; 1635 event.mTaskRootClass = null; 1636 } else { 1637 event.mTaskRootPackage = taskRoot.getPackageName(); 1638 event.mTaskRootClass = taskRoot.getClassName(); 1639 } 1640 mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget(); 1641 } 1642 1643 @Override reportEvent(String packageName, int userId, int eventType)1644 public void reportEvent(String packageName, int userId, int eventType) { 1645 if (packageName == null) { 1646 Slog.w(TAG, "Event reported without a package name, eventType:" + eventType); 1647 return; 1648 } 1649 1650 Event event = new Event(eventType, SystemClock.elapsedRealtime()); 1651 event.mPackage = packageName; 1652 mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget(); 1653 } 1654 1655 @Override reportConfigurationChange(Configuration config, int userId)1656 public void reportConfigurationChange(Configuration config, int userId) { 1657 if (config == null) { 1658 Slog.w(TAG, "Configuration event reported with a null config"); 1659 return; 1660 } 1661 1662 Event event = new Event(CONFIGURATION_CHANGE, SystemClock.elapsedRealtime()); 1663 event.mPackage = "android"; 1664 event.mConfiguration = new Configuration(config); 1665 mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget(); 1666 } 1667 1668 @Override reportInterruptiveNotification(String packageName, String channelId, int userId)1669 public void reportInterruptiveNotification(String packageName, String channelId, 1670 int userId) { 1671 if (packageName == null || channelId == null) { 1672 Slog.w(TAG, "Event reported without a package name or a channel ID"); 1673 return; 1674 } 1675 1676 Event event = new Event(NOTIFICATION_INTERRUPTION, SystemClock.elapsedRealtime()); 1677 event.mPackage = packageName.intern(); 1678 event.mNotificationChannelId = channelId.intern(); 1679 mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget(); 1680 } 1681 1682 @Override reportShortcutUsage(String packageName, String shortcutId, int userId)1683 public void reportShortcutUsage(String packageName, String shortcutId, int userId) { 1684 if (packageName == null || shortcutId == null) { 1685 Slog.w(TAG, "Event reported without a package name or a shortcut ID"); 1686 return; 1687 } 1688 1689 Event event = new Event(SHORTCUT_INVOCATION, SystemClock.elapsedRealtime()); 1690 event.mPackage = packageName.intern(); 1691 event.mShortcutId = shortcutId.intern(); 1692 mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget(); 1693 } 1694 1695 @Override reportContentProviderUsage(String name, String packageName, int userId)1696 public void reportContentProviderUsage(String name, String packageName, int userId) { 1697 mAppStandby.postReportContentProviderUsage(name, packageName, userId); 1698 } 1699 1700 @Override isAppIdle(String packageName, int uidForAppId, int userId)1701 public boolean isAppIdle(String packageName, int uidForAppId, int userId) { 1702 return mAppStandby.isAppIdleFiltered(packageName, uidForAppId, 1703 userId, SystemClock.elapsedRealtime()); 1704 } 1705 1706 @Override getAppStandbyBucket(String packageName, int userId, long nowElapsed)1707 @StandbyBuckets public int getAppStandbyBucket(String packageName, int userId, 1708 long nowElapsed) { 1709 return mAppStandby.getAppStandbyBucket(packageName, userId, nowElapsed, false); 1710 } 1711 1712 @Override getIdleUidsForUser(int userId)1713 public int[] getIdleUidsForUser(int userId) { 1714 return mAppStandby.getIdleUidsForUser(userId); 1715 } 1716 1717 @Override isAppIdleParoleOn()1718 public boolean isAppIdleParoleOn() { 1719 return mAppStandby.isParoledOrCharging(); 1720 } 1721 1722 @Override prepareShutdown()1723 public void prepareShutdown() { 1724 // This method *WILL* do IO work, but we must block until it is finished or else 1725 // we might not shutdown cleanly. This is ok to do with the 'am' lock held, because 1726 // we are shutting down. 1727 UsageStatsService.this.shutdown(); 1728 } 1729 1730 @Override prepareForPossibleShutdown()1731 public void prepareForPossibleShutdown() { 1732 UsageStatsService.this.prepareForPossibleShutdown(); 1733 } 1734 1735 @Override addAppIdleStateChangeListener(AppIdleStateChangeListener listener)1736 public void addAppIdleStateChangeListener(AppIdleStateChangeListener listener) { 1737 mAppStandby.addListener(listener); 1738 listener.onParoleStateChanged(isAppIdleParoleOn()); 1739 } 1740 1741 @Override removeAppIdleStateChangeListener( AppIdleStateChangeListener listener)1742 public void removeAppIdleStateChangeListener( 1743 AppIdleStateChangeListener listener) { 1744 mAppStandby.removeListener(listener); 1745 } 1746 1747 @Override getBackupPayload(int user, String key)1748 public byte[] getBackupPayload(int user, String key) { 1749 // Check to ensure that only user 0's data is b/r for now 1750 synchronized (mLock) { 1751 if (user == UserHandle.USER_SYSTEM) { 1752 final UserUsageStatsService userStats = 1753 getUserDataAndInitializeIfNeededLocked(user, checkAndGetTimeLocked()); 1754 return userStats.getBackupPayload(key); 1755 } else { 1756 return null; 1757 } 1758 } 1759 } 1760 1761 @Override applyRestoredPayload(int user, String key, byte[] payload)1762 public void applyRestoredPayload(int user, String key, byte[] payload) { 1763 synchronized (mLock) { 1764 if (user == UserHandle.USER_SYSTEM) { 1765 final UserUsageStatsService userStats = 1766 getUserDataAndInitializeIfNeededLocked(user, checkAndGetTimeLocked()); 1767 userStats.applyRestoredPayload(key, payload); 1768 } 1769 } 1770 } 1771 1772 @Override queryUsageStatsForUser( int userId, int intervalType, long beginTime, long endTime, boolean obfuscateInstantApps)1773 public List<UsageStats> queryUsageStatsForUser( 1774 int userId, int intervalType, long beginTime, long endTime, 1775 boolean obfuscateInstantApps) { 1776 return UsageStatsService.this.queryUsageStats( 1777 userId, intervalType, beginTime, endTime, obfuscateInstantApps); 1778 } 1779 1780 @Override setLastJobRunTime(String packageName, int userId, long elapsedRealtime)1781 public void setLastJobRunTime(String packageName, int userId, long elapsedRealtime) { 1782 mAppStandby.setLastJobRunTime(packageName, userId, elapsedRealtime); 1783 } 1784 1785 @Override getTimeSinceLastJobRun(String packageName, int userId)1786 public long getTimeSinceLastJobRun(String packageName, int userId) { 1787 return mAppStandby.getTimeSinceLastJobRun(packageName, userId); 1788 } 1789 1790 @Override reportAppJobState(String packageName, int userId, int numDeferredJobs, long timeSinceLastJobRun)1791 public void reportAppJobState(String packageName, int userId, 1792 int numDeferredJobs, long timeSinceLastJobRun) { 1793 } 1794 1795 @Override onActiveAdminAdded(String packageName, int userId)1796 public void onActiveAdminAdded(String packageName, int userId) { 1797 mAppStandby.addActiveDeviceAdmin(packageName, userId); 1798 } 1799 1800 @Override setActiveAdminApps(Set<String> packageNames, int userId)1801 public void setActiveAdminApps(Set<String> packageNames, int userId) { 1802 mAppStandby.setActiveAdminApps(packageNames, userId); 1803 } 1804 1805 @Override onAdminDataAvailable()1806 public void onAdminDataAvailable() { 1807 mAppStandby.onAdminDataAvailable(); 1808 } 1809 1810 @Override reportSyncScheduled(String packageName, int userId, boolean exempted)1811 public void reportSyncScheduled(String packageName, int userId, boolean exempted) { 1812 mAppStandby.postReportSyncScheduled(packageName, userId, exempted); 1813 } 1814 1815 @Override reportExemptedSyncStart(String packageName, int userId)1816 public void reportExemptedSyncStart(String packageName, int userId) { 1817 mAppStandby.postReportExemptedSyncStart(packageName, userId); 1818 } 1819 1820 @Override getAppUsageLimit(String packageName, UserHandle user)1821 public AppUsageLimitData getAppUsageLimit(String packageName, UserHandle user) { 1822 return mAppTimeLimit.getAppUsageLimit(packageName, user); 1823 } 1824 } 1825 } 1826