blob: 9b29b3212b44115d927cfceb18ec02824c4608e0 [file] [log] [blame]
Makoto Onuki9be01402017-11-10 13:22:26 -08001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy 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,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.server;
17
18import android.annotation.NonNull;
Makoto Onuki9be01402017-11-10 13:22:26 -080019import android.app.ActivityManager;
Makoto Onuki15407842018-01-19 14:23:11 -080020import android.app.ActivityManagerInternal;
Makoto Onuki9be01402017-11-10 13:22:26 -080021import android.app.AppOpsManager;
22import android.app.AppOpsManager.PackageOps;
Makoto Onuki2206af32017-11-21 16:25:35 -080023import android.app.IActivityManager;
Makoto Onuki9be01402017-11-10 13:22:26 -080024import android.app.IUidObserver;
Makoto Onukieb898f12018-01-23 15:26:27 -080025import android.app.usage.UsageStatsManager;
26import android.app.usage.UsageStatsManagerInternal;
27import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener;
Makoto Onuki2206af32017-11-21 16:25:35 -080028import android.content.BroadcastReceiver;
Makoto Onuki9be01402017-11-10 13:22:26 -080029import android.content.Context;
Makoto Onuki2206af32017-11-21 16:25:35 -080030import android.content.Intent;
31import android.content.IntentFilter;
Suprabh Shukla4deb8522018-01-08 16:27:10 -080032import android.database.ContentObserver;
Nancy Zheng525aaa12018-01-12 11:45:37 -080033import android.net.Uri;
34import android.os.BatteryManager;
Makoto Onuki9be01402017-11-10 13:22:26 -080035import android.os.Handler;
Makoto Onuki2206af32017-11-21 16:25:35 -080036import android.os.Looper;
37import android.os.Message;
Makoto Onuki9be01402017-11-10 13:22:26 -080038import android.os.PowerManager.ServiceType;
39import android.os.PowerManagerInternal;
40import android.os.RemoteException;
41import android.os.ServiceManager;
42import android.os.UserHandle;
Suprabh Shukla4deb8522018-01-08 16:27:10 -080043import android.provider.Settings;
Makoto Onuki9be01402017-11-10 13:22:26 -080044import android.util.ArraySet;
45import android.util.Pair;
Suprabh Shukla4deb8522018-01-08 16:27:10 -080046import android.util.Slog;
Makoto Onuki9be01402017-11-10 13:22:26 -080047import android.util.SparseBooleanArray;
Makoto Onukieb898f12018-01-23 15:26:27 -080048import android.util.SparseSetArray;
Makoto Onuki2206af32017-11-21 16:25:35 -080049import android.util.proto.ProtoOutputStream;
Makoto Onuki9be01402017-11-10 13:22:26 -080050
51import com.android.internal.annotations.GuardedBy;
Makoto Onuki2206af32017-11-21 16:25:35 -080052import com.android.internal.annotations.VisibleForTesting;
Makoto Onuki9be01402017-11-10 13:22:26 -080053import com.android.internal.app.IAppOpsCallback;
54import com.android.internal.app.IAppOpsService;
Makoto Onuki2206af32017-11-21 16:25:35 -080055import com.android.internal.util.ArrayUtils;
Makoto Onuki9be01402017-11-10 13:22:26 -080056import com.android.internal.util.Preconditions;
Makoto Onukieb898f12018-01-23 15:26:27 -080057import com.android.server.ForceAppStandbyTrackerProto.ExemptedPackage;
Makoto Onuki2206af32017-11-21 16:25:35 -080058import com.android.server.ForceAppStandbyTrackerProto.RunAnyInBackgroundRestrictedPackages;
Makoto Onuki9be01402017-11-10 13:22:26 -080059
Makoto Onuki2206af32017-11-21 16:25:35 -080060import java.io.PrintWriter;
61import java.util.Arrays;
Makoto Onuki9be01402017-11-10 13:22:26 -080062import java.util.List;
63
64/**
Makoto Onuki2206af32017-11-21 16:25:35 -080065 * Class to keep track of the information related to "force app standby", which includes:
66 * - OP_RUN_ANY_IN_BACKGROUND for each package
Makoto Onukiadb50d82018-01-29 16:20:30 -080067 * - UID foreground/active state
Makoto Onuki2206af32017-11-21 16:25:35 -080068 * - User+system power save whitelist
69 * - Temporary power save whitelist
70 * - Global "force all apps standby" mode enforced by battery saver.
Makoto Onuki9be01402017-11-10 13:22:26 -080071 *
Makoto Onukiadb50d82018-01-29 16:20:30 -080072 * TODO: Make it a LocalService.
Makoto Onuki2206af32017-11-21 16:25:35 -080073 *
74 * Test:
Makoto Onukie4918212018-02-06 11:30:15 -080075 atest $ANDROID_BUILD_TOP/frameworks/base/services/tests/servicestests/src/com/android/server/AppStateTrackerTest.java
Makoto Onuki9be01402017-11-10 13:22:26 -080076 */
Makoto Onukie4918212018-02-06 11:30:15 -080077public class AppStateTracker {
Makoto Onuki9be01402017-11-10 13:22:26 -080078 private static final String TAG = "ForceAppStandbyTracker";
Makoto Onukieb898f12018-01-23 15:26:27 -080079 private static final boolean DEBUG = true;
Makoto Onuki9be01402017-11-10 13:22:26 -080080
Makoto Onukie4918212018-02-06 11:30:15 -080081 @GuardedBy("AppStateTracker.class")
82 private static AppStateTracker sInstance;
Makoto Onuki9be01402017-11-10 13:22:26 -080083
84 private final Object mLock = new Object();
85 private final Context mContext;
86
Makoto Onuki2206af32017-11-21 16:25:35 -080087 @VisibleForTesting
88 static final int TARGET_OP = AppOpsManager.OP_RUN_ANY_IN_BACKGROUND;
89
90 IActivityManager mIActivityManager;
Makoto Onukie4918212018-02-06 11:30:15 -080091 ActivityManagerInternal mActivityManagerInternal;
Makoto Onuki9be01402017-11-10 13:22:26 -080092 AppOpsManager mAppOpsManager;
93 IAppOpsService mAppOpsService;
94 PowerManagerInternal mPowerManagerInternal;
Makoto Onukieb898f12018-01-23 15:26:27 -080095 StandbyTracker mStandbyTracker;
96 UsageStatsManagerInternal mUsageStatsManagerInternal;
Makoto Onuki9be01402017-11-10 13:22:26 -080097
Makoto Onuki2206af32017-11-21 16:25:35 -080098 private final MyHandler mHandler;
Makoto Onuki9be01402017-11-10 13:22:26 -080099
Nancy Zheng525aaa12018-01-12 11:45:37 -0800100 @VisibleForTesting
101 FeatureFlagsObserver mFlagsObserver;
102
Makoto Onuki9be01402017-11-10 13:22:26 -0800103 /**
104 * Pair of (uid (not user-id), packageName) with OP_RUN_ANY_IN_BACKGROUND *not* allowed.
105 */
106 @GuardedBy("mLock")
Makoto Onuki2206af32017-11-21 16:25:35 -0800107 final ArraySet<Pair<Integer, String>> mRunAnyRestrictedPackages = new ArraySet<>();
Makoto Onuki9be01402017-11-10 13:22:26 -0800108
Makoto Onukiadb50d82018-01-29 16:20:30 -0800109 /** UIDs that are active. */
110 @GuardedBy("mLock")
111 final SparseBooleanArray mActiveUids = new SparseBooleanArray();
112
113 /** UIDs that are in the foreground. */
Makoto Onuki9be01402017-11-10 13:22:26 -0800114 @GuardedBy("mLock")
115 final SparseBooleanArray mForegroundUids = new SparseBooleanArray();
116
Makoto Onuki71755c92018-01-16 14:15:44 -0800117 /**
118 * System except-idle + user whitelist in the device idle controller.
119 */
Makoto Onuki9be01402017-11-10 13:22:26 -0800120 @GuardedBy("mLock")
Makoto Onuki2206af32017-11-21 16:25:35 -0800121 private int[] mPowerWhitelistedAllAppIds = new int[0];
122
123 @GuardedBy("mLock")
124 private int[] mTempWhitelistedAppIds = mPowerWhitelistedAllAppIds;
125
Makoto Onukieb898f12018-01-23 15:26:27 -0800126 /**
127 * Per-user packages that are in the EXEMPT bucket.
128 */
129 @GuardedBy("mLock")
130 private final SparseSetArray<String> mExemptedPackages = new SparseSetArray<>();
131
Makoto Onuki2206af32017-11-21 16:25:35 -0800132 @GuardedBy("mLock")
Makoto Onuki9be01402017-11-10 13:22:26 -0800133 final ArraySet<Listener> mListeners = new ArraySet<>();
134
135 @GuardedBy("mLock")
136 boolean mStarted;
137
Nancy Zheng525aaa12018-01-12 11:45:37 -0800138 /**
139 * Only used for small battery use-case.
140 */
Makoto Onuki9be01402017-11-10 13:22:26 -0800141 @GuardedBy("mLock")
Nancy Zheng525aaa12018-01-12 11:45:37 -0800142 boolean mIsPluggedIn;
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800143
144 @GuardedBy("mLock")
Nancy Zheng525aaa12018-01-12 11:45:37 -0800145 boolean mBatterySaverEnabled;
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800146
Nancy Zheng525aaa12018-01-12 11:45:37 -0800147 /**
148 * True if the forced app standby is currently enabled
149 */
150 @GuardedBy("mLock")
151 boolean mForceAllAppsStandby;
152
153 /**
154 * True if the forced app standby for small battery devices feature is enabled in settings
155 */
156 @GuardedBy("mLock")
157 boolean mForceAllAppStandbyForSmallBattery;
158
159 /**
160 * True if the forced app standby feature is enabled in settings
161 */
162 @GuardedBy("mLock")
163 boolean mForcedAppStandbyEnabled;
164
Makoto Onukieb898f12018-01-23 15:26:27 -0800165 interface Stats {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800166 int UID_FG_STATE_CHANGED = 0;
167 int UID_ACTIVE_STATE_CHANGED = 1;
168 int RUN_ANY_CHANGED = 2;
169 int ALL_UNWHITELISTED = 3;
170 int ALL_WHITELIST_CHANGED = 4;
171 int TEMP_WHITELIST_CHANGED = 5;
172 int EXEMPT_CHANGED = 6;
173 int FORCE_ALL_CHANGED = 7;
174 int FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED = 8;
Makoto Onukie4918212018-02-06 11:30:15 -0800175
176 int IS_UID_ACTIVE_CACHED = 9;
177 int IS_UID_ACTIVE_RAW = 10;
Makoto Onukieb898f12018-01-23 15:26:27 -0800178 }
179
180 private final StatLogger mStatLogger = new StatLogger(new String[] {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800181 "UID_FG_STATE_CHANGED",
182 "UID_ACTIVE_STATE_CHANGED",
Makoto Onukieb898f12018-01-23 15:26:27 -0800183 "RUN_ANY_CHANGED",
184 "ALL_UNWHITELISTED",
185 "ALL_WHITELIST_CHANGED",
186 "TEMP_WHITELIST_CHANGED",
187 "EXEMPT_CHANGED",
188 "FORCE_ALL_CHANGED",
189 "FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED",
Makoto Onukie4918212018-02-06 11:30:15 -0800190
191 "IS_UID_ACTIVE_CACHED",
192 "IS_UID_ACTIVE_RAW",
Makoto Onukieb898f12018-01-23 15:26:27 -0800193 });
194
Nancy Zheng525aaa12018-01-12 11:45:37 -0800195 @VisibleForTesting
196 class FeatureFlagsObserver extends ContentObserver {
197 FeatureFlagsObserver() {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800198 super(null);
199 }
200
201 void register() {
202 mContext.getContentResolver().registerContentObserver(
203 Settings.Global.getUriFor(Settings.Global.FORCED_APP_STANDBY_ENABLED),
204 false, this);
Nancy Zheng525aaa12018-01-12 11:45:37 -0800205
206 mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor(
207 Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED), false, this);
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800208 }
209
210 boolean isForcedAppStandbyEnabled() {
Makoto Onukieb898f12018-01-23 15:26:27 -0800211 return injectGetGlobalSettingInt(Settings.Global.FORCED_APP_STANDBY_ENABLED, 1) == 1;
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800212 }
213
Nancy Zheng525aaa12018-01-12 11:45:37 -0800214 boolean isForcedAppStandbyForSmallBatteryEnabled() {
Makoto Onukieb898f12018-01-23 15:26:27 -0800215 return injectGetGlobalSettingInt(
Nancy Zheng525aaa12018-01-12 11:45:37 -0800216 Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED, 0) == 1;
217 }
218
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800219 @Override
Nancy Zheng525aaa12018-01-12 11:45:37 -0800220 public void onChange(boolean selfChange, Uri uri) {
221 if (Settings.Global.getUriFor(Settings.Global.FORCED_APP_STANDBY_ENABLED).equals(uri)) {
222 final boolean enabled = isForcedAppStandbyEnabled();
223 synchronized (mLock) {
224 if (mForcedAppStandbyEnabled == enabled) {
225 return;
226 }
227 mForcedAppStandbyEnabled = enabled;
228 if (DEBUG) {
229 Slog.d(TAG,"Forced app standby feature flag changed: "
230 + mForcedAppStandbyEnabled);
231 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800232 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800233 mHandler.notifyForcedAppStandbyFeatureFlagChanged();
234 } else if (Settings.Global.getUriFor(
235 Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED).equals(uri)) {
236 final boolean enabled = isForcedAppStandbyForSmallBatteryEnabled();
237 synchronized (mLock) {
238 if (mForceAllAppStandbyForSmallBattery == enabled) {
239 return;
240 }
241 mForceAllAppStandbyForSmallBattery = enabled;
242 if (DEBUG) {
243 Slog.d(TAG, "Forced app standby for small battery feature flag changed: "
244 + mForceAllAppStandbyForSmallBattery);
245 }
246 updateForceAllAppStandbyState();
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800247 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800248 } else {
249 Slog.w(TAG, "Unexpected feature flag uri encountered: " + uri);
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800250 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800251 }
252 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800253
254 public static abstract class Listener {
Makoto Onuki2206af32017-11-21 16:25:35 -0800255 /**
256 * This is called when the OP_RUN_ANY_IN_BACKGROUND appops changed for a package.
257 */
Makoto Onukie4918212018-02-06 11:30:15 -0800258 private void onRunAnyAppOpsChanged(AppStateTracker sender,
Makoto Onuki2206af32017-11-21 16:25:35 -0800259 int uid, @NonNull String packageName) {
260 updateJobsForUidPackage(uid, packageName);
261
Suprabh Shuklac25447d2018-01-19 16:43:35 -0800262 if (!sender.areAlarmsRestricted(uid, packageName, /*allowWhileIdle=*/ false)) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800263 unblockAlarmsForUidPackage(uid, packageName);
Suprabh Shuklac25447d2018-01-19 16:43:35 -0800264 } else if (!sender.areAlarmsRestricted(uid, packageName, /*allowWhileIdle=*/ true)){
265 // we need to deliver the allow-while-idle alarms for this uid, package
266 unblockAllUnrestrictedAlarms();
Makoto Onuki2206af32017-11-21 16:25:35 -0800267 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800268 }
269
Makoto Onuki2206af32017-11-21 16:25:35 -0800270 /**
271 * This is called when the foreground state changed for a UID.
272 */
Makoto Onukie4918212018-02-06 11:30:15 -0800273 private void onUidForegroundStateChanged(AppStateTracker sender, int uid) {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800274 onUidForeground(uid, sender.isUidInForeground(uid));
275 }
276
277 /**
278 * This is called when the active/idle state changed for a UID.
279 */
Makoto Onukie4918212018-02-06 11:30:15 -0800280 private void onUidActiveStateChanged(AppStateTracker sender, int uid) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800281 updateJobsForUid(uid);
282
Makoto Onukiadb50d82018-01-29 16:20:30 -0800283 if (sender.isUidActive(uid)) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800284 unblockAlarmsForUid(uid);
285 }
286 }
287
288 /**
289 * This is called when an app-id(s) is removed from the power save whitelist.
290 */
Makoto Onukie4918212018-02-06 11:30:15 -0800291 private void onPowerSaveUnwhitelisted(AppStateTracker sender) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800292 updateAllJobs();
293 unblockAllUnrestrictedAlarms();
294 }
295
296 /**
297 * This is called when the power save whitelist changes, excluding the
298 * {@link #onPowerSaveUnwhitelisted} case.
299 */
Makoto Onukie4918212018-02-06 11:30:15 -0800300 private void onPowerSaveWhitelistedChanged(AppStateTracker sender) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800301 updateAllJobs();
302 }
303
304 /**
305 * This is called when the temp whitelist changes.
306 */
Makoto Onukie4918212018-02-06 11:30:15 -0800307 private void onTempPowerSaveWhitelistChanged(AppStateTracker sender) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800308
309 // TODO This case happens rather frequently; consider optimizing and update jobs
310 // only for affected app-ids.
311
312 updateAllJobs();
Makoto Onukieb898f12018-01-23 15:26:27 -0800313
314 // Note when an app is just put in the temp whitelist, we do *not* drain pending alarms.
315 }
316
317 /**
318 * This is called when the EXEMPT bucket is updated.
319 */
Makoto Onukie4918212018-02-06 11:30:15 -0800320 private void onExemptChanged(AppStateTracker sender) {
Makoto Onukieb898f12018-01-23 15:26:27 -0800321 // This doesn't happen very often, so just re-evaluate all jobs / alarms.
322 updateAllJobs();
323 unblockAllUnrestrictedAlarms();
Makoto Onuki2206af32017-11-21 16:25:35 -0800324 }
325
326 /**
327 * This is called when the global "force all apps standby" flag changes.
328 */
Makoto Onukie4918212018-02-06 11:30:15 -0800329 private void onForceAllAppsStandbyChanged(AppStateTracker sender) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800330 updateAllJobs();
331
332 if (!sender.isForceAllAppsStandbyEnabled()) {
333 unblockAllUnrestrictedAlarms();
334 }
335 }
336
337 /**
338 * Called when the job restrictions for multiple UIDs might have changed, so the job
339 * scheduler should re-evaluate all restrictions for all jobs.
340 */
341 public void updateAllJobs() {
342 }
343
344 /**
345 * Called when the job restrictions for a UID might have changed, so the job
346 * scheduler should re-evaluate all restrictions for all jobs.
347 */
348 public void updateJobsForUid(int uid) {
349 }
350
351 /**
352 * Called when the job restrictions for a UID - package might have changed, so the job
353 * scheduler should re-evaluate all restrictions for all jobs.
354 */
355 public void updateJobsForUidPackage(int uid, String packageName) {
356 }
357
358 /**
359 * Called when the job restrictions for multiple UIDs might have changed, so the alarm
360 * manager should re-evaluate all restrictions for all blocked jobs.
361 */
362 public void unblockAllUnrestrictedAlarms() {
363 }
364
365 /**
366 * Called when all jobs for a specific UID are unblocked.
367 */
368 public void unblockAlarmsForUid(int uid) {
369 }
370
371 /**
372 * Called when all alarms for a specific UID - package are unblocked.
373 */
374 public void unblockAlarmsForUidPackage(int uid, String packageName) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800375 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800376
377 /**
378 * Called when a UID comes into the foreground or the background.
379 *
380 * @see #isUidInForeground(int)
381 */
382 public void onUidForeground(int uid, boolean foreground) {
383 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800384 }
385
Makoto Onukie4918212018-02-06 11:30:15 -0800386 public AppStateTracker(Context context, Looper looper) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800387 mContext = context;
Makoto Onuki2206af32017-11-21 16:25:35 -0800388 mHandler = new MyHandler(looper);
389 }
390
Makoto Onuki9be01402017-11-10 13:22:26 -0800391 /**
392 * Call it when the system is ready.
393 */
Makoto Onukie4918212018-02-06 11:30:15 -0800394 public void onSystemServicesReady() {
Makoto Onuki9be01402017-11-10 13:22:26 -0800395 synchronized (mLock) {
396 if (mStarted) {
397 return;
398 }
399 mStarted = true;
400
Makoto Onuki2206af32017-11-21 16:25:35 -0800401 mIActivityManager = Preconditions.checkNotNull(injectIActivityManager());
Makoto Onukie4918212018-02-06 11:30:15 -0800402 mActivityManagerInternal = Preconditions.checkNotNull(injectActivityManagerInternal());
Makoto Onuki2206af32017-11-21 16:25:35 -0800403 mAppOpsManager = Preconditions.checkNotNull(injectAppOpsManager());
404 mAppOpsService = Preconditions.checkNotNull(injectIAppOpsService());
405 mPowerManagerInternal = Preconditions.checkNotNull(injectPowerManagerInternal());
Makoto Onukieb898f12018-01-23 15:26:27 -0800406 mUsageStatsManagerInternal = Preconditions.checkNotNull(
407 injectUsageStatsManagerInternal());
408
Nancy Zheng525aaa12018-01-12 11:45:37 -0800409 mFlagsObserver = new FeatureFlagsObserver();
410 mFlagsObserver.register();
411 mForcedAppStandbyEnabled = mFlagsObserver.isForcedAppStandbyEnabled();
412 mForceAllAppStandbyForSmallBattery =
413 mFlagsObserver.isForcedAppStandbyForSmallBatteryEnabled();
Makoto Onukieb898f12018-01-23 15:26:27 -0800414 mStandbyTracker = new StandbyTracker();
415 mUsageStatsManagerInternal.addAppIdleStateChangeListener(mStandbyTracker);
Makoto Onuki9be01402017-11-10 13:22:26 -0800416
417 try {
Makoto Onuki2206af32017-11-21 16:25:35 -0800418 mIActivityManager.registerUidObserver(new UidObserver(),
Makoto Onukiadb50d82018-01-29 16:20:30 -0800419 ActivityManager.UID_OBSERVER_GONE
420 | ActivityManager.UID_OBSERVER_IDLE
421 | ActivityManager.UID_OBSERVER_ACTIVE
422 | ActivityManager.UID_OBSERVER_PROCSTATE,
Makoto Onuki9be01402017-11-10 13:22:26 -0800423 ActivityManager.PROCESS_STATE_UNKNOWN, null);
Makoto Onuki2206af32017-11-21 16:25:35 -0800424 mAppOpsService.startWatchingMode(TARGET_OP, null,
Makoto Onuki9be01402017-11-10 13:22:26 -0800425 new AppOpsWatcher());
426 } catch (RemoteException e) {
427 // shouldn't happen.
428 }
429
Makoto Onuki2206af32017-11-21 16:25:35 -0800430 IntentFilter filter = new IntentFilter();
431 filter.addAction(Intent.ACTION_USER_REMOVED);
Nancy Zheng525aaa12018-01-12 11:45:37 -0800432 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800433 mContext.registerReceiver(new MyReceiver(), filter);
Makoto Onuki9be01402017-11-10 13:22:26 -0800434
435 refreshForcedAppStandbyUidPackagesLocked();
Makoto Onuki2206af32017-11-21 16:25:35 -0800436
437 mPowerManagerInternal.registerLowPowerModeObserver(
438 ServiceType.FORCE_ALL_APPS_STANDBY,
Nancy Zheng525aaa12018-01-12 11:45:37 -0800439 (state) -> {
440 synchronized (mLock) {
441 mBatterySaverEnabled = state.batterySaverEnabled;
442 updateForceAllAppStandbyState();
443 }
444 });
Makoto Onuki2206af32017-11-21 16:25:35 -0800445
Nancy Zheng525aaa12018-01-12 11:45:37 -0800446 mBatterySaverEnabled = mPowerManagerInternal.getLowPowerState(
447 ServiceType.FORCE_ALL_APPS_STANDBY).batterySaverEnabled;
448
449 updateForceAllAppStandbyState();
Makoto Onuki9be01402017-11-10 13:22:26 -0800450 }
451 }
452
Makoto Onuki2206af32017-11-21 16:25:35 -0800453 @VisibleForTesting
454 AppOpsManager injectAppOpsManager() {
455 return mContext.getSystemService(AppOpsManager.class);
456 }
457
458 @VisibleForTesting
459 IAppOpsService injectIAppOpsService() {
460 return IAppOpsService.Stub.asInterface(
461 ServiceManager.getService(Context.APP_OPS_SERVICE));
462 }
463
464 @VisibleForTesting
465 IActivityManager injectIActivityManager() {
466 return ActivityManager.getService();
467 }
468
469 @VisibleForTesting
Makoto Onukie4918212018-02-06 11:30:15 -0800470 ActivityManagerInternal injectActivityManagerInternal() {
471 return LocalServices.getService(ActivityManagerInternal.class);
472 }
473
474 @VisibleForTesting
Makoto Onuki2206af32017-11-21 16:25:35 -0800475 PowerManagerInternal injectPowerManagerInternal() {
476 return LocalServices.getService(PowerManagerInternal.class);
477 }
478
Nancy Zheng525aaa12018-01-12 11:45:37 -0800479 @VisibleForTesting
Makoto Onukieb898f12018-01-23 15:26:27 -0800480 UsageStatsManagerInternal injectUsageStatsManagerInternal() {
481 return LocalServices.getService(UsageStatsManagerInternal.class);
482 }
483
484 @VisibleForTesting
Nancy Zheng525aaa12018-01-12 11:45:37 -0800485 boolean isSmallBatteryDevice() {
486 return ActivityManager.isSmallBatteryDevice();
487 }
488
Makoto Onukieb898f12018-01-23 15:26:27 -0800489 @VisibleForTesting
490 int injectGetGlobalSettingInt(String key, int def) {
491 return Settings.Global.getInt(mContext.getContentResolver(), key, def);
492 }
493
Makoto Onuki9be01402017-11-10 13:22:26 -0800494 /**
Makoto Onuki2206af32017-11-21 16:25:35 -0800495 * Update {@link #mRunAnyRestrictedPackages} with the current app ops state.
Makoto Onuki9be01402017-11-10 13:22:26 -0800496 */
Andreas Gampea36dc622018-02-05 17:19:22 -0800497 @GuardedBy("mLock")
Makoto Onuki9be01402017-11-10 13:22:26 -0800498 private void refreshForcedAppStandbyUidPackagesLocked() {
Makoto Onuki2206af32017-11-21 16:25:35 -0800499 mRunAnyRestrictedPackages.clear();
500 final List<PackageOps> ops = mAppOpsManager.getPackagesForOps(
501 new int[] {TARGET_OP});
Makoto Onuki9be01402017-11-10 13:22:26 -0800502
503 if (ops == null) {
504 return;
505 }
506 final int size = ops.size();
507 for (int i = 0; i < size; i++) {
508 final AppOpsManager.PackageOps pkg = ops.get(i);
509 final List<AppOpsManager.OpEntry> entries = ops.get(i).getOps();
510
511 for (int j = 0; j < entries.size(); j++) {
512 AppOpsManager.OpEntry ent = entries.get(j);
Makoto Onuki2206af32017-11-21 16:25:35 -0800513 if (ent.getOp() != TARGET_OP) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800514 continue;
515 }
516 if (ent.getMode() != AppOpsManager.MODE_ALLOWED) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800517 mRunAnyRestrictedPackages.add(Pair.create(
Makoto Onuki9be01402017-11-10 13:22:26 -0800518 pkg.getUid(), pkg.getPackageName()));
519 }
520 }
521 }
522 }
523
Nancy Zheng525aaa12018-01-12 11:45:37 -0800524 private void updateForceAllAppStandbyState() {
525 synchronized (mLock) {
526 if (mForceAllAppStandbyForSmallBattery && isSmallBatteryDevice()) {
527 toggleForceAllAppsStandbyLocked(!mIsPluggedIn);
528 } else {
529 toggleForceAllAppsStandbyLocked(mBatterySaverEnabled);
530 }
531 }
532 }
533
Makoto Onuki2206af32017-11-21 16:25:35 -0800534 /**
535 * Update {@link #mForceAllAppsStandby} and notifies the listeners.
536 */
Andreas Gampea36dc622018-02-05 17:19:22 -0800537 @GuardedBy("mLock")
Nancy Zheng525aaa12018-01-12 11:45:37 -0800538 private void toggleForceAllAppsStandbyLocked(boolean enable) {
539 if (enable == mForceAllAppsStandby) {
540 return;
Makoto Onuki12391f22018-01-18 21:44:28 +0000541 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800542 mForceAllAppsStandby = enable;
543
544 mHandler.notifyForceAllAppsStandbyChanged();
Makoto Onuki9be01402017-11-10 13:22:26 -0800545 }
546
Andreas Gampea36dc622018-02-05 17:19:22 -0800547 @GuardedBy("mLock")
Makoto Onuki9be01402017-11-10 13:22:26 -0800548 private int findForcedAppStandbyUidPackageIndexLocked(int uid, @NonNull String packageName) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800549 final int size = mRunAnyRestrictedPackages.size();
550 if (size > 8) {
551 return mRunAnyRestrictedPackages.indexOf(Pair.create(uid, packageName));
552 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800553 for (int i = 0; i < size; i++) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800554 final Pair<Integer, String> pair = mRunAnyRestrictedPackages.valueAt(i);
Makoto Onuki9be01402017-11-10 13:22:26 -0800555
556 if ((pair.first == uid) && packageName.equals(pair.second)) {
557 return i;
558 }
559 }
560 return -1;
561 }
562
563 /**
Makoto Onuki2206af32017-11-21 16:25:35 -0800564 * @return whether a uid package-name pair is in mRunAnyRestrictedPackages.
Makoto Onuki9be01402017-11-10 13:22:26 -0800565 */
Andreas Gampea36dc622018-02-05 17:19:22 -0800566 @GuardedBy("mLock")
Makoto Onuki2206af32017-11-21 16:25:35 -0800567 boolean isRunAnyRestrictedLocked(int uid, @NonNull String packageName) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800568 return findForcedAppStandbyUidPackageIndexLocked(uid, packageName) >= 0;
569 }
570
Makoto Onuki2206af32017-11-21 16:25:35 -0800571 /**
572 * Add to / remove from {@link #mRunAnyRestrictedPackages}.
573 */
Andreas Gampea36dc622018-02-05 17:19:22 -0800574 @GuardedBy("mLock")
Makoto Onuki2206af32017-11-21 16:25:35 -0800575 boolean updateForcedAppStandbyUidPackageLocked(int uid, @NonNull String packageName,
Makoto Onuki9be01402017-11-10 13:22:26 -0800576 boolean restricted) {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800577 final int index = findForcedAppStandbyUidPackageIndexLocked(uid, packageName);
Makoto Onuki9be01402017-11-10 13:22:26 -0800578 final boolean wasRestricted = index >= 0;
579 if (wasRestricted == restricted) {
580 return false;
581 }
582 if (restricted) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800583 mRunAnyRestrictedPackages.add(Pair.create(uid, packageName));
Makoto Onuki9be01402017-11-10 13:22:26 -0800584 } else {
Makoto Onuki2206af32017-11-21 16:25:35 -0800585 mRunAnyRestrictedPackages.removeAt(index);
Makoto Onuki9be01402017-11-10 13:22:26 -0800586 }
587 return true;
588 }
589
Makoto Onukiadb50d82018-01-29 16:20:30 -0800590 private static boolean addUidToArray(SparseBooleanArray array, int uid) {
591 if (UserHandle.isCore(uid)) {
592 return false;
Makoto Onuki9be01402017-11-10 13:22:26 -0800593 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800594 if (array.get(uid)) {
595 return false;
596 }
597 array.put(uid, true);
598 return true;
Makoto Onuki9be01402017-11-10 13:22:26 -0800599 }
600
Makoto Onukiadb50d82018-01-29 16:20:30 -0800601 private static boolean removeUidFromArray(SparseBooleanArray array, int uid, boolean remove) {
602 if (UserHandle.isCore(uid)) {
603 return false;
Makoto Onuki9be01402017-11-10 13:22:26 -0800604 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800605 if (!array.get(uid)) {
606 return false;
607 }
608 if (remove) {
609 array.delete(uid);
610 } else {
611 array.put(uid, false);
612 }
613 return true;
Makoto Onuki9be01402017-11-10 13:22:26 -0800614 }
615
Makoto Onuki2206af32017-11-21 16:25:35 -0800616 private final class UidObserver extends IUidObserver.Stub {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800617 @Override
618 public void onUidStateChanged(int uid, int procState, long procStateSeq) {
Makoto Onuki4d298b52018-02-05 10:54:58 -0800619 mHandler.onUidStateChanged(uid, procState);
Makoto Onuki9be01402017-11-10 13:22:26 -0800620 }
621
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800622 @Override
623 public void onUidActive(int uid) {
Makoto Onuki4d298b52018-02-05 10:54:58 -0800624 mHandler.onUidActive(uid);
625 }
626
627 @Override
628 public void onUidGone(int uid, boolean disabled) {
629 mHandler.onUidGone(uid, disabled);
Makoto Onuki9be01402017-11-10 13:22:26 -0800630 }
631
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800632 @Override
633 public void onUidIdle(int uid, boolean disabled) {
Makoto Onuki4d298b52018-02-05 10:54:58 -0800634 mHandler.onUidIdle(uid, disabled);
Makoto Onuki9be01402017-11-10 13:22:26 -0800635 }
636
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800637 @Override
638 public void onUidCachedChanged(int uid, boolean cached) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800639 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800640 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800641
642 private final class AppOpsWatcher extends IAppOpsCallback.Stub {
643 @Override
644 public void opChanged(int op, int uid, String packageName) throws RemoteException {
Makoto Onuki2206af32017-11-21 16:25:35 -0800645 boolean restricted = false;
646 try {
647 restricted = mAppOpsService.checkOperation(TARGET_OP,
648 uid, packageName) != AppOpsManager.MODE_ALLOWED;
649 } catch (RemoteException e) {
650 // Shouldn't happen
651 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800652 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800653 if (updateForcedAppStandbyUidPackageLocked(uid, packageName, restricted)) {
654 mHandler.notifyRunAnyAppOpsChanged(uid, packageName);
655 }
656 }
657 }
658 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800659
Makoto Onuki2206af32017-11-21 16:25:35 -0800660 private final class MyReceiver extends BroadcastReceiver {
661 @Override
662 public void onReceive(Context context, Intent intent) {
663 if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
664 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
665 if (userId > 0) {
666 mHandler.doUserRemoved(userId);
Makoto Onuki9be01402017-11-10 13:22:26 -0800667 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800668 } else if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
669 synchronized (mLock) {
670 mIsPluggedIn = (intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0);
671 }
672 updateForceAllAppStandbyState();
Makoto Onuki9be01402017-11-10 13:22:26 -0800673 }
674 }
675 }
676
Makoto Onukieb898f12018-01-23 15:26:27 -0800677 final class StandbyTracker extends AppIdleStateChangeListener {
678 @Override
679 public void onAppIdleStateChanged(String packageName, int userId, boolean idle,
680 int bucket) {
681 if (DEBUG) {
682 Slog.d(TAG,"onAppIdleStateChanged: " + packageName + " u" + userId
683 + (idle ? " idle" : " active") + " " + bucket);
684 }
685 final boolean changed;
686 if (bucket == UsageStatsManager.STANDBY_BUCKET_EXEMPTED) {
687 changed = mExemptedPackages.add(userId, packageName);
688 } else {
689 changed = mExemptedPackages.remove(userId, packageName);
690 }
691 if (changed) {
692 mHandler.notifyExemptChanged();
693 }
694 }
695
696 @Override
697 public void onParoleStateChanged(boolean isParoleOn) {
698 }
699 }
700
Makoto Onuki9be01402017-11-10 13:22:26 -0800701 private Listener[] cloneListeners() {
702 synchronized (mLock) {
703 return mListeners.toArray(new Listener[mListeners.size()]);
704 }
705 }
706
Makoto Onuki2206af32017-11-21 16:25:35 -0800707 private class MyHandler extends Handler {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800708 private static final int MSG_UID_ACTIVE_STATE_CHANGED = 0;
709 private static final int MSG_UID_FG_STATE_CHANGED = 1;
710 private static final int MSG_RUN_ANY_CHANGED = 3;
711 private static final int MSG_ALL_UNWHITELISTED = 4;
712 private static final int MSG_ALL_WHITELIST_CHANGED = 5;
713 private static final int MSG_TEMP_WHITELIST_CHANGED = 6;
714 private static final int MSG_FORCE_ALL_CHANGED = 7;
715 private static final int MSG_USER_REMOVED = 8;
716 private static final int MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED = 9;
717 private static final int MSG_EXEMPT_CHANGED = 10;
Makoto Onuki9be01402017-11-10 13:22:26 -0800718
Makoto Onuki4d298b52018-02-05 10:54:58 -0800719 private static final int MSG_ON_UID_STATE_CHANGED = 11;
720 private static final int MSG_ON_UID_ACTIVE = 12;
721 private static final int MSG_ON_UID_GONE = 13;
722 private static final int MSG_ON_UID_IDLE = 14;
723
Makoto Onuki2206af32017-11-21 16:25:35 -0800724 public MyHandler(Looper looper) {
725 super(looper);
Makoto Onuki9be01402017-11-10 13:22:26 -0800726 }
Makoto Onuki2206af32017-11-21 16:25:35 -0800727
Makoto Onukiadb50d82018-01-29 16:20:30 -0800728 public void notifyUidActiveStateChanged(int uid) {
729 obtainMessage(MSG_UID_ACTIVE_STATE_CHANGED, uid, 0).sendToTarget();
730 }
731
Makoto Onuki2206af32017-11-21 16:25:35 -0800732 public void notifyUidForegroundStateChanged(int uid) {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800733 obtainMessage(MSG_UID_FG_STATE_CHANGED, uid, 0).sendToTarget();
Makoto Onuki2206af32017-11-21 16:25:35 -0800734 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800735
Makoto Onuki2206af32017-11-21 16:25:35 -0800736 public void notifyRunAnyAppOpsChanged(int uid, @NonNull String packageName) {
737 obtainMessage(MSG_RUN_ANY_CHANGED, uid, 0, packageName).sendToTarget();
738 }
739
740 public void notifyAllUnwhitelisted() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800741 removeMessages(MSG_ALL_UNWHITELISTED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800742 obtainMessage(MSG_ALL_UNWHITELISTED).sendToTarget();
743 }
744
745 public void notifyAllWhitelistChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800746 removeMessages(MSG_ALL_WHITELIST_CHANGED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800747 obtainMessage(MSG_ALL_WHITELIST_CHANGED).sendToTarget();
748 }
749
750 public void notifyTempWhitelistChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800751 removeMessages(MSG_TEMP_WHITELIST_CHANGED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800752 obtainMessage(MSG_TEMP_WHITELIST_CHANGED).sendToTarget();
753 }
754
755 public void notifyForceAllAppsStandbyChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800756 removeMessages(MSG_FORCE_ALL_CHANGED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800757 obtainMessage(MSG_FORCE_ALL_CHANGED).sendToTarget();
758 }
759
Nancy Zheng525aaa12018-01-12 11:45:37 -0800760 public void notifyForcedAppStandbyFeatureFlagChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800761 removeMessages(MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED);
Nancy Zheng525aaa12018-01-12 11:45:37 -0800762 obtainMessage(MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED).sendToTarget();
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800763 }
764
Makoto Onukieb898f12018-01-23 15:26:27 -0800765 public void notifyExemptChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800766 removeMessages(MSG_EXEMPT_CHANGED);
Makoto Onukieb898f12018-01-23 15:26:27 -0800767 obtainMessage(MSG_EXEMPT_CHANGED).sendToTarget();
768 }
769
Makoto Onuki2206af32017-11-21 16:25:35 -0800770 public void doUserRemoved(int userId) {
771 obtainMessage(MSG_USER_REMOVED, userId, 0).sendToTarget();
772 }
773
Makoto Onuki4d298b52018-02-05 10:54:58 -0800774 public void onUidStateChanged(int uid, int procState) {
775 obtainMessage(MSG_ON_UID_STATE_CHANGED, uid, procState).sendToTarget();
776 }
777
778 public void onUidActive(int uid) {
779 obtainMessage(MSG_ON_UID_ACTIVE, uid, 0).sendToTarget();
780 }
781
782 public void onUidGone(int uid, boolean disabled) {
783 obtainMessage(MSG_ON_UID_GONE, uid, disabled ? 1 : 0).sendToTarget();
784 }
785
786 public void onUidIdle(int uid, boolean disabled) {
787 obtainMessage(MSG_ON_UID_IDLE, uid, disabled ? 1 : 0).sendToTarget();
788 }
789
Makoto Onuki2206af32017-11-21 16:25:35 -0800790 @Override
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800791 public void handleMessage(Message msg) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800792 switch (msg.what) {
793 case MSG_USER_REMOVED:
794 handleUserRemoved(msg.arg1);
795 return;
796 }
797
798 // Only notify the listeners when started.
799 synchronized (mLock) {
800 if (!mStarted) {
801 return;
802 }
803 }
Makoto Onukie4918212018-02-06 11:30:15 -0800804 final AppStateTracker sender = AppStateTracker.this;
Makoto Onuki2206af32017-11-21 16:25:35 -0800805
Makoto Onukieb898f12018-01-23 15:26:27 -0800806 long start = mStatLogger.getTime();
Makoto Onuki2206af32017-11-21 16:25:35 -0800807 switch (msg.what) {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800808 case MSG_UID_ACTIVE_STATE_CHANGED:
809 for (Listener l : cloneListeners()) {
810 l.onUidActiveStateChanged(sender, msg.arg1);
811 }
812 mStatLogger.logDurationStat(Stats.UID_ACTIVE_STATE_CHANGED, start);
813 return;
814
815 case MSG_UID_FG_STATE_CHANGED:
Makoto Onuki2206af32017-11-21 16:25:35 -0800816 for (Listener l : cloneListeners()) {
817 l.onUidForegroundStateChanged(sender, msg.arg1);
818 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800819 mStatLogger.logDurationStat(Stats.UID_FG_STATE_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800820 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800821
Makoto Onuki2206af32017-11-21 16:25:35 -0800822 case MSG_RUN_ANY_CHANGED:
823 for (Listener l : cloneListeners()) {
824 l.onRunAnyAppOpsChanged(sender, msg.arg1, (String) msg.obj);
825 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800826 mStatLogger.logDurationStat(Stats.RUN_ANY_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800827 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800828
Makoto Onuki2206af32017-11-21 16:25:35 -0800829 case MSG_ALL_UNWHITELISTED:
830 for (Listener l : cloneListeners()) {
831 l.onPowerSaveUnwhitelisted(sender);
832 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800833 mStatLogger.logDurationStat(Stats.ALL_UNWHITELISTED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800834 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800835
Makoto Onuki2206af32017-11-21 16:25:35 -0800836 case MSG_ALL_WHITELIST_CHANGED:
837 for (Listener l : cloneListeners()) {
838 l.onPowerSaveWhitelistedChanged(sender);
839 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800840 mStatLogger.logDurationStat(Stats.ALL_WHITELIST_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800841 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800842
Makoto Onuki2206af32017-11-21 16:25:35 -0800843 case MSG_TEMP_WHITELIST_CHANGED:
844 for (Listener l : cloneListeners()) {
845 l.onTempPowerSaveWhitelistChanged(sender);
846 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800847 mStatLogger.logDurationStat(Stats.TEMP_WHITELIST_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800848 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800849
850 case MSG_EXEMPT_CHANGED:
851 for (Listener l : cloneListeners()) {
852 l.onExemptChanged(sender);
853 }
854 mStatLogger.logDurationStat(Stats.EXEMPT_CHANGED, start);
855 return;
856
Makoto Onuki2206af32017-11-21 16:25:35 -0800857 case MSG_FORCE_ALL_CHANGED:
858 for (Listener l : cloneListeners()) {
859 l.onForceAllAppsStandbyChanged(sender);
860 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800861 mStatLogger.logDurationStat(Stats.FORCE_ALL_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800862 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800863
Nancy Zheng525aaa12018-01-12 11:45:37 -0800864 case MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED:
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800865 // Feature flag for forced app standby changed.
866 final boolean unblockAlarms;
867 synchronized (mLock) {
868 unblockAlarms = !mForcedAppStandbyEnabled && !mForceAllAppsStandby;
869 }
Suprabh Shuklac25447d2018-01-19 16:43:35 -0800870 for (Listener l : cloneListeners()) {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800871 l.updateAllJobs();
872 if (unblockAlarms) {
873 l.unblockAllUnrestrictedAlarms();
874 }
875 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800876 mStatLogger.logDurationStat(
877 Stats.FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED, start);
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800878 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800879
Makoto Onuki2206af32017-11-21 16:25:35 -0800880 case MSG_USER_REMOVED:
881 handleUserRemoved(msg.arg1);
882 return;
Makoto Onuki4d298b52018-02-05 10:54:58 -0800883
884 case MSG_ON_UID_STATE_CHANGED:
885 handleUidStateChanged(msg.arg1, msg.arg2);
886 return;
887 case MSG_ON_UID_ACTIVE:
888 handleUidActive(msg.arg1);
889 return;
890 case MSG_ON_UID_GONE:
891 handleUidGone(msg.arg1, msg.arg1 != 0);
892 return;
893 case MSG_ON_UID_IDLE:
894 handleUidIdle(msg.arg1, msg.arg1 != 0);
895 return;
896 }
897 }
898
899 public void handleUidStateChanged(int uid, int procState) {
900 synchronized (mLock) {
901 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
902 if (removeUidFromArray(mForegroundUids, uid, false)) {
903 mHandler.notifyUidForegroundStateChanged(uid);
904 }
905 } else {
906 if (addUidToArray(mForegroundUids, uid)) {
907 mHandler.notifyUidForegroundStateChanged(uid);
908 }
909 }
910 }
911 }
912
913 public void handleUidActive(int uid) {
914 synchronized (mLock) {
915 if (addUidToArray(mActiveUids, uid)) {
916 mHandler.notifyUidActiveStateChanged(uid);
917 }
918 }
919 }
920
921 public void handleUidGone(int uid, boolean disabled) {
922 removeUid(uid, true);
923 }
924
925 public void handleUidIdle(int uid, boolean disabled) {
926 // Just to avoid excessive memcpy, don't remove from the array in this case.
927 removeUid(uid, false);
928 }
929
930 private void removeUid(int uid, boolean remove) {
931 synchronized (mLock) {
932 if (removeUidFromArray(mActiveUids, uid, remove)) {
933 mHandler.notifyUidActiveStateChanged(uid);
934 }
935 if (removeUidFromArray(mForegroundUids, uid, remove)) {
936 mHandler.notifyUidForegroundStateChanged(uid);
937 }
Makoto Onuki2206af32017-11-21 16:25:35 -0800938 }
939 }
940 }
941
942 void handleUserRemoved(int removedUserId) {
943 synchronized (mLock) {
944 for (int i = mRunAnyRestrictedPackages.size() - 1; i >= 0; i--) {
945 final Pair<Integer, String> pair = mRunAnyRestrictedPackages.valueAt(i);
946 final int uid = pair.first;
947 final int userId = UserHandle.getUserId(uid);
948
949 if (userId == removedUserId) {
950 mRunAnyRestrictedPackages.removeAt(i);
951 }
952 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800953 cleanUpArrayForUser(mActiveUids, removedUserId);
954 cleanUpArrayForUser(mForegroundUids, removedUserId);
Makoto Onukieb898f12018-01-23 15:26:27 -0800955 mExemptedPackages.remove(removedUserId);
Makoto Onuki2206af32017-11-21 16:25:35 -0800956 }
957 }
958
Makoto Onukiadb50d82018-01-29 16:20:30 -0800959 private void cleanUpArrayForUser(SparseBooleanArray array, int removedUserId) {
960 for (int i = array.size() - 1; i >= 0; i--) {
961 final int uid = array.keyAt(i);
962 final int userId = UserHandle.getUserId(uid);
963
964 if (userId == removedUserId) {
965 array.removeAt(i);
966 }
967 }
968 }
969
Makoto Onuki2206af32017-11-21 16:25:35 -0800970 /**
971 * Called by device idle controller to update the power save whitelists.
972 */
973 public void setPowerSaveWhitelistAppIds(
974 int[] powerSaveWhitelistAllAppIdArray, int[] tempWhitelistAppIdArray) {
975 synchronized (mLock) {
976 final int[] previousWhitelist = mPowerWhitelistedAllAppIds;
977 final int[] previousTempWhitelist = mTempWhitelistedAppIds;
978
979 mPowerWhitelistedAllAppIds = powerSaveWhitelistAllAppIdArray;
980 mTempWhitelistedAppIds = tempWhitelistAppIdArray;
981
982 if (isAnyAppIdUnwhitelisted(previousWhitelist, mPowerWhitelistedAllAppIds)) {
983 mHandler.notifyAllUnwhitelisted();
984 } else if (!Arrays.equals(previousWhitelist, mPowerWhitelistedAllAppIds)) {
985 mHandler.notifyAllWhitelistChanged();
986 }
987
988 if (!Arrays.equals(previousTempWhitelist, mTempWhitelistedAppIds)) {
989 mHandler.notifyTempWhitelistChanged();
990 }
991
992 }
993 }
994
995 /**
996 * @retunr true if a sorted app-id array {@code prevArray} has at least one element
997 * that's not in a sorted app-id array {@code newArray}.
998 */
999 @VisibleForTesting
1000 static boolean isAnyAppIdUnwhitelisted(int[] prevArray, int[] newArray) {
1001 int i1 = 0;
1002 int i2 = 0;
1003 boolean prevFinished;
1004 boolean newFinished;
1005
1006 for (;;) {
1007 prevFinished = i1 >= prevArray.length;
1008 newFinished = i2 >= newArray.length;
1009 if (prevFinished || newFinished) {
1010 break;
1011 }
1012 int a1 = prevArray[i1];
1013 int a2 = newArray[i2];
1014
1015 if (a1 == a2) {
1016 i1++;
1017 i2++;
1018 continue;
1019 }
1020 if (a1 < a2) {
1021 // prevArray has an element that's not in a2.
1022 return true;
1023 }
1024 i2++;
1025 }
1026 if (prevFinished) {
1027 return false;
1028 }
1029 return newFinished;
Makoto Onuki9be01402017-11-10 13:22:26 -08001030 }
1031
1032 // Public interface.
1033
1034 /**
1035 * Register a new listener.
1036 */
1037 public void addListener(@NonNull Listener listener) {
1038 synchronized (mLock) {
1039 mListeners.add(listener);
1040 }
1041 }
1042
1043 /**
Makoto Onuki2206af32017-11-21 16:25:35 -08001044 * @return whether alarms should be restricted for a UID package-name.
Makoto Onuki9be01402017-11-10 13:22:26 -08001045 */
Suprabh Shuklac25447d2018-01-19 16:43:35 -08001046 public boolean areAlarmsRestricted(int uid, @NonNull String packageName,
1047 boolean allowWhileIdle) {
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001048 return isRestricted(uid, packageName, /*useTempWhitelistToo=*/ false,
Suprabh Shuklac25447d2018-01-19 16:43:35 -08001049 /* exemptOnBatterySaver =*/ allowWhileIdle);
Makoto Onuki2206af32017-11-21 16:25:35 -08001050 }
1051
1052 /**
1053 * @return whether jobs should be restricted for a UID package-name.
1054 */
Makoto Onuki15407842018-01-19 14:23:11 -08001055 public boolean areJobsRestricted(int uid, @NonNull String packageName,
1056 boolean hasForegroundExemption) {
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001057 return isRestricted(uid, packageName, /*useTempWhitelistToo=*/ true,
Makoto Onuki15407842018-01-19 14:23:11 -08001058 hasForegroundExemption);
Makoto Onuki2206af32017-11-21 16:25:35 -08001059 }
1060
1061 /**
1062 * @return whether force-app-standby is effective for a UID package-name.
1063 */
1064 private boolean isRestricted(int uid, @NonNull String packageName,
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001065 boolean useTempWhitelistToo, boolean exemptOnBatterySaver) {
Makoto Onukiadb50d82018-01-29 16:20:30 -08001066 if (isUidActive(uid)) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001067 return false;
1068 }
1069 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001070 // Whitelisted?
1071 final int appId = UserHandle.getAppId(uid);
1072 if (ArrayUtils.contains(mPowerWhitelistedAllAppIds, appId)) {
1073 return false;
1074 }
1075 if (useTempWhitelistToo &&
1076 ArrayUtils.contains(mTempWhitelistedAppIds, appId)) {
1077 return false;
1078 }
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001079 if (mForcedAppStandbyEnabled && isRunAnyRestrictedLocked(uid, packageName)) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001080 return true;
1081 }
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001082 if (exemptOnBatterySaver) {
1083 return false;
1084 }
Makoto Onukieb898f12018-01-23 15:26:27 -08001085 final int userId = UserHandle.getUserId(uid);
1086 if (mExemptedPackages.contains(userId, packageName)) {
1087 return false;
1088 }
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001089 return mForceAllAppsStandby;
Makoto Onuki9be01402017-11-10 13:22:26 -08001090 }
1091 }
1092
Makoto Onuki2206af32017-11-21 16:25:35 -08001093 /**
Makoto Onukie4918212018-02-06 11:30:15 -08001094 * @return whether a UID is in active or not *based on cached information.*
Makoto Onukiadb50d82018-01-29 16:20:30 -08001095 *
1096 * Note this information is based on the UID proc state callback, meaning it's updated
1097 * asynchronously and may subtly be stale. If the fresh data is needed, use
Makoto Onukie4918212018-02-06 11:30:15 -08001098 * {@link #isUidActiveSynced} instead.
Makoto Onukiadb50d82018-01-29 16:20:30 -08001099 */
1100 public boolean isUidActive(int uid) {
1101 if (UserHandle.isCore(uid)) {
1102 return true;
1103 }
1104 synchronized (mLock) {
1105 return mActiveUids.get(uid);
1106 }
1107 }
1108
1109 /**
Makoto Onukie4918212018-02-06 11:30:15 -08001110 * @return whether a UID is in active or not *right now.*
1111 *
1112 * This gives the fresh information, but may access the activity manager so is slower.
1113 */
1114 public boolean isUidActiveSynced(int uid) {
1115 if (isUidActive(uid)) { // Use the cached one first.
1116 return true;
1117 }
1118 final long start = mStatLogger.getTime();
1119
1120 final boolean ret = mActivityManagerInternal.isUidActive(uid);
1121 mStatLogger.logDurationStat(Stats.IS_UID_ACTIVE_RAW, start);
1122
1123 return ret;
1124 }
1125
1126 /**
Makoto Onuki2206af32017-11-21 16:25:35 -08001127 * @return whether a UID is in the foreground or not.
1128 *
Makoto Onuki15407842018-01-19 14:23:11 -08001129 * Note this information is based on the UID proc state callback, meaning it's updated
1130 * asynchronously and may subtly be stale. If the fresh data is needed, use
1131 * {@link ActivityManagerInternal#getUidProcessState} instead.
Makoto Onuki2206af32017-11-21 16:25:35 -08001132 */
Makoto Onukiadb50d82018-01-29 16:20:30 -08001133 public boolean isUidInForeground(int uid) {
Makoto Onuki9cc471c2018-01-23 12:33:56 -08001134 if (UserHandle.isCore(uid)) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001135 return true;
1136 }
1137 synchronized (mLock) {
1138 return mForegroundUids.get(uid);
1139 }
1140 }
1141
Makoto Onuki2206af32017-11-21 16:25:35 -08001142 /**
1143 * @return whether force all apps standby is enabled or not.
1144 *
Makoto Onuki2206af32017-11-21 16:25:35 -08001145 */
1146 boolean isForceAllAppsStandbyEnabled() {
Makoto Onuki9be01402017-11-10 13:22:26 -08001147 synchronized (mLock) {
1148 return mForceAllAppsStandby;
1149 }
1150 }
1151
Makoto Onuki2206af32017-11-21 16:25:35 -08001152 /**
1153 * @return whether a UID/package has {@code OP_RUN_ANY_IN_BACKGROUND} allowed or not.
1154 *
1155 * Note clients normally shouldn't need to access it. It's only for dumpsys.
1156 */
Makoto Onuki9be01402017-11-10 13:22:26 -08001157 public boolean isRunAnyInBackgroundAppOpsAllowed(int uid, @NonNull String packageName) {
1158 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001159 return !isRunAnyRestrictedLocked(uid, packageName);
Makoto Onuki9be01402017-11-10 13:22:26 -08001160 }
1161 }
1162
Makoto Onuki2206af32017-11-21 16:25:35 -08001163 /**
1164 * @return whether a UID is in the user / system defined power-save whitelist or not.
1165 *
1166 * Note clients normally shouldn't need to access it. It's only for dumpsys.
1167 */
1168 public boolean isUidPowerSaveWhitelisted(int uid) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001169 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001170 return ArrayUtils.contains(mPowerWhitelistedAllAppIds, UserHandle.getAppId(uid));
Makoto Onuki9be01402017-11-10 13:22:26 -08001171 }
1172 }
1173
Makoto Onuki2206af32017-11-21 16:25:35 -08001174 /**
1175 * @return whether a UID is in the temp power-save whitelist or not.
1176 *
1177 * Note clients normally shouldn't need to access it. It's only for dumpsys.
1178 */
1179 public boolean isUidTempPowerSaveWhitelisted(int uid) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001180 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001181 return ArrayUtils.contains(mTempWhitelistedAppIds, UserHandle.getAppId(uid));
1182 }
1183 }
1184
1185 public void dump(PrintWriter pw, String indent) {
1186 synchronized (mLock) {
1187 pw.print(indent);
Suprabh Shukla4deb8522018-01-08 16:27:10 -08001188 pw.println("Forced App Standby Feature enabled: " + mForcedAppStandbyEnabled);
1189
1190 pw.print(indent);
Makoto Onuki2206af32017-11-21 16:25:35 -08001191 pw.print("Force all apps standby: ");
1192 pw.println(isForceAllAppsStandbyEnabled());
1193
1194 pw.print(indent);
Nancy Zheng525aaa12018-01-12 11:45:37 -08001195 pw.print("Small Battery Device: ");
1196 pw.println(isSmallBatteryDevice());
1197
1198 pw.print(indent);
1199 pw.print("Force all apps standby for small battery device: ");
1200 pw.println(mForceAllAppStandbyForSmallBattery);
1201
1202 pw.print(indent);
1203 pw.print("Plugged In: ");
1204 pw.println(mIsPluggedIn);
1205
1206 pw.print(indent);
Makoto Onukiadb50d82018-01-29 16:20:30 -08001207 pw.print("Active uids: ");
1208 dumpUids(pw, mActiveUids);
Makoto Onuki2206af32017-11-21 16:25:35 -08001209
Makoto Onukiadb50d82018-01-29 16:20:30 -08001210 pw.print(indent);
1211 pw.print("Foreground uids: ");
1212 dumpUids(pw, mForegroundUids);
Makoto Onuki2206af32017-11-21 16:25:35 -08001213
1214 pw.print(indent);
1215 pw.print("Whitelist appids: ");
1216 pw.println(Arrays.toString(mPowerWhitelistedAllAppIds));
1217
1218 pw.print(indent);
1219 pw.print("Temp whitelist appids: ");
1220 pw.println(Arrays.toString(mTempWhitelistedAppIds));
1221
1222 pw.print(indent);
Makoto Onukieb898f12018-01-23 15:26:27 -08001223 pw.println("Exempted packages:");
1224 for (int i = 0; i < mExemptedPackages.size(); i++) {
1225 pw.print(indent);
1226 pw.print(" User ");
1227 pw.print(mExemptedPackages.keyAt(i));
1228 pw.println();
1229
1230 for (int j = 0; j < mExemptedPackages.sizeAt(i); j++) {
1231 pw.print(indent);
1232 pw.print(" ");
1233 pw.print(mExemptedPackages.valueAt(i, j));
1234 pw.println();
1235 }
1236 }
1237 pw.println();
1238
1239 pw.print(indent);
Makoto Onuki2206af32017-11-21 16:25:35 -08001240 pw.println("Restricted packages:");
1241 for (Pair<Integer, String> uidAndPackage : mRunAnyRestrictedPackages) {
1242 pw.print(indent);
1243 pw.print(" ");
1244 pw.print(UserHandle.formatUid(uidAndPackage.first));
1245 pw.print(" ");
1246 pw.print(uidAndPackage.second);
1247 pw.println();
1248 }
Makoto Onukieb898f12018-01-23 15:26:27 -08001249
1250 mStatLogger.dump(pw, indent);
Makoto Onuki2206af32017-11-21 16:25:35 -08001251 }
1252 }
1253
Makoto Onukiadb50d82018-01-29 16:20:30 -08001254 private void dumpUids(PrintWriter pw, SparseBooleanArray array) {
1255 pw.print("[");
1256
1257 String sep = "";
1258 for (int i = 0; i < array.size(); i++) {
1259 if (array.valueAt(i)) {
1260 pw.print(sep);
1261 pw.print(UserHandle.formatUid(array.keyAt(i)));
1262 sep = " ";
1263 }
1264 }
1265 pw.println("]");
1266 }
1267
Makoto Onuki2206af32017-11-21 16:25:35 -08001268 public void dumpProto(ProtoOutputStream proto, long fieldId) {
1269 synchronized (mLock) {
1270 final long token = proto.start(fieldId);
1271
1272 proto.write(ForceAppStandbyTrackerProto.FORCE_ALL_APPS_STANDBY, mForceAllAppsStandby);
Nancy Zheng525aaa12018-01-12 11:45:37 -08001273 proto.write(ForceAppStandbyTrackerProto.IS_SMALL_BATTERY_DEVICE,
1274 isSmallBatteryDevice());
1275 proto.write(ForceAppStandbyTrackerProto.FORCE_ALL_APPS_STANDBY_FOR_SMALL_BATTERY,
1276 mForceAllAppStandbyForSmallBattery);
Makoto Onukieb898f12018-01-23 15:26:27 -08001277 proto.write(ForceAppStandbyTrackerProto.IS_PLUGGED_IN, mIsPluggedIn);
Makoto Onuki2206af32017-11-21 16:25:35 -08001278
Makoto Onukiadb50d82018-01-29 16:20:30 -08001279 for (int i = 0; i < mActiveUids.size(); i++) {
1280 if (mActiveUids.valueAt(i)) {
1281 proto.write(ForceAppStandbyTrackerProto.ACTIVE_UIDS,
1282 mActiveUids.keyAt(i));
1283 }
1284 }
1285
Makoto Onuki2206af32017-11-21 16:25:35 -08001286 for (int i = 0; i < mForegroundUids.size(); i++) {
1287 if (mForegroundUids.valueAt(i)) {
1288 proto.write(ForceAppStandbyTrackerProto.FOREGROUND_UIDS,
1289 mForegroundUids.keyAt(i));
1290 }
1291 }
1292
1293 for (int appId : mPowerWhitelistedAllAppIds) {
1294 proto.write(ForceAppStandbyTrackerProto.POWER_SAVE_WHITELIST_APP_IDS, appId);
1295 }
1296
1297 for (int appId : mTempWhitelistedAppIds) {
1298 proto.write(ForceAppStandbyTrackerProto.TEMP_POWER_SAVE_WHITELIST_APP_IDS, appId);
1299 }
1300
Makoto Onukieb898f12018-01-23 15:26:27 -08001301 for (int i = 0; i < mExemptedPackages.size(); i++) {
1302 for (int j = 0; j < mExemptedPackages.sizeAt(i); j++) {
1303 final long token2 = proto.start(
1304 ForceAppStandbyTrackerProto.EXEMPTED_PACKAGES);
1305
1306 proto.write(ExemptedPackage.USER_ID, mExemptedPackages.keyAt(i));
1307 proto.write(ExemptedPackage.PACKAGE_NAME, mExemptedPackages.valueAt(i, j));
1308
1309 proto.end(token2);
1310 }
1311 }
1312
Makoto Onuki2206af32017-11-21 16:25:35 -08001313 for (Pair<Integer, String> uidAndPackage : mRunAnyRestrictedPackages) {
1314 final long token2 = proto.start(
1315 ForceAppStandbyTrackerProto.RUN_ANY_IN_BACKGROUND_RESTRICTED_PACKAGES);
1316 proto.write(RunAnyInBackgroundRestrictedPackages.UID, uidAndPackage.first);
1317 proto.write(RunAnyInBackgroundRestrictedPackages.PACKAGE_NAME,
1318 uidAndPackage.second);
1319 proto.end(token2);
1320 }
Makoto Onukieb898f12018-01-23 15:26:27 -08001321
1322 mStatLogger.dumpProto(proto, ForceAppStandbyTrackerProto.STATS);
1323
Makoto Onuki2206af32017-11-21 16:25:35 -08001324 proto.end(token);
Makoto Onuki9be01402017-11-10 13:22:26 -08001325 }
1326 }
1327}