OSDN Git Service

Merge commit '5142a2d5b3f70c2017792ce04d3f254221ab3d21' into manual_merge_5142a2d5b3
[android-x86/frameworks-base.git] / services / usage / java / com / android / server / usage / UsageStatsService.java
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.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;
72
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;
79
80 import java.io.BufferedReader;
81 import java.io.File;
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;
90
91 /**
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.
94  */
95 public class UsageStatsService extends SystemService implements
96         UserUsageStatsService.StatsUpdatedListener {
97
98     static final String TAG = "UsageStatsService";
99
100     static final boolean DEBUG = false;
101     static final boolean COMPRESS_TIME = false;
102
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.
108
109     long mAppIdleDurationMillis;
110     long mCheckIdleIntervalMillis;
111     long mAppIdleWallclockThresholdMillis;
112     long mAppIdleParoleIntervalMillis;
113     long mAppIdleParoleDurationMillis;
114
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;
127
128     private final Object mLock = new Object();
129     Handler mHandler;
130     AppOpsManager mAppOps;
131     UserManager mUserManager;
132     AppWidgetManager mAppWidgetManager;
133     IDeviceIdleController mDeviceIdleController;
134     private DisplayManager mDisplayManager;
135     private PowerManager mPowerManager;
136     private IBatteryStats mBatteryStats;
137
138     private final SparseArray<UserUsageStatsService> mUserState = new SparseArray<>();
139     private File mUsageStatsDir;
140     long mRealTimeSnapshot;
141     long mSystemTimeSnapshot;
142
143     boolean mAppIdleEnabled;
144     boolean mAppIdleParoled;
145     private boolean mScreenOn;
146     private long mLastAppIdleParoledTime;
147
148     long mScreenOnTime;
149     long mLastScreenOnEventRealtime;
150
151     @GuardedBy("mLock")
152     private AppIdleHistory mAppIdleHistory = new AppIdleHistory();
153
154     private ArrayList<UsageStatsManagerInternal.AppIdleStateChangeListener>
155             mPackageAccessListeners = new ArrayList<>();
156
157     public UsageStatsService(Context context) {
158         super(context);
159     }
160
161     @Override
162     public void onStart() {
163         mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE);
164         mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE);
165
166         mHandler = new H(BackgroundThread.get().getLooper());
167
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());
174         }
175
176         IntentFilter userActions = new IntentFilter(Intent.ACTION_USER_REMOVED);
177         userActions.addAction(Intent.ACTION_USER_STARTED);
178         getContext().registerReceiverAsUser(new UserActionsReceiver(), UserHandle.ALL, userActions,
179                 null, null);
180
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);
188         }
189
190         synchronized (mLock) {
191             cleanUpRemovedUsersLocked();
192             mLastScreenOnEventRealtime = SystemClock.elapsedRealtime();
193             mScreenOnTime = readScreenOnTimeLocked();
194         }
195
196         mRealTimeSnapshot = SystemClock.elapsedRealtime();
197         mSystemTimeSnapshot = System.currentTimeMillis();
198
199         publishLocalService(UsageStatsManagerInternal.class, new LocalService());
200         publishBinderService(Context.USAGE_STATS_SERVICE, new BinderService());
201     }
202
203     @Override
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();
210
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);
219
220             mDisplayManager.registerDisplayListener(mDisplayListener, mHandler);
221             synchronized (mLock) {
222                 updateDisplayLocked();
223             }
224         } else if (phase == PHASE_BOOT_COMPLETED) {
225             setAppIdleParoled(getContext().getSystemService(BatteryManager.class).isCharging());
226         }
227     }
228
229     private class UserActionsReceiver extends BroadcastReceiver {
230
231         @Override
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())) {
235                 if (userId >= 0) {
236                     mHandler.obtainMessage(MSG_REMOVE_USER, userId, 0).sendToTarget();
237                 }
238             } else if (Intent.ACTION_USER_STARTED.equals(intent.getAction())) {
239                 if (userId >=0) {
240                     postCheckIdleStates(userId);
241                 }
242             }
243         }
244     }
245
246     private class DeviceStateReceiver extends BroadcastReceiver {
247         @Override
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();
255             }
256         }
257     }
258
259     private final DisplayManager.DisplayListener mDisplayListener
260             = new DisplayManager.DisplayListener() {
261
262         @Override public void onDisplayAdded(int displayId) {
263         }
264
265         @Override public void onDisplayRemoved(int displayId) {
266         }
267
268         @Override public void onDisplayChanged(int displayId) {
269             if (displayId == Display.DEFAULT_DISPLAY) {
270                 synchronized (UsageStatsService.this.mLock) {
271                     updateDisplayLocked();
272                 }
273             }
274         }
275     };
276
277     @Override
278     public void onStatsUpdated() {
279         mHandler.sendEmptyMessageDelayed(MSG_FLUSH_TO_DISK, FLUSH_INTERVAL);
280     }
281
282     @Override
283     public void onStatsReloaded() {
284         postOneTimeCheckIdleStates();
285     }
286
287     @Override
288     public long getAppIdleRollingWindowDurationMillis() {
289         return mAppIdleWallclockThresholdMillis * 2;
290     }
291
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");
296         }
297
298         ArraySet<String> toDelete = new ArraySet<>();
299         String[] fileNames = mUsageStatsDir.list();
300         if (fileNames == null) {
301             // No users to delete.
302             return;
303         }
304
305         toDelete.addAll(Arrays.asList(fileNames));
306
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));
311         }
312
313         final int deleteCount = toDelete.size();
314         for (int i = 0; i < deleteCount; i++) {
315             deleteRecursively(new File(mUsageStatsDir, toDelete.valueAt(i)));
316         }
317     }
318
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);
325                 if (paroled) {
326                     postParoleEndTimeout();
327                 } else {
328                     mLastAppIdleParoledTime = checkAndGetTimeLocked();
329                     postNextParoleTimeout();
330                 }
331                 postParoleStateChanged();
332             }
333         }
334     }
335
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();
344         if (timeLeft < 0) {
345             timeLeft = 0;
346         }
347         mHandler.sendEmptyMessageDelayed(MSG_CHECK_PAROLE_TIMEOUT, timeLeft / 10);
348     }
349
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);
354     }
355
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);
360     }
361
362     void postCheckIdleStates(int userId) {
363         mHandler.sendMessage(mHandler.obtainMessage(MSG_CHECK_IDLE_STATES, userId, 0));
364     }
365
366     /**
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.
369      */
370     void postOneTimeCheckIdleStates() {
371         mHandler.sendEmptyMessage(MSG_ONE_TIME_CHECK_IDLE_STATES);
372     }
373
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) {
377             return;
378         }
379
380         final int[] userIds;
381         try {
382             if (checkUserId == UserHandle.USER_ALL) {
383                 userIds = ActivityManagerNative.getDefault().getRunningUserIds();
384             } else {
385                 userIds = new int[] { checkUserId };
386             }
387         } catch (RemoteException re) {
388             return;
389         }
390
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,
397                             userId);
398             synchronized (mLock) {
399                 final long timeNow = checkAndGetTimeLocked();
400                 final long screenOnTime = getScreenOnTimeLocked();
401                 UserUsageStatsService service = getUserDataAndInitializeIfNeededLocked(userId,
402                         timeNow);
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);
413                 }
414             }
415         }
416     }
417
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);
426                 } else {
427                     if (DEBUG) Slog.d(TAG, "Not long enough to go to parole");
428                     postNextParoleTimeout();
429                 }
430             }
431         }
432     }
433
434     private void notifyBatteryStats(String packageName, int userId, boolean idle) {
435         try {
436             final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
437                     PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
438             if (idle) {
439                 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_PACKAGE_INACTIVE,
440                         packageName, uid);
441             } else {
442                 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_PACKAGE_ACTIVE,
443                         packageName, uid);
444             }
445         } catch (RemoteException re) {
446         }
447     }
448
449     void updateDisplayLocked() {
450         boolean screenOn = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY).getState()
451                 == Display.STATE_ON;
452
453         if (screenOn == mScreenOn) return;
454
455         mScreenOn = screenOn;
456         long now = SystemClock.elapsedRealtime();
457         if (mScreenOn) {
458             mLastScreenOnEventRealtime = now;
459         } else {
460             mScreenOnTime += now - mLastScreenOnEventRealtime;
461             writeScreenOnTimeLocked(mScreenOnTime);
462         }
463     }
464
465     long getScreenOnTimeLocked() {
466         long screenOnTime = mScreenOnTime;
467         if (mScreenOn) {
468             screenOnTime += SystemClock.elapsedRealtime() - mLastScreenOnEventRealtime;
469         }
470         return screenOnTime;
471     }
472
473     private File getScreenOnTimeFile() {
474         return new File(mUsageStatsDir, UserHandle.USER_SYSTEM + "/screen_on_time");
475     }
476
477     private long readScreenOnTimeLocked() {
478         long screenOnTime = 0;
479         File screenOnTimeFile = getScreenOnTimeFile();
480         if (screenOnTimeFile.exists()) {
481             try {
482                 BufferedReader reader = new BufferedReader(new FileReader(screenOnTimeFile));
483                 screenOnTime = Long.parseLong(reader.readLine());
484                 reader.close();
485             } catch (IOException | NumberFormatException e) {
486             }
487         } else {
488             writeScreenOnTimeLocked(screenOnTime);
489         }
490         return screenOnTime;
491     }
492
493     private void writeScreenOnTimeLocked(long screenOnTime) {
494         AtomicFile screenOnTimeFile = new AtomicFile(getScreenOnTimeFile());
495         FileOutputStream fos = null;
496         try {
497             fos = screenOnTimeFile.startWrite();
498             fos.write(Long.toString(screenOnTime).getBytes());
499             screenOnTimeFile.finishWrite(fos);
500         } catch (IOException ioe) {
501             screenOnTimeFile.failWrite(fos);
502         }
503     }
504
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;
510             if (!deviceIdle
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);
517             }
518         }
519     }
520
521     private static void deleteRecursively(File f) {
522         File[] files = f.listFiles();
523         if (files != null) {
524             for (File subFile : files) {
525                 deleteRecursively(subFile);
526             }
527         }
528
529         if (!f.delete()) {
530             Slog.e(TAG, "Failed to delete " + f);
531         }
532     }
533
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);
542         }
543         return service;
544     }
545
546     /**
547      * This should be the only way to get the time from the system.
548      */
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(),
561                         false);
562             }
563             mRealTimeSnapshot = actualRealtime;
564             mSystemTimeSnapshot = actualSystemTime;
565         }
566         return actualSystemTime;
567     }
568
569     /**
570      * Assuming the event's timestamp is measured in milliseconds since boot,
571      * convert it to a system wall time.
572      */
573     private void convertToSystemTimeLocked(UsageEvents.Event event) {
574         event.mTimeStamp = Math.max(0, event.mTimeStamp - mRealTimeSnapshot) + mSystemTimeSnapshot;
575     }
576
577     /**
578      * Called by the Binder stub
579      */
580     void shutdown() {
581         synchronized (mLock) {
582             mHandler.removeMessages(MSG_REPORT_EVENT);
583             flushToDiskLocked();
584         }
585     }
586
587     /**
588      * Called by the Binder stub.
589      */
590     void reportEvent(UsageEvents.Event event, int userId) {
591         synchronized (mLock) {
592             final long timeNow = checkAndGetTimeLocked();
593             final long screenOnTime = getScreenOnTimeLocked();
594             convertToSystemTimeLocked(event);
595
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);
613                 }
614             }
615         }
616     }
617
618     void reportContentProviderUsage(String authority, String providerPkgName, int userId) {
619         // Get sync adapters for the authority
620         String[] packages = ContentResolver.getSyncAdapterPackagesForAuthorityAsUser(
621                 authority, userId);
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.
625             try {
626                 PackageInfo pi = AppGlobals.getPackageManager().getPackageInfo(
627                         packageName, PackageManager.MATCH_SYSTEM_ONLY, userId);
628                 if (pi == null || pi.applicationInfo == null) {
629                     continue;
630                 }
631                 if (!packageName.equals(providerPkgName)) {
632                     forceIdleState(packageName, userId, false);
633                 }
634             } catch (RemoteException re) {
635                 // Shouldn't happen
636             }
637         }
638     }
639
640     /**
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.
644      */
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;
650
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));
664                 if (!idle) {
665                     notifyBatteryStats(packageName, userId, idle);
666                 }
667                 mAppIdleHistory.addEntry(packageName, userId, idle, timeNow);
668             }
669         }
670     }
671
672     /**
673      * Called by the Binder stub.
674      */
675     void flushToDisk() {
676         synchronized (mLock) {
677             flushToDiskLocked();
678         }
679     }
680
681     /**
682      * Called by the Binder stub.
683      */
684     void removeUser(int userId) {
685         synchronized (mLock) {
686             Slog.i(TAG, "Removing user " + userId + " and all data.");
687             mUserState.remove(userId);
688             cleanUpRemovedUsersLocked();
689         }
690     }
691
692     /**
693      * Called by the Binder stub.
694      */
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)) {
699                 return null;
700             }
701
702             final UserUsageStatsService service =
703                     getUserDataAndInitializeIfNeededLocked(userId, timeNow);
704             return service.queryUsageStats(bucketType, beginTime, endTime);
705         }
706     }
707
708     /**
709      * Called by the Binder stub.
710      */
711     List<ConfigurationStats> queryConfigurationStats(int userId, int bucketType, long beginTime,
712             long endTime) {
713         synchronized (mLock) {
714             final long timeNow = checkAndGetTimeLocked();
715             if (!validRange(timeNow, beginTime, endTime)) {
716                 return null;
717             }
718
719             final UserUsageStatsService service =
720                     getUserDataAndInitializeIfNeededLocked(userId, timeNow);
721             return service.queryConfigurationStats(bucketType, beginTime, endTime);
722         }
723     }
724
725     /**
726      * Called by the Binder stub.
727      */
728     UsageEvents queryEvents(int userId, long beginTime, long endTime) {
729         synchronized (mLock) {
730             final long timeNow = checkAndGetTimeLocked();
731             if (!validRange(timeNow, beginTime, endTime)) {
732                 return null;
733             }
734
735             final UserUsageStatsService service =
736                     getUserDataAndInitializeIfNeededLocked(userId, timeNow);
737             return service.queryEvents(beginTime, endTime);
738         }
739     }
740
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,
747                     timeNow);
748         }
749     }
750
751     /**
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
757      */
758     boolean hasPassedIdleTimeoutLocked(long beginIdleTime, long lastUsedTime,
759             long screenOnTime, long currentTime) {
760         return (beginIdleTime <= screenOnTime - mAppIdleDurationMillis)
761                 && (lastUsedTime <= currentTime - mAppIdleWallclockThresholdMillis);
762     }
763
764     void addListener(AppIdleStateChangeListener listener) {
765         synchronized (mLock) {
766             if (!mPackageAccessListeners.contains(listener)) {
767                 mPackageAccessListeners.add(listener);
768             }
769         }
770     }
771
772     void removeListener(AppIdleStateChangeListener listener) {
773         synchronized (mLock) {
774             mPackageAccessListeners.remove(listener);
775         }
776     }
777
778     boolean isAppIdleFilteredOrParoled(String packageName, int userId, long timeNow) {
779         if (mAppIdleParoled) {
780             return false;
781         }
782         try {
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) {
788         }
789         return false;
790     }
791
792     boolean isAppIdleFiltered(String packageName, int uidForAppId, int userId, long timeNow) {
793         final UserUsageStatsService userService;
794         final long screenOnTime;
795         synchronized (mLock) {
796             if (timeNow == -1) {
797                 timeNow = checkAndGetTimeLocked();
798             }
799             userService = getUserDataAndInitializeIfNeededLocked(userId, timeNow);
800             screenOnTime = getScreenOnTimeLocked();
801         }
802         return isAppIdleFiltered(packageName, UserHandle.getAppId(uidForAppId), userId,
803                 userService, timeNow, screenOnTime);
804     }
805
806     /**
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.
811      */
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) {
817             return false;
818         }
819         if (appId < Process.FIRST_APPLICATION_UID) {
820             // System uids never go idle.
821             return false;
822         }
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).
826             return false;
827         }
828         try {
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)) {
833                 return false;
834             }
835         } catch (RemoteException re) {
836         }
837         // TODO: Optimize this check
838         if (isActiveDeviceAdmin(packageName, userId)) {
839             return false;
840         }
841
842         if (isCarrierApp(packageName)) {
843             return false;
844         }
845
846         if (isActiveNetworkScorer(packageName)) {
847             return false;
848         }
849
850         if (mAppWidgetManager != null
851                 && mAppWidgetManager.isBoundWidgetPackage(packageName, userId)) {
852             return false;
853         }
854
855         return isAppIdleUnfiltered(packageName, userService, timeNow, screenOnTime);
856     }
857
858     int[] getIdleUidsForUser(int userId) {
859         if (!mAppIdleEnabled) {
860             return new int[0];
861         }
862
863         final long timeNow;
864         final UserUsageStatsService userService;
865         final long screenOnTime;
866         synchronized (mLock) {
867             timeNow = checkAndGetTimeLocked();
868             userService = getUserDataAndInitializeIfNeededLocked(userId, timeNow);
869             screenOnTime = getScreenOnTimeLocked();
870         }
871
872         List<ApplicationInfo> apps;
873         try {
874             ParceledListSlice<ApplicationInfo> slice = AppGlobals.getPackageManager()
875                     .getInstalledApplications(PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
876             if (slice == null) {
877                 return new int[0];
878             }
879             apps = slice.getList();
880         } catch (RemoteException e) {
881             return new int[0];
882         }
883
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();
887
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);
892
893             // Check whether this app is idle.
894             boolean idle = isAppIdleFiltered(ai.packageName, UserHandle.getAppId(ai.uid),
895                     userId, userService, timeNow, screenOnTime);
896
897             int index = uidStates.indexOfKey(ai.uid);
898             if (index < 0) {
899                 uidStates.put(ai.uid, 1 + (idle ? 1<<16 : 0));
900             } else {
901                 int value = uidStates.valueAt(index);
902                 uidStates.setValueAt(index, value + 1 + (idle ? 1<<16 : 0));
903             }
904         }
905
906         int numIdle = 0;
907         for (int i = uidStates.size() - 1; i >= 0; i--) {
908             int value = uidStates.valueAt(i);
909             if ((value&0x7fff) == (value>>16)) {
910                 numIdle++;
911             }
912         }
913
914         int[] res = new int[numIdle];
915         numIdle = 0;
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);
920                 numIdle++;
921             }
922         }
923
924         return res;
925     }
926
927     void setAppIdle(String packageName, boolean idle, int userId) {
928         if (packageName == null) return;
929
930         mHandler.obtainMessage(MSG_FORCE_IDLE_STATE, userId, idle ? 1 : 0, packageName)
931                 .sendToTarget();
932     }
933
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)) {
942                 return true;
943             }
944         }
945         return false;
946     }
947
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;
952     }
953
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());
958     }
959
960     void informListeners(String packageName, int userId, boolean isIdle) {
961         for (AppIdleStateChangeListener listener : mPackageAccessListeners) {
962             listener.onAppIdleStateChanged(packageName, userId, isIdle);
963         }
964     }
965
966     void informParoleStateChanged() {
967         for (AppIdleStateChangeListener listener : mPackageAccessListeners) {
968             listener.onParoleStateChanged(mAppIdleParoled);
969         }
970     }
971
972     private static boolean validRange(long currentTime, long beginTime, long endTime) {
973         return beginTime <= currentTime && beginTime < endTime;
974     }
975
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();
981         }
982
983         mHandler.removeMessages(MSG_FLUSH_TO_DISK);
984     }
985
986     /**
987      * Called by the Binder stub.
988      */
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));
995
996             final int userCount = mUserState.size();
997             for (int i = 0; i < userCount; i++) {
998                 idpw.printPair("user", mUserState.keyAt(i));
999                 idpw.println();
1000                 idpw.increaseIndent();
1001                 if (argSet.contains("--checkin")) {
1002                     mUserState.valueAt(i).checkin(idpw, screenOnTime);
1003                 } else {
1004                     mUserState.valueAt(i).dump(idpw, screenOnTime);
1005                     idpw.println();
1006                     if (args.length > 0 && "history".equals(args[0])) {
1007                         mAppIdleHistory.dump(idpw, mUserState.keyAt(i));
1008                     }
1009                 }
1010                 idpw.decreaseIndent();
1011             }
1012             pw.print("Screen On Timebase: ");
1013             pw.print(screenOnTime);
1014             pw.print(" (");
1015             TimeUtils.formatDuration(screenOnTime, pw);
1016             pw.println(")");
1017
1018             pw.println();
1019             pw.println("Settings:");
1020
1021             pw.print("  mAppIdleDurationMillis=");
1022             TimeUtils.formatDuration(mAppIdleDurationMillis, pw);
1023             pw.println();
1024
1025             pw.print("  mAppIdleWallclockThresholdMillis=");
1026             TimeUtils.formatDuration(mAppIdleWallclockThresholdMillis, pw);
1027             pw.println();
1028
1029             pw.print("  mCheckIdleIntervalMillis=");
1030             TimeUtils.formatDuration(mCheckIdleIntervalMillis, pw);
1031             pw.println();
1032
1033             pw.print("  mAppIdleParoleIntervalMillis=");
1034             TimeUtils.formatDuration(mAppIdleParoleIntervalMillis, pw);
1035             pw.println();
1036
1037             pw.print("  mAppIdleParoleDurationMillis=");
1038             TimeUtils.formatDuration(mAppIdleParoleDurationMillis, pw);
1039             pw.println();
1040
1041             pw.println();
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);
1047             pw.println();
1048             pw.print("mScreenOnTime="); TimeUtils.formatDuration(mScreenOnTime, pw);
1049             pw.println();
1050             pw.print("mLastScreenOnEventRealtime=");
1051             TimeUtils.formatDuration(mLastScreenOnEventRealtime, pw);
1052             pw.println();
1053         }
1054     }
1055
1056     class H extends Handler {
1057         public H(Looper looper) {
1058             super(looper);
1059         }
1060
1061         @Override
1062         public void handleMessage(Message msg) {
1063             switch (msg.what) {
1064                 case MSG_REPORT_EVENT:
1065                     reportEvent((UsageEvents.Event) msg.obj, msg.arg1);
1066                     break;
1067
1068                 case MSG_FLUSH_TO_DISK:
1069                     flushToDisk();
1070                     break;
1071
1072                 case MSG_REMOVE_USER:
1073                     removeUser(msg.arg1);
1074                     break;
1075
1076                 case MSG_INFORM_LISTENERS:
1077                     informListeners((String) msg.obj, msg.arg1, msg.arg2 == 1);
1078                     break;
1079
1080                 case MSG_FORCE_IDLE_STATE:
1081                     forceIdleState((String) msg.obj, msg.arg1, msg.arg2 == 1);
1082                     break;
1083
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);
1089                     break;
1090
1091                 case MSG_ONE_TIME_CHECK_IDLE_STATES:
1092                     mHandler.removeMessages(MSG_ONE_TIME_CHECK_IDLE_STATES);
1093                     checkIdleStates(UserHandle.USER_ALL);
1094                     break;
1095
1096                 case MSG_CHECK_PAROLE_TIMEOUT:
1097                     checkParoleTimeout();
1098                     break;
1099
1100                 case MSG_PAROLE_END_TIMEOUT:
1101                     if (DEBUG) Slog.d(TAG, "Ending parole");
1102                     setAppIdleParoled(false);
1103                     break;
1104
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
1110                     args.recycle();
1111                     break;
1112
1113                 case MSG_PAROLE_STATE_CHANGED:
1114                     if (DEBUG) Slog.d(TAG, "Parole state changed: " + mAppIdleParoled);
1115                     informParoleStateChanged();
1116                     break;
1117
1118                 default:
1119                     super.handleMessage(msg);
1120                     break;
1121             }
1122         }
1123     }
1124
1125     /**
1126      * Observe settings changes for {@link Settings.Global#APP_IDLE_CONSTANTS}.
1127      */
1128     private class SettingsObserver extends ContentObserver {
1129         /**
1130          * This flag has been used to disable app idle on older builds with bug b/26355386.
1131          */
1132         @Deprecated
1133         private static final String KEY_IDLE_DURATION_OLD = "idle_duration";
1134
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";
1139
1140         private final KeyValueListParser mParser = new KeyValueListParser(',');
1141
1142         SettingsObserver(Handler handler) {
1143             super(handler);
1144         }
1145
1146         void registerObserver() {
1147             getContext().getContentResolver().registerContentObserver(Settings.Global.getUriFor(
1148                     Settings.Global.APP_IDLE_CONSTANTS), false, this);
1149         }
1150
1151         @Override
1152         public void onChange(boolean selfChange) {
1153             updateSettings();
1154             postOneTimeCheckIdleStates();
1155         }
1156
1157         void updateSettings() {
1158             synchronized (mLock) {
1159                 // Look at global settings for this.
1160                 // TODO: Maybe apply different thresholds for different users.
1161                 try {
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.
1167                 }
1168
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);
1172
1173                 mAppIdleWallclockThresholdMillis = mParser.getLong(KEY_WALLCLOCK_THRESHOLD,
1174                         COMPRESS_TIME ? ONE_MINUTE * 8 : 2L * 24 * 60 * ONE_MINUTE); // 2 days
1175
1176                 mCheckIdleIntervalMillis = Math.min(mAppIdleDurationMillis / 4,
1177                         COMPRESS_TIME ? ONE_MINUTE : 8 * 60 * ONE_MINUTE); // 8 hours
1178
1179                 // Default: 24 hours between paroles
1180                 mAppIdleParoleIntervalMillis = mParser.getLong(KEY_PAROLE_INTERVAL,
1181                         COMPRESS_TIME ? ONE_MINUTE * 10 : 24 * 60 * ONE_MINUTE);
1182
1183                 mAppIdleParoleDurationMillis = mParser.getLong(KEY_PAROLE_DURATION,
1184                         COMPRESS_TIME ? ONE_MINUTE : 10 * ONE_MINUTE); // 10 minutes
1185             }
1186         }
1187     }
1188
1189     private final class BinderService extends IUsageStatsManager.Stub {
1190
1191         private boolean hasPermission(String callingPackage) {
1192             final int callingUid = Binder.getCallingUid();
1193             if (callingUid == Process.SYSTEM_UID) {
1194                 return true;
1195             }
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
1200                 // permission.
1201                 return getContext().checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
1202                         == PackageManager.PERMISSION_GRANTED;
1203             }
1204             return mode == AppOpsManager.MODE_ALLOWED;
1205         }
1206
1207         @Override
1208         public ParceledListSlice<UsageStats> queryUsageStats(int bucketType, long beginTime,
1209                 long endTime, String callingPackage) {
1210             if (!hasPermission(callingPackage)) {
1211                 return null;
1212             }
1213
1214             final int userId = UserHandle.getCallingUserId();
1215             final long token = Binder.clearCallingIdentity();
1216             try {
1217                 final List<UsageStats> results = UsageStatsService.this.queryUsageStats(
1218                         userId, bucketType, beginTime, endTime);
1219                 if (results != null) {
1220                     return new ParceledListSlice<>(results);
1221                 }
1222             } finally {
1223                 Binder.restoreCallingIdentity(token);
1224             }
1225             return null;
1226         }
1227
1228         @Override
1229         public ParceledListSlice<ConfigurationStats> queryConfigurationStats(int bucketType,
1230                 long beginTime, long endTime, String callingPackage) throws RemoteException {
1231             if (!hasPermission(callingPackage)) {
1232                 return null;
1233             }
1234
1235             final int userId = UserHandle.getCallingUserId();
1236             final long token = Binder.clearCallingIdentity();
1237             try {
1238                 final List<ConfigurationStats> results =
1239                         UsageStatsService.this.queryConfigurationStats(userId, bucketType,
1240                                 beginTime, endTime);
1241                 if (results != null) {
1242                     return new ParceledListSlice<>(results);
1243                 }
1244             } finally {
1245                 Binder.restoreCallingIdentity(token);
1246             }
1247             return null;
1248         }
1249
1250         @Override
1251         public UsageEvents queryEvents(long beginTime, long endTime, String callingPackage) {
1252             if (!hasPermission(callingPackage)) {
1253                 return null;
1254             }
1255
1256             final int userId = UserHandle.getCallingUserId();
1257             final long token = Binder.clearCallingIdentity();
1258             try {
1259                 return UsageStatsService.this.queryEvents(userId, beginTime, endTime);
1260             } finally {
1261                 Binder.restoreCallingIdentity(token);
1262             }
1263         }
1264
1265         @Override
1266         public boolean isAppInactive(String packageName, int userId) {
1267             try {
1268                 userId = ActivityManagerNative.getDefault().handleIncomingUser(Binder.getCallingPid(),
1269                         Binder.getCallingUid(), userId, false, true, "isAppInactive", null);
1270             } catch (RemoteException re) {
1271                 return false;
1272             }
1273             final long token = Binder.clearCallingIdentity();
1274             try {
1275                 return UsageStatsService.this.isAppIdleFilteredOrParoled(packageName, userId, -1);
1276             } finally {
1277                 Binder.restoreCallingIdentity(token);
1278             }
1279         }
1280
1281         @Override
1282         public void setAppInactive(String packageName, boolean idle, int userId) {
1283             final int callingUid = Binder.getCallingUid();
1284             try {
1285                 userId = ActivityManagerNative.getDefault().handleIncomingUser(
1286                         Binder.getCallingPid(), callingUid, userId, false, true,
1287                         "setAppIdle", null);
1288             } catch (RemoteException re) {
1289                 return;
1290             }
1291             getContext().enforceCallingPermission(Manifest.permission.CHANGE_APP_IDLE_STATE,
1292                     "No permission to change app idle state");
1293             final long token = Binder.clearCallingIdentity();
1294             try {
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) {
1300             } finally {
1301                 Binder.restoreCallingIdentity(token);
1302             }
1303         }
1304
1305         @Override
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,
1312                     reason.toString());
1313         }
1314
1315         @Override
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);
1322                 return;
1323             }
1324             UsageStatsService.this.dump(args, pw);
1325         }
1326
1327
1328     }
1329
1330     /**
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.
1334      */
1335     private final class LocalService extends UsageStatsManagerInternal {
1336
1337         @Override
1338         public void reportEvent(ComponentName component, int userId, int eventType) {
1339             if (component == null) {
1340                 Slog.w(TAG, "Event reported without a component name");
1341                 return;
1342             }
1343
1344             UsageEvents.Event event = new UsageEvents.Event();
1345             event.mPackage = component.getPackageName();
1346             event.mClass = component.getClassName();
1347
1348             // This will later be converted to system time.
1349             event.mTimeStamp = SystemClock.elapsedRealtime();
1350
1351             event.mEventType = eventType;
1352             mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget();
1353         }
1354
1355         @Override
1356         public void reportEvent(String packageName, int userId, int eventType) {
1357             if (packageName == null) {
1358                 Slog.w(TAG, "Event reported without a package name");
1359                 return;
1360             }
1361
1362             UsageEvents.Event event = new UsageEvents.Event();
1363             event.mPackage = packageName;
1364
1365             // This will later be converted to system time.
1366             event.mTimeStamp = SystemClock.elapsedRealtime();
1367
1368             event.mEventType = eventType;
1369             mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget();
1370         }
1371
1372         @Override
1373         public void reportConfigurationChange(Configuration config, int userId) {
1374             if (config == null) {
1375                 Slog.w(TAG, "Configuration event reported with a null config");
1376                 return;
1377             }
1378
1379             UsageEvents.Event event = new UsageEvents.Event();
1380             event.mPackage = "android";
1381
1382             // This will later be converted to system time.
1383             event.mTimeStamp = SystemClock.elapsedRealtime();
1384
1385             event.mEventType = UsageEvents.Event.CONFIGURATION_CHANGE;
1386             event.mConfiguration = new Configuration(config);
1387             mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget();
1388         }
1389
1390         @Override
1391         public void reportContentProviderUsage(String name, String packageName, int userId) {
1392             SomeArgs args = SomeArgs.obtain();
1393             args.arg1 = name;
1394             args.arg2 = packageName;
1395             args.arg3 = userId;
1396             mHandler.obtainMessage(MSG_REPORT_CONTENT_PROVIDER_USAGE, args)
1397                     .sendToTarget();
1398         }
1399
1400         @Override
1401         public boolean isAppIdle(String packageName, int uidForAppId, int userId) {
1402             return UsageStatsService.this.isAppIdleFiltered(packageName, uidForAppId, userId, -1);
1403         }
1404
1405         @Override
1406         public int[] getIdleUidsForUser(int userId) {
1407             return UsageStatsService.this.getIdleUidsForUser(userId);
1408         }
1409
1410         @Override
1411         public boolean isAppIdleParoleOn() {
1412             return mAppIdleParoled;
1413         }
1414
1415         @Override
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.
1420             shutdown();
1421         }
1422
1423         @Override
1424         public void addAppIdleStateChangeListener(AppIdleStateChangeListener listener) {
1425             UsageStatsService.this.addListener(listener);
1426             listener.onParoleStateChanged(isAppIdleParoleOn());
1427         }
1428
1429         @Override
1430         public void removeAppIdleStateChangeListener(
1431                 AppIdleStateChangeListener listener) {
1432             UsageStatsService.this.removeListener(listener);
1433         }
1434
1435         @Override
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);
1442             } else {
1443                 return null;
1444             }
1445         }
1446
1447         @Override
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);
1453             }
1454         }
1455     }
1456 }