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