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