2 * Copyright (C) 2014 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
17 package com.android.server.usage;
19 import android.Manifest;
20 import android.app.ActivityManagerNative;
21 import android.app.AppGlobals;
22 import android.app.AppOpsManager;
23 import android.app.admin.DevicePolicyManager;
24 import android.app.usage.ConfigurationStats;
25 import android.app.usage.IUsageStatsManager;
26 import android.app.usage.UsageEvents;
27 import android.app.usage.UsageEvents.Event;
28 import android.app.usage.UsageStats;
29 import android.app.usage.UsageStatsManagerInternal;
30 import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener;
31 import android.appwidget.AppWidgetManager;
32 import android.content.BroadcastReceiver;
33 import android.content.ComponentName;
34 import android.content.ContentResolver;
35 import android.content.Context;
36 import android.content.Intent;
37 import android.content.IntentFilter;
38 import android.content.pm.ApplicationInfo;
39 import android.content.pm.PackageInfo;
40 import android.content.pm.PackageManager;
41 import android.content.pm.ParceledListSlice;
42 import android.content.pm.UserInfo;
43 import android.content.res.Configuration;
44 import android.database.ContentObserver;
45 import android.hardware.display.DisplayManager;
46 import android.net.NetworkScoreManager;
47 import android.os.BatteryManager;
48 import android.os.BatteryStats;
49 import android.os.Binder;
50 import android.os.Environment;
51 import android.os.Handler;
52 import android.os.IDeviceIdleController;
53 import android.os.Looper;
54 import android.os.Message;
55 import android.os.PowerManager;
56 import android.os.Process;
57 import android.os.RemoteException;
58 import android.os.ServiceManager;
59 import android.os.SystemClock;
60 import android.os.UserHandle;
61 import android.os.UserManager;
62 import android.provider.Settings;
63 import android.telephony.TelephonyManager;
64 import android.util.ArraySet;
65 import android.util.AtomicFile;
66 import android.util.KeyValueListParser;
67 import android.util.Slog;
68 import android.util.SparseArray;
69 import android.util.SparseIntArray;
70 import android.util.TimeUtils;
71 import android.view.Display;
73 import com.android.internal.annotations.GuardedBy;
74 import com.android.internal.app.IBatteryStats;
75 import com.android.internal.os.BackgroundThread;
76 import com.android.internal.os.SomeArgs;
77 import com.android.internal.util.IndentingPrintWriter;
78 import com.android.server.SystemService;
80 import java.io.BufferedReader;
82 import java.io.FileDescriptor;
83 import java.io.FileOutputStream;
84 import java.io.FileReader;
85 import java.io.IOException;
86 import java.io.PrintWriter;
87 import java.util.ArrayList;
88 import java.util.Arrays;
89 import java.util.List;
92 * A service that collects, aggregates, and persists application usage data.
93 * This data can be queried by apps that have been granted permission by AppOps.
95 public class UsageStatsService extends SystemService implements
96 UserUsageStatsService.StatsUpdatedListener {
98 static final String TAG = "UsageStatsService";
100 static final boolean DEBUG = false;
101 static final boolean COMPRESS_TIME = false;
103 private static final long TEN_SECONDS = 10 * 1000;
104 private static final long ONE_MINUTE = 60 * 1000;
105 private static final long TWENTY_MINUTES = 20 * 60 * 1000;
106 private static final long FLUSH_INTERVAL = COMPRESS_TIME ? TEN_SECONDS : TWENTY_MINUTES;
107 private static final long TIME_CHANGE_THRESHOLD_MILLIS = 2 * 1000; // Two seconds.
109 long mAppIdleDurationMillis;
110 long mCheckIdleIntervalMillis;
111 long mAppIdleWallclockThresholdMillis;
112 long mAppIdleParoleIntervalMillis;
113 long mAppIdleParoleDurationMillis;
115 // Handler message types.
116 static final int MSG_REPORT_EVENT = 0;
117 static final int MSG_FLUSH_TO_DISK = 1;
118 static final int MSG_REMOVE_USER = 2;
119 static final int MSG_INFORM_LISTENERS = 3;
120 static final int MSG_FORCE_IDLE_STATE = 4;
121 static final int MSG_CHECK_IDLE_STATES = 5;
122 static final int MSG_CHECK_PAROLE_TIMEOUT = 6;
123 static final int MSG_PAROLE_END_TIMEOUT = 7;
124 static final int MSG_REPORT_CONTENT_PROVIDER_USAGE = 8;
125 static final int MSG_PAROLE_STATE_CHANGED = 9;
126 static final int MSG_ONE_TIME_CHECK_IDLE_STATES = 10;
128 private final Object mLock = new Object();
130 AppOpsManager mAppOps;
131 UserManager mUserManager;
132 AppWidgetManager mAppWidgetManager;
133 IDeviceIdleController mDeviceIdleController;
134 private DisplayManager mDisplayManager;
135 private PowerManager mPowerManager;
136 private IBatteryStats mBatteryStats;
138 private final SparseArray<UserUsageStatsService> mUserState = new SparseArray<>();
139 private File mUsageStatsDir;
140 long mRealTimeSnapshot;
141 long mSystemTimeSnapshot;
143 boolean mAppIdleEnabled;
144 boolean mAppIdleParoled;
145 private boolean mScreenOn;
146 private long mLastAppIdleParoledTime;
149 long mLastScreenOnEventRealtime;
152 private AppIdleHistory mAppIdleHistory = new AppIdleHistory();
154 private ArrayList<UsageStatsManagerInternal.AppIdleStateChangeListener>
155 mPackageAccessListeners = new ArrayList<>();
157 public UsageStatsService(Context context) {
162 public void onStart() {
163 mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE);
164 mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE);
166 mHandler = new H(BackgroundThread.get().getLooper());
168 File systemDataDir = new File(Environment.getDataDirectory(), "system");
169 mUsageStatsDir = new File(systemDataDir, "usagestats");
170 mUsageStatsDir.mkdirs();
171 if (!mUsageStatsDir.exists()) {
172 throw new IllegalStateException("Usage stats directory does not exist: "
173 + mUsageStatsDir.getAbsolutePath());
176 IntentFilter userActions = new IntentFilter(Intent.ACTION_USER_REMOVED);
177 userActions.addAction(Intent.ACTION_USER_STARTED);
178 getContext().registerReceiverAsUser(new UserActionsReceiver(), UserHandle.ALL, userActions,
181 mAppIdleEnabled = getContext().getResources().getBoolean(
182 com.android.internal.R.bool.config_enableAutoPowerModes);
183 if (mAppIdleEnabled) {
184 IntentFilter deviceStates = new IntentFilter(BatteryManager.ACTION_CHARGING);
185 deviceStates.addAction(BatteryManager.ACTION_DISCHARGING);
186 deviceStates.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
187 getContext().registerReceiver(new DeviceStateReceiver(), deviceStates);
190 synchronized (mLock) {
191 cleanUpRemovedUsersLocked();
192 mLastScreenOnEventRealtime = SystemClock.elapsedRealtime();
193 mScreenOnTime = readScreenOnTimeLocked();
196 mRealTimeSnapshot = SystemClock.elapsedRealtime();
197 mSystemTimeSnapshot = System.currentTimeMillis();
199 publishLocalService(UsageStatsManagerInternal.class, new LocalService());
200 publishBinderService(Context.USAGE_STATS_SERVICE, new BinderService());
204 public void onBootPhase(int phase) {
205 if (phase == PHASE_SYSTEM_SERVICES_READY) {
206 // Observe changes to the threshold
207 SettingsObserver settingsObserver = new SettingsObserver(mHandler);
208 settingsObserver.registerObserver();
209 settingsObserver.updateSettings();
211 mAppWidgetManager = getContext().getSystemService(AppWidgetManager.class);
212 mDeviceIdleController = IDeviceIdleController.Stub.asInterface(
213 ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
214 mBatteryStats = IBatteryStats.Stub.asInterface(
215 ServiceManager.getService(BatteryStats.SERVICE_NAME));
216 mDisplayManager = (DisplayManager) getContext().getSystemService(
217 Context.DISPLAY_SERVICE);
218 mPowerManager = getContext().getSystemService(PowerManager.class);
220 mDisplayManager.registerDisplayListener(mDisplayListener, mHandler);
221 synchronized (mLock) {
222 updateDisplayLocked();
224 } else if (phase == PHASE_BOOT_COMPLETED) {
225 setAppIdleParoled(getContext().getSystemService(BatteryManager.class).isCharging());
229 private class UserActionsReceiver extends BroadcastReceiver {
232 public void onReceive(Context context, Intent intent) {
233 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
234 if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
236 mHandler.obtainMessage(MSG_REMOVE_USER, userId, 0).sendToTarget();
238 } else if (Intent.ACTION_USER_STARTED.equals(intent.getAction())) {
240 postCheckIdleStates(userId);
246 private class DeviceStateReceiver extends BroadcastReceiver {
248 public void onReceive(Context context, Intent intent) {
249 final String action = intent.getAction();
250 if (BatteryManager.ACTION_CHARGING.equals(action)
251 || BatteryManager.ACTION_DISCHARGING.equals(action)) {
252 setAppIdleParoled(BatteryManager.ACTION_CHARGING.equals(action));
253 } else if (PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED.equals(action)) {
254 onDeviceIdleModeChanged();
259 private final DisplayManager.DisplayListener mDisplayListener
260 = new DisplayManager.DisplayListener() {
262 @Override public void onDisplayAdded(int displayId) {
265 @Override public void onDisplayRemoved(int displayId) {
268 @Override public void onDisplayChanged(int displayId) {
269 if (displayId == Display.DEFAULT_DISPLAY) {
270 synchronized (UsageStatsService.this.mLock) {
271 updateDisplayLocked();
278 public void onStatsUpdated() {
279 mHandler.sendEmptyMessageDelayed(MSG_FLUSH_TO_DISK, FLUSH_INTERVAL);
283 public void onStatsReloaded() {
284 postOneTimeCheckIdleStates();
288 public long getAppIdleRollingWindowDurationMillis() {
289 return mAppIdleWallclockThresholdMillis * 2;
292 private void cleanUpRemovedUsersLocked() {
293 final List<UserInfo> users = mUserManager.getUsers(true);
294 if (users == null || users.size() == 0) {
295 throw new IllegalStateException("There can't be no users");
298 ArraySet<String> toDelete = new ArraySet<>();
299 String[] fileNames = mUsageStatsDir.list();
300 if (fileNames == null) {
301 // No users to delete.
305 toDelete.addAll(Arrays.asList(fileNames));
307 final int userCount = users.size();
308 for (int i = 0; i < userCount; i++) {
309 final UserInfo userInfo = users.get(i);
310 toDelete.remove(Integer.toString(userInfo.id));
313 final int deleteCount = toDelete.size();
314 for (int i = 0; i < deleteCount; i++) {
315 deleteRecursively(new File(mUsageStatsDir, toDelete.valueAt(i)));
319 /** Paroled here means temporary pardon from being inactive */
320 void setAppIdleParoled(boolean paroled) {
321 synchronized (mLock) {
322 if (mAppIdleParoled != paroled) {
323 mAppIdleParoled = paroled;
324 if (DEBUG) Slog.d(TAG, "Changing paroled to " + mAppIdleParoled);
326 postParoleEndTimeout();
328 mLastAppIdleParoledTime = checkAndGetTimeLocked();
329 postNextParoleTimeout();
331 postParoleStateChanged();
336 private void postNextParoleTimeout() {
337 if (DEBUG) Slog.d(TAG, "Posting MSG_CHECK_PAROLE_TIMEOUT");
338 mHandler.removeMessages(MSG_CHECK_PAROLE_TIMEOUT);
339 // Compute when the next parole needs to happen. We check more frequently than necessary
340 // since the message handler delays are based on elapsedRealTime and not wallclock time.
341 // The comparison is done in wallclock time.
342 long timeLeft = (mLastAppIdleParoledTime + mAppIdleParoleIntervalMillis)
343 - checkAndGetTimeLocked();
347 mHandler.sendEmptyMessageDelayed(MSG_CHECK_PAROLE_TIMEOUT, timeLeft / 10);
350 private void postParoleEndTimeout() {
351 if (DEBUG) Slog.d(TAG, "Posting MSG_PAROLE_END_TIMEOUT");
352 mHandler.removeMessages(MSG_PAROLE_END_TIMEOUT);
353 mHandler.sendEmptyMessageDelayed(MSG_PAROLE_END_TIMEOUT, mAppIdleParoleDurationMillis);
356 private void postParoleStateChanged() {
357 if (DEBUG) Slog.d(TAG, "Posting MSG_PAROLE_STATE_CHANGED");
358 mHandler.removeMessages(MSG_PAROLE_STATE_CHANGED);
359 mHandler.sendEmptyMessage(MSG_PAROLE_STATE_CHANGED);
362 void postCheckIdleStates(int userId) {
363 mHandler.sendMessage(mHandler.obtainMessage(MSG_CHECK_IDLE_STATES, userId, 0));
367 * We send a different message to check idle states once, otherwise we would end up
368 * scheduling a series of repeating checkIdleStates each time we fired off one.
370 void postOneTimeCheckIdleStates() {
371 mHandler.sendEmptyMessage(MSG_ONE_TIME_CHECK_IDLE_STATES);
374 /** Check all running users' or specified user's apps to see if they enter an idle state. */
375 void checkIdleStates(int checkUserId) {
376 if (!mAppIdleEnabled) {
382 if (checkUserId == UserHandle.USER_ALL) {
383 userIds = ActivityManagerNative.getDefault().getRunningUserIds();
385 userIds = new int[] { checkUserId };
387 } catch (RemoteException re) {
391 for (int i = 0; i < userIds.length; i++) {
392 final int userId = userIds[i];
393 List<PackageInfo> packages =
394 getContext().getPackageManager().getInstalledPackagesAsUser(
395 PackageManager.GET_DISABLED_COMPONENTS
396 | PackageManager.GET_UNINSTALLED_PACKAGES,
398 synchronized (mLock) {
399 final long timeNow = checkAndGetTimeLocked();
400 final long screenOnTime = getScreenOnTimeLocked();
401 UserUsageStatsService service = getUserDataAndInitializeIfNeededLocked(userId,
403 final int packageCount = packages.size();
404 for (int p = 0; p < packageCount; p++) {
405 final PackageInfo pi = packages.get(p);
406 final String packageName = pi.packageName;
407 final boolean isIdle = isAppIdleFiltered(packageName,
408 UserHandle.getAppId(pi.applicationInfo.uid),
409 userId, service, timeNow, screenOnTime);
410 mHandler.sendMessage(mHandler.obtainMessage(MSG_INFORM_LISTENERS,
411 userId, isIdle ? 1 : 0, packageName));
412 mAppIdleHistory.addEntry(packageName, userId, isIdle, timeNow);
418 /** Check if it's been a while since last parole and let idle apps do some work */
419 void checkParoleTimeout() {
420 synchronized (mLock) {
421 if (!mAppIdleParoled) {
422 final long timeSinceLastParole = checkAndGetTimeLocked() - mLastAppIdleParoledTime;
423 if (timeSinceLastParole > mAppIdleParoleIntervalMillis) {
424 if (DEBUG) Slog.d(TAG, "Crossed default parole interval");
425 setAppIdleParoled(true);
427 if (DEBUG) Slog.d(TAG, "Not long enough to go to parole");
428 postNextParoleTimeout();
434 private void notifyBatteryStats(String packageName, int userId, boolean idle) {
436 final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
437 PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
439 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_PACKAGE_INACTIVE,
442 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_PACKAGE_ACTIVE,
445 } catch (RemoteException re) {
449 void updateDisplayLocked() {
450 boolean screenOn = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY).getState()
453 if (screenOn == mScreenOn) return;
455 mScreenOn = screenOn;
456 long now = SystemClock.elapsedRealtime();
458 mLastScreenOnEventRealtime = now;
460 mScreenOnTime += now - mLastScreenOnEventRealtime;
461 writeScreenOnTimeLocked(mScreenOnTime);
465 long getScreenOnTimeLocked() {
466 long screenOnTime = mScreenOnTime;
468 screenOnTime += SystemClock.elapsedRealtime() - mLastScreenOnEventRealtime;
473 private File getScreenOnTimeFile() {
474 return new File(mUsageStatsDir, UserHandle.USER_SYSTEM + "/screen_on_time");
477 private long readScreenOnTimeLocked() {
478 long screenOnTime = 0;
479 File screenOnTimeFile = getScreenOnTimeFile();
480 if (screenOnTimeFile.exists()) {
482 BufferedReader reader = new BufferedReader(new FileReader(screenOnTimeFile));
483 screenOnTime = Long.parseLong(reader.readLine());
485 } catch (IOException | NumberFormatException e) {
488 writeScreenOnTimeLocked(screenOnTime);
493 private void writeScreenOnTimeLocked(long screenOnTime) {
494 AtomicFile screenOnTimeFile = new AtomicFile(getScreenOnTimeFile());
495 FileOutputStream fos = null;
497 fos = screenOnTimeFile.startWrite();
498 fos.write(Long.toString(screenOnTime).getBytes());
499 screenOnTimeFile.finishWrite(fos);
500 } catch (IOException ioe) {
501 screenOnTimeFile.failWrite(fos);
505 void onDeviceIdleModeChanged() {
506 final boolean deviceIdle = mPowerManager.isDeviceIdleMode();
507 if (DEBUG) Slog.i(TAG, "DeviceIdleMode changed to " + deviceIdle);
508 synchronized (mLock) {
509 final long timeSinceLastParole = checkAndGetTimeLocked() - mLastAppIdleParoledTime;
511 && timeSinceLastParole >= mAppIdleParoleIntervalMillis) {
512 if (DEBUG) Slog.i(TAG, "Bringing idle apps out of inactive state due to deviceIdleMode=false");
513 setAppIdleParoled(true);
514 } else if (deviceIdle) {
515 if (DEBUG) Slog.i(TAG, "Device idle, back to prison");
516 setAppIdleParoled(false);
521 private static void deleteRecursively(File f) {
522 File[] files = f.listFiles();
524 for (File subFile : files) {
525 deleteRecursively(subFile);
530 Slog.e(TAG, "Failed to delete " + f);
534 private UserUsageStatsService getUserDataAndInitializeIfNeededLocked(int userId,
535 long currentTimeMillis) {
536 UserUsageStatsService service = mUserState.get(userId);
537 if (service == null) {
538 service = new UserUsageStatsService(getContext(), userId,
539 new File(mUsageStatsDir, Integer.toString(userId)), this);
540 service.init(currentTimeMillis, getScreenOnTimeLocked());
541 mUserState.put(userId, service);
547 * This should be the only way to get the time from the system.
549 private long checkAndGetTimeLocked() {
550 final long actualSystemTime = System.currentTimeMillis();
551 final long actualRealtime = SystemClock.elapsedRealtime();
552 final long expectedSystemTime = (actualRealtime - mRealTimeSnapshot) + mSystemTimeSnapshot;
553 final long diffSystemTime = actualSystemTime - expectedSystemTime;
554 if (Math.abs(diffSystemTime) > TIME_CHANGE_THRESHOLD_MILLIS) {
555 // The time has changed.
556 Slog.i(TAG, "Time changed in UsageStats by " + (diffSystemTime / 1000) + " seconds");
557 final int userCount = mUserState.size();
558 for (int i = 0; i < userCount; i++) {
559 final UserUsageStatsService service = mUserState.valueAt(i);
560 service.onTimeChanged(expectedSystemTime, actualSystemTime, getScreenOnTimeLocked(),
563 mRealTimeSnapshot = actualRealtime;
564 mSystemTimeSnapshot = actualSystemTime;
566 return actualSystemTime;
570 * Assuming the event's timestamp is measured in milliseconds since boot,
571 * convert it to a system wall time.
573 private void convertToSystemTimeLocked(UsageEvents.Event event) {
574 event.mTimeStamp = Math.max(0, event.mTimeStamp - mRealTimeSnapshot) + mSystemTimeSnapshot;
578 * Called by the Binder stub
581 synchronized (mLock) {
582 mHandler.removeMessages(MSG_REPORT_EVENT);
588 * Called by the Binder stub.
590 void reportEvent(UsageEvents.Event event, int userId) {
591 synchronized (mLock) {
592 final long timeNow = checkAndGetTimeLocked();
593 final long screenOnTime = getScreenOnTimeLocked();
594 convertToSystemTimeLocked(event);
596 final UserUsageStatsService service =
597 getUserDataAndInitializeIfNeededLocked(userId, timeNow);
598 final long beginIdleTime = service.getBeginIdleTime(event.mPackage);
599 final long lastUsedTime = service.getSystemLastUsedTime(event.mPackage);
600 final boolean previouslyIdle = hasPassedIdleTimeoutLocked(beginIdleTime,
601 lastUsedTime, screenOnTime, timeNow);
602 service.reportEvent(event, screenOnTime);
603 // Inform listeners if necessary
604 if ((event.mEventType == Event.MOVE_TO_FOREGROUND
605 || event.mEventType == Event.MOVE_TO_BACKGROUND
606 || event.mEventType == Event.SYSTEM_INTERACTION
607 || event.mEventType == Event.USER_INTERACTION)) {
608 if (previouslyIdle) {
609 mHandler.sendMessage(mHandler.obtainMessage(MSG_INFORM_LISTENERS, userId,
610 /* idle = */ 0, event.mPackage));
611 notifyBatteryStats(event.mPackage, userId, false);
612 mAppIdleHistory.addEntry(event.mPackage, userId, false, timeNow);
618 void reportContentProviderUsage(String authority, String providerPkgName, int userId) {
619 // Get sync adapters for the authority
620 String[] packages = ContentResolver.getSyncAdapterPackagesForAuthorityAsUser(
622 for (String packageName: packages) {
623 // Only force the sync adapters to active if the provider is not in the same package and
624 // the sync adapter is a system package.
626 PackageInfo pi = AppGlobals.getPackageManager().getPackageInfo(
627 packageName, PackageManager.MATCH_SYSTEM_ONLY, userId);
628 if (pi == null || pi.applicationInfo == null) {
631 if (!packageName.equals(providerPkgName)) {
632 forceIdleState(packageName, userId, false);
634 } catch (RemoteException re) {
641 * Forces the app's beginIdleTime and lastUsedTime to reflect idle or active. If idle,
642 * then it rolls back the beginIdleTime and lastUsedTime to a point in time that's behind
643 * the threshold for idle.
645 void forceIdleState(String packageName, int userId, boolean idle) {
646 synchronized (mLock) {
647 final long timeNow = checkAndGetTimeLocked();
648 final long screenOnTime = getScreenOnTimeLocked();
649 final long deviceUsageTime = screenOnTime - (idle ? mAppIdleDurationMillis : 0) - 5000;
651 final UserUsageStatsService service =
652 getUserDataAndInitializeIfNeededLocked(userId, timeNow);
653 final long beginIdleTime = service.getBeginIdleTime(packageName);
654 final long lastUsedTime = service.getSystemLastUsedTime(packageName);
655 final boolean previouslyIdle = hasPassedIdleTimeoutLocked(beginIdleTime,
656 lastUsedTime, screenOnTime, timeNow);
657 service.setBeginIdleTime(packageName, deviceUsageTime);
658 service.setSystemLastUsedTime(packageName,
659 timeNow - (idle ? mAppIdleWallclockThresholdMillis : 0) - 5000);
660 // Inform listeners if necessary
661 if (previouslyIdle != idle) {
662 mHandler.sendMessage(mHandler.obtainMessage(MSG_INFORM_LISTENERS, userId,
663 /* idle = */ idle ? 1 : 0, packageName));
665 notifyBatteryStats(packageName, userId, idle);
667 mAppIdleHistory.addEntry(packageName, userId, idle, timeNow);
673 * Called by the Binder stub.
676 synchronized (mLock) {
682 * Called by the Binder stub.
684 void removeUser(int userId) {
685 synchronized (mLock) {
686 Slog.i(TAG, "Removing user " + userId + " and all data.");
687 mUserState.remove(userId);
688 cleanUpRemovedUsersLocked();
693 * Called by the Binder stub.
695 List<UsageStats> queryUsageStats(int userId, int bucketType, long beginTime, long endTime) {
696 synchronized (mLock) {
697 final long timeNow = checkAndGetTimeLocked();
698 if (!validRange(timeNow, beginTime, endTime)) {
702 final UserUsageStatsService service =
703 getUserDataAndInitializeIfNeededLocked(userId, timeNow);
704 return service.queryUsageStats(bucketType, beginTime, endTime);
709 * Called by the Binder stub.
711 List<ConfigurationStats> queryConfigurationStats(int userId, int bucketType, long beginTime,
713 synchronized (mLock) {
714 final long timeNow = checkAndGetTimeLocked();
715 if (!validRange(timeNow, beginTime, endTime)) {
719 final UserUsageStatsService service =
720 getUserDataAndInitializeIfNeededLocked(userId, timeNow);
721 return service.queryConfigurationStats(bucketType, beginTime, endTime);
726 * Called by the Binder stub.
728 UsageEvents queryEvents(int userId, long beginTime, long endTime) {
729 synchronized (mLock) {
730 final long timeNow = checkAndGetTimeLocked();
731 if (!validRange(timeNow, beginTime, endTime)) {
735 final UserUsageStatsService service =
736 getUserDataAndInitializeIfNeededLocked(userId, timeNow);
737 return service.queryEvents(beginTime, endTime);
741 private boolean isAppIdleUnfiltered(String packageName, UserUsageStatsService userService,
742 long timeNow, long screenOnTime) {
743 synchronized (mLock) {
744 long beginIdleTime = userService.getBeginIdleTime(packageName);
745 long lastUsedTime = userService.getSystemLastUsedTime(packageName);
746 return hasPassedIdleTimeoutLocked(beginIdleTime, lastUsedTime, screenOnTime,
752 * @param beginIdleTime when the app was last used in device usage timebase
753 * @param lastUsedTime wallclock time of when the app was last used
754 * @param screenOnTime screen-on timebase time
755 * @param currentTime current time in device usage timebase
756 * @return whether it's been used far enough in the past to be considered inactive
758 boolean hasPassedIdleTimeoutLocked(long beginIdleTime, long lastUsedTime,
759 long screenOnTime, long currentTime) {
760 return (beginIdleTime <= screenOnTime - mAppIdleDurationMillis)
761 && (lastUsedTime <= currentTime - mAppIdleWallclockThresholdMillis);
764 void addListener(AppIdleStateChangeListener listener) {
765 synchronized (mLock) {
766 if (!mPackageAccessListeners.contains(listener)) {
767 mPackageAccessListeners.add(listener);
772 void removeListener(AppIdleStateChangeListener listener) {
773 synchronized (mLock) {
774 mPackageAccessListeners.remove(listener);
778 boolean isAppIdleFilteredOrParoled(String packageName, int userId, long timeNow) {
779 if (mAppIdleParoled) {
783 ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(packageName,
784 PackageManager.GET_UNINSTALLED_PACKAGES
785 | PackageManager.GET_DISABLED_COMPONENTS);
786 return isAppIdleFiltered(packageName, ai.uid, userId, timeNow);
787 } catch (PackageManager.NameNotFoundException e) {
792 boolean isAppIdleFiltered(String packageName, int uidForAppId, int userId, long timeNow) {
793 final UserUsageStatsService userService;
794 final long screenOnTime;
795 synchronized (mLock) {
797 timeNow = checkAndGetTimeLocked();
799 userService = getUserDataAndInitializeIfNeededLocked(userId, timeNow);
800 screenOnTime = getScreenOnTimeLocked();
802 return isAppIdleFiltered(packageName, UserHandle.getAppId(uidForAppId), userId,
803 userService, timeNow, screenOnTime);
807 * Checks if an app has been idle for a while and filters out apps that are excluded.
808 * It returns false if the current system state allows all apps to be considered active.
809 * This happens if the device is plugged in or temporarily allowed to make exceptions.
810 * Called by interface impls.
812 private boolean isAppIdleFiltered(String packageName, int appId, int userId,
813 UserUsageStatsService userService, long timeNow, long screenOnTime) {
814 if (packageName == null) return false;
815 // If not enabled at all, of course nobody is ever idle.
816 if (!mAppIdleEnabled) {
819 if (appId < Process.FIRST_APPLICATION_UID) {
820 // System uids never go idle.
823 if (packageName.equals("android")) {
824 // Nor does the framework (which should be redundant with the above, but for MR1 we will
825 // retain this for safety).
829 // We allow all whitelisted apps, including those that don't want to be whitelisted
830 // for idle mode, because app idle (aka app standby) is really not as big an issue
831 // for controlling who participates vs. doze mode.
832 if (mDeviceIdleController.isPowerSaveWhitelistExceptIdleApp(packageName)) {
835 } catch (RemoteException re) {
837 // TODO: Optimize this check
838 if (isActiveDeviceAdmin(packageName, userId)) {
842 if (isCarrierApp(packageName)) {
846 if (isActiveNetworkScorer(packageName)) {
850 if (mAppWidgetManager != null
851 && mAppWidgetManager.isBoundWidgetPackage(packageName, userId)) {
855 return isAppIdleUnfiltered(packageName, userService, timeNow, screenOnTime);
858 int[] getIdleUidsForUser(int userId) {
859 if (!mAppIdleEnabled) {
864 final UserUsageStatsService userService;
865 final long screenOnTime;
866 synchronized (mLock) {
867 timeNow = checkAndGetTimeLocked();
868 userService = getUserDataAndInitializeIfNeededLocked(userId, timeNow);
869 screenOnTime = getScreenOnTimeLocked();
872 List<ApplicationInfo> apps;
874 ParceledListSlice<ApplicationInfo> slice = AppGlobals.getPackageManager()
875 .getInstalledApplications(PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
879 apps = slice.getList();
880 } catch (RemoteException e) {
884 // State of each uid. Key is the uid. Value lower 16 bits is the number of apps
885 // associated with that uid, upper 16 bits is the number of those apps that is idle.
886 SparseIntArray uidStates = new SparseIntArray();
888 // Now resolve all app state. Iterating over all apps, keeping track of how many
889 // we find for each uid and how many of those are idle.
890 for (int i = apps.size()-1; i >= 0; i--) {
891 ApplicationInfo ai = apps.get(i);
893 // Check whether this app is idle.
894 boolean idle = isAppIdleFiltered(ai.packageName, UserHandle.getAppId(ai.uid),
895 userId, userService, timeNow, screenOnTime);
897 int index = uidStates.indexOfKey(ai.uid);
899 uidStates.put(ai.uid, 1 + (idle ? 1<<16 : 0));
901 int value = uidStates.valueAt(index);
902 uidStates.setValueAt(index, value + 1 + (idle ? 1<<16 : 0));
907 for (int i = uidStates.size() - 1; i >= 0; i--) {
908 int value = uidStates.valueAt(i);
909 if ((value&0x7fff) == (value>>16)) {
914 int[] res = new int[numIdle];
916 for (int i = uidStates.size() - 1; i >= 0; i--) {
917 int value = uidStates.valueAt(i);
918 if ((value&0x7fff) == (value>>16)) {
919 res[numIdle] = uidStates.keyAt(i);
927 void setAppIdle(String packageName, boolean idle, int userId) {
928 if (packageName == null) return;
930 mHandler.obtainMessage(MSG_FORCE_IDLE_STATE, userId, idle ? 1 : 0, packageName)
934 private boolean isActiveDeviceAdmin(String packageName, int userId) {
935 DevicePolicyManager dpm = getContext().getSystemService(DevicePolicyManager.class);
936 if (dpm == null) return false;
937 List<ComponentName> components = dpm.getActiveAdminsAsUser(userId);
938 if (components == null) return false;
939 final int size = components.size();
940 for (int i = 0; i < size; i++) {
941 if (components.get(i).getPackageName().equals(packageName)) {
948 private boolean isCarrierApp(String packageName) {
949 TelephonyManager telephonyManager = getContext().getSystemService(TelephonyManager.class);
950 return telephonyManager.checkCarrierPrivilegesForPackageAnyPhone(packageName)
951 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
954 private boolean isActiveNetworkScorer(String packageName) {
955 NetworkScoreManager nsm = (NetworkScoreManager) getContext().getSystemService(
956 Context.NETWORK_SCORE_SERVICE);
957 return packageName != null && packageName.equals(nsm.getActiveScorerPackage());
960 void informListeners(String packageName, int userId, boolean isIdle) {
961 for (AppIdleStateChangeListener listener : mPackageAccessListeners) {
962 listener.onAppIdleStateChanged(packageName, userId, isIdle);
966 void informParoleStateChanged() {
967 for (AppIdleStateChangeListener listener : mPackageAccessListeners) {
968 listener.onParoleStateChanged(mAppIdleParoled);
972 private static boolean validRange(long currentTime, long beginTime, long endTime) {
973 return beginTime <= currentTime && beginTime < endTime;
976 private void flushToDiskLocked() {
977 final int userCount = mUserState.size();
978 for (int i = 0; i < userCount; i++) {
979 UserUsageStatsService service = mUserState.valueAt(i);
980 service.persistActiveStats();
983 mHandler.removeMessages(MSG_FLUSH_TO_DISK);
987 * Called by the Binder stub.
989 void dump(String[] args, PrintWriter pw) {
990 synchronized (mLock) {
991 final long screenOnTime = getScreenOnTimeLocked();
992 IndentingPrintWriter idpw = new IndentingPrintWriter(pw, " ");
993 ArraySet<String> argSet = new ArraySet<>();
994 argSet.addAll(Arrays.asList(args));
996 final int userCount = mUserState.size();
997 for (int i = 0; i < userCount; i++) {
998 idpw.printPair("user", mUserState.keyAt(i));
1000 idpw.increaseIndent();
1001 if (argSet.contains("--checkin")) {
1002 mUserState.valueAt(i).checkin(idpw, screenOnTime);
1004 mUserState.valueAt(i).dump(idpw, screenOnTime);
1006 if (args.length > 0 && "history".equals(args[0])) {
1007 mAppIdleHistory.dump(idpw, mUserState.keyAt(i));
1010 idpw.decreaseIndent();
1012 pw.print("Screen On Timebase: ");
1013 pw.print(screenOnTime);
1015 TimeUtils.formatDuration(screenOnTime, pw);
1019 pw.println("Settings:");
1021 pw.print(" mAppIdleDurationMillis=");
1022 TimeUtils.formatDuration(mAppIdleDurationMillis, pw);
1025 pw.print(" mAppIdleWallclockThresholdMillis=");
1026 TimeUtils.formatDuration(mAppIdleWallclockThresholdMillis, pw);
1029 pw.print(" mCheckIdleIntervalMillis=");
1030 TimeUtils.formatDuration(mCheckIdleIntervalMillis, pw);
1033 pw.print(" mAppIdleParoleIntervalMillis=");
1034 TimeUtils.formatDuration(mAppIdleParoleIntervalMillis, pw);
1037 pw.print(" mAppIdleParoleDurationMillis=");
1038 TimeUtils.formatDuration(mAppIdleParoleDurationMillis, pw);
1042 pw.print("mAppIdleEnabled="); pw.print(mAppIdleEnabled);
1043 pw.print(" mAppIdleParoled="); pw.print(mAppIdleParoled);
1044 pw.print(" mScreenOn="); pw.println(mScreenOn);
1045 pw.print("mLastAppIdleParoledTime=");
1046 TimeUtils.formatDuration(mLastAppIdleParoledTime, pw);
1048 pw.print("mScreenOnTime="); TimeUtils.formatDuration(mScreenOnTime, pw);
1050 pw.print("mLastScreenOnEventRealtime=");
1051 TimeUtils.formatDuration(mLastScreenOnEventRealtime, pw);
1056 class H extends Handler {
1057 public H(Looper looper) {
1062 public void handleMessage(Message msg) {
1064 case MSG_REPORT_EVENT:
1065 reportEvent((UsageEvents.Event) msg.obj, msg.arg1);
1068 case MSG_FLUSH_TO_DISK:
1072 case MSG_REMOVE_USER:
1073 removeUser(msg.arg1);
1076 case MSG_INFORM_LISTENERS:
1077 informListeners((String) msg.obj, msg.arg1, msg.arg2 == 1);
1080 case MSG_FORCE_IDLE_STATE:
1081 forceIdleState((String) msg.obj, msg.arg1, msg.arg2 == 1);
1084 case MSG_CHECK_IDLE_STATES:
1085 checkIdleStates(msg.arg1);
1086 mHandler.sendMessageDelayed(mHandler.obtainMessage(
1087 MSG_CHECK_IDLE_STATES, msg.arg1, 0),
1088 mCheckIdleIntervalMillis);
1091 case MSG_ONE_TIME_CHECK_IDLE_STATES:
1092 mHandler.removeMessages(MSG_ONE_TIME_CHECK_IDLE_STATES);
1093 checkIdleStates(UserHandle.USER_ALL);
1096 case MSG_CHECK_PAROLE_TIMEOUT:
1097 checkParoleTimeout();
1100 case MSG_PAROLE_END_TIMEOUT:
1101 if (DEBUG) Slog.d(TAG, "Ending parole");
1102 setAppIdleParoled(false);
1105 case MSG_REPORT_CONTENT_PROVIDER_USAGE:
1106 SomeArgs args = (SomeArgs) msg.obj;
1107 reportContentProviderUsage((String) args.arg1, // authority name
1108 (String) args.arg2, // package name
1109 (int) args.arg3); // userId
1113 case MSG_PAROLE_STATE_CHANGED:
1114 if (DEBUG) Slog.d(TAG, "Parole state changed: " + mAppIdleParoled);
1115 informParoleStateChanged();
1119 super.handleMessage(msg);
1126 * Observe settings changes for {@link Settings.Global#APP_IDLE_CONSTANTS}.
1128 private class SettingsObserver extends ContentObserver {
1130 * This flag has been used to disable app idle on older builds with bug b/26355386.
1133 private static final String KEY_IDLE_DURATION_OLD = "idle_duration";
1135 private static final String KEY_IDLE_DURATION = "idle_duration2";
1136 private static final String KEY_WALLCLOCK_THRESHOLD = "wallclock_threshold";
1137 private static final String KEY_PAROLE_INTERVAL = "parole_interval";
1138 private static final String KEY_PAROLE_DURATION = "parole_duration";
1140 private final KeyValueListParser mParser = new KeyValueListParser(',');
1142 SettingsObserver(Handler handler) {
1146 void registerObserver() {
1147 getContext().getContentResolver().registerContentObserver(Settings.Global.getUriFor(
1148 Settings.Global.APP_IDLE_CONSTANTS), false, this);
1152 public void onChange(boolean selfChange) {
1154 postOneTimeCheckIdleStates();
1157 void updateSettings() {
1158 synchronized (mLock) {
1159 // Look at global settings for this.
1160 // TODO: Maybe apply different thresholds for different users.
1162 mParser.setString(Settings.Global.getString(getContext().getContentResolver(),
1163 Settings.Global.APP_IDLE_CONSTANTS));
1164 } catch (IllegalArgumentException e) {
1165 Slog.e(TAG, "Bad value for app idle settings: " + e.getMessage());
1166 // fallthrough, mParser is empty and all defaults will be returned.
1169 // Default: 12 hours of screen-on time sans dream-time
1170 mAppIdleDurationMillis = mParser.getLong(KEY_IDLE_DURATION,
1171 COMPRESS_TIME ? ONE_MINUTE * 4 : 12 * 60 * ONE_MINUTE);
1173 mAppIdleWallclockThresholdMillis = mParser.getLong(KEY_WALLCLOCK_THRESHOLD,
1174 COMPRESS_TIME ? ONE_MINUTE * 8 : 2L * 24 * 60 * ONE_MINUTE); // 2 days
1176 mCheckIdleIntervalMillis = Math.min(mAppIdleDurationMillis / 4,
1177 COMPRESS_TIME ? ONE_MINUTE : 8 * 60 * ONE_MINUTE); // 8 hours
1179 // Default: 24 hours between paroles
1180 mAppIdleParoleIntervalMillis = mParser.getLong(KEY_PAROLE_INTERVAL,
1181 COMPRESS_TIME ? ONE_MINUTE * 10 : 24 * 60 * ONE_MINUTE);
1183 mAppIdleParoleDurationMillis = mParser.getLong(KEY_PAROLE_DURATION,
1184 COMPRESS_TIME ? ONE_MINUTE : 10 * ONE_MINUTE); // 10 minutes
1189 private final class BinderService extends IUsageStatsManager.Stub {
1191 private boolean hasPermission(String callingPackage) {
1192 final int callingUid = Binder.getCallingUid();
1193 if (callingUid == Process.SYSTEM_UID) {
1196 final int mode = mAppOps.checkOp(AppOpsManager.OP_GET_USAGE_STATS,
1197 callingUid, callingPackage);
1198 if (mode == AppOpsManager.MODE_DEFAULT) {
1199 // The default behavior here is to check if PackageManager has given the app
1201 return getContext().checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
1202 == PackageManager.PERMISSION_GRANTED;
1204 return mode == AppOpsManager.MODE_ALLOWED;
1208 public ParceledListSlice<UsageStats> queryUsageStats(int bucketType, long beginTime,
1209 long endTime, String callingPackage) {
1210 if (!hasPermission(callingPackage)) {
1214 final int userId = UserHandle.getCallingUserId();
1215 final long token = Binder.clearCallingIdentity();
1217 final List<UsageStats> results = UsageStatsService.this.queryUsageStats(
1218 userId, bucketType, beginTime, endTime);
1219 if (results != null) {
1220 return new ParceledListSlice<>(results);
1223 Binder.restoreCallingIdentity(token);
1229 public ParceledListSlice<ConfigurationStats> queryConfigurationStats(int bucketType,
1230 long beginTime, long endTime, String callingPackage) throws RemoteException {
1231 if (!hasPermission(callingPackage)) {
1235 final int userId = UserHandle.getCallingUserId();
1236 final long token = Binder.clearCallingIdentity();
1238 final List<ConfigurationStats> results =
1239 UsageStatsService.this.queryConfigurationStats(userId, bucketType,
1240 beginTime, endTime);
1241 if (results != null) {
1242 return new ParceledListSlice<>(results);
1245 Binder.restoreCallingIdentity(token);
1251 public UsageEvents queryEvents(long beginTime, long endTime, String callingPackage) {
1252 if (!hasPermission(callingPackage)) {
1256 final int userId = UserHandle.getCallingUserId();
1257 final long token = Binder.clearCallingIdentity();
1259 return UsageStatsService.this.queryEvents(userId, beginTime, endTime);
1261 Binder.restoreCallingIdentity(token);
1266 public boolean isAppInactive(String packageName, int userId) {
1268 userId = ActivityManagerNative.getDefault().handleIncomingUser(Binder.getCallingPid(),
1269 Binder.getCallingUid(), userId, false, true, "isAppInactive", null);
1270 } catch (RemoteException re) {
1273 final long token = Binder.clearCallingIdentity();
1275 return UsageStatsService.this.isAppIdleFilteredOrParoled(packageName, userId, -1);
1277 Binder.restoreCallingIdentity(token);
1282 public void setAppInactive(String packageName, boolean idle, int userId) {
1283 final int callingUid = Binder.getCallingUid();
1285 userId = ActivityManagerNative.getDefault().handleIncomingUser(
1286 Binder.getCallingPid(), callingUid, userId, false, true,
1287 "setAppIdle", null);
1288 } catch (RemoteException re) {
1291 getContext().enforceCallingPermission(Manifest.permission.CHANGE_APP_IDLE_STATE,
1292 "No permission to change app idle state");
1293 final long token = Binder.clearCallingIdentity();
1295 PackageInfo pi = AppGlobals.getPackageManager().getPackageInfo(packageName,
1296 PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
1297 if (pi == null) return;
1298 UsageStatsService.this.setAppIdle(packageName, idle, userId);
1299 } catch (RemoteException re) {
1301 Binder.restoreCallingIdentity(token);
1306 public void whitelistAppTemporarily(String packageName, long duration, int userId)
1307 throws RemoteException {
1308 StringBuilder reason = new StringBuilder(32);
1309 reason.append("from:");
1310 UserHandle.formatUid(reason, Binder.getCallingUid());
1311 mDeviceIdleController.addPowerSaveTempWhitelistApp(packageName, duration, userId,
1316 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1317 if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
1318 != PackageManager.PERMISSION_GRANTED) {
1319 pw.println("Permission Denial: can't dump UsageStats from pid="
1320 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1321 + " without permission " + android.Manifest.permission.DUMP);
1324 UsageStatsService.this.dump(args, pw);
1331 * This local service implementation is primarily used by ActivityManagerService.
1332 * ActivityManagerService will call these methods holding the 'am' lock, which means we
1333 * shouldn't be doing any IO work or other long running tasks in these methods.
1335 private final class LocalService extends UsageStatsManagerInternal {
1338 public void reportEvent(ComponentName component, int userId, int eventType) {
1339 if (component == null) {
1340 Slog.w(TAG, "Event reported without a component name");
1344 UsageEvents.Event event = new UsageEvents.Event();
1345 event.mPackage = component.getPackageName();
1346 event.mClass = component.getClassName();
1348 // This will later be converted to system time.
1349 event.mTimeStamp = SystemClock.elapsedRealtime();
1351 event.mEventType = eventType;
1352 mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget();
1356 public void reportEvent(String packageName, int userId, int eventType) {
1357 if (packageName == null) {
1358 Slog.w(TAG, "Event reported without a package name");
1362 UsageEvents.Event event = new UsageEvents.Event();
1363 event.mPackage = packageName;
1365 // This will later be converted to system time.
1366 event.mTimeStamp = SystemClock.elapsedRealtime();
1368 event.mEventType = eventType;
1369 mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget();
1373 public void reportConfigurationChange(Configuration config, int userId) {
1374 if (config == null) {
1375 Slog.w(TAG, "Configuration event reported with a null config");
1379 UsageEvents.Event event = new UsageEvents.Event();
1380 event.mPackage = "android";
1382 // This will later be converted to system time.
1383 event.mTimeStamp = SystemClock.elapsedRealtime();
1385 event.mEventType = UsageEvents.Event.CONFIGURATION_CHANGE;
1386 event.mConfiguration = new Configuration(config);
1387 mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget();
1391 public void reportContentProviderUsage(String name, String packageName, int userId) {
1392 SomeArgs args = SomeArgs.obtain();
1394 args.arg2 = packageName;
1396 mHandler.obtainMessage(MSG_REPORT_CONTENT_PROVIDER_USAGE, args)
1401 public boolean isAppIdle(String packageName, int uidForAppId, int userId) {
1402 return UsageStatsService.this.isAppIdleFiltered(packageName, uidForAppId, userId, -1);
1406 public int[] getIdleUidsForUser(int userId) {
1407 return UsageStatsService.this.getIdleUidsForUser(userId);
1411 public boolean isAppIdleParoleOn() {
1412 return mAppIdleParoled;
1416 public void prepareShutdown() {
1417 // This method *WILL* do IO work, but we must block until it is finished or else
1418 // we might not shutdown cleanly. This is ok to do with the 'am' lock held, because
1419 // we are shutting down.
1424 public void addAppIdleStateChangeListener(AppIdleStateChangeListener listener) {
1425 UsageStatsService.this.addListener(listener);
1426 listener.onParoleStateChanged(isAppIdleParoleOn());
1430 public void removeAppIdleStateChangeListener(
1431 AppIdleStateChangeListener listener) {
1432 UsageStatsService.this.removeListener(listener);
1436 public byte[] getBackupPayload(int user, String key) {
1437 // Check to ensure that only user 0's data is b/r for now
1438 if (user == UserHandle.USER_SYSTEM) {
1439 final UserUsageStatsService userStats =
1440 getUserDataAndInitializeIfNeededLocked(user, checkAndGetTimeLocked());
1441 return userStats.getBackupPayload(key);
1448 public void applyRestoredPayload(int user, String key, byte[] payload) {
1449 if (user == UserHandle.USER_SYSTEM) {
1450 final UserUsageStatsService userStats =
1451 getUserDataAndInitializeIfNeededLocked(user, checkAndGetTimeLocked());
1452 userStats.applyRestoredPayload(key, payload);