OSDN Git Service

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