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.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                 final boolean displayOn = isDisplayOn();
    308                 synchronized (UsageStatsService.this.mLock) {
    309                     mAppIdleHistory.updateDisplayLocked(displayOn, 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 and screen on time. If this fails for whatever reason, the apps will be
   1009         // considered not-idle, which is the safest outcome in such an event.
   1010         mAppIdleHistory.writeAppIdleDurationsLocked();
   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 }
   1514