blob: 3a7b5d6835077549427f5c02b1f4ee79b6e3f27d [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;
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -070056import com.android.internal.util.IndentingPrintWriter;
Makoto Onuki9be01402017-11-10 13:22:26 -080057import com.android.internal.util.Preconditions;
Makoto Onuki49392d32018-04-11 13:51:02 -070058import com.android.internal.util.StatLogger;
Makoto Onukieb898f12018-01-23 15:26:27 -080059import com.android.server.ForceAppStandbyTrackerProto.ExemptedPackage;
Makoto Onuki2206af32017-11-21 16:25:35 -080060import com.android.server.ForceAppStandbyTrackerProto.RunAnyInBackgroundRestrictedPackages;
Makoto Onuki9be01402017-11-10 13:22:26 -080061
Makoto Onuki2206af32017-11-21 16:25:35 -080062import java.io.PrintWriter;
63import java.util.Arrays;
Makoto Onuki9be01402017-11-10 13:22:26 -080064import java.util.List;
65
66/**
Makoto Onuki2206af32017-11-21 16:25:35 -080067 * Class to keep track of the information related to "force app standby", which includes:
68 * - OP_RUN_ANY_IN_BACKGROUND for each package
Makoto Onukiadb50d82018-01-29 16:20:30 -080069 * - UID foreground/active state
Makoto Onuki2206af32017-11-21 16:25:35 -080070 * - User+system power save whitelist
71 * - Temporary power save whitelist
72 * - Global "force all apps standby" mode enforced by battery saver.
Makoto Onuki9be01402017-11-10 13:22:26 -080073 *
Makoto Onuki2206af32017-11-21 16:25:35 -080074 * 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 Onukic871c872018-03-19 09:39:56 -070078 private static final String TAG = "AppStateTracker";
79 private static final boolean DEBUG = false;
Makoto Onuki9be01402017-11-10 13:22:26 -080080
81 private final Object mLock = new Object();
82 private final Context mContext;
83
Makoto Onuki2206af32017-11-21 16:25:35 -080084 @VisibleForTesting
85 static final int TARGET_OP = AppOpsManager.OP_RUN_ANY_IN_BACKGROUND;
86
87 IActivityManager mIActivityManager;
Makoto Onukie4918212018-02-06 11:30:15 -080088 ActivityManagerInternal mActivityManagerInternal;
Makoto Onuki9be01402017-11-10 13:22:26 -080089 AppOpsManager mAppOpsManager;
90 IAppOpsService mAppOpsService;
91 PowerManagerInternal mPowerManagerInternal;
Makoto Onukieb898f12018-01-23 15:26:27 -080092 StandbyTracker mStandbyTracker;
93 UsageStatsManagerInternal mUsageStatsManagerInternal;
Makoto Onuki9be01402017-11-10 13:22:26 -080094
Makoto Onuki2206af32017-11-21 16:25:35 -080095 private final MyHandler mHandler;
Makoto Onuki9be01402017-11-10 13:22:26 -080096
Nancy Zheng525aaa12018-01-12 11:45:37 -080097 @VisibleForTesting
98 FeatureFlagsObserver mFlagsObserver;
99
Makoto Onuki9be01402017-11-10 13:22:26 -0800100 /**
101 * Pair of (uid (not user-id), packageName) with OP_RUN_ANY_IN_BACKGROUND *not* allowed.
102 */
103 @GuardedBy("mLock")
Makoto Onuki2206af32017-11-21 16:25:35 -0800104 final ArraySet<Pair<Integer, String>> mRunAnyRestrictedPackages = new ArraySet<>();
Makoto Onuki9be01402017-11-10 13:22:26 -0800105
Makoto Onukiadb50d82018-01-29 16:20:30 -0800106 /** UIDs that are active. */
107 @GuardedBy("mLock")
108 final SparseBooleanArray mActiveUids = new SparseBooleanArray();
109
110 /** UIDs that are in the foreground. */
Makoto Onuki9be01402017-11-10 13:22:26 -0800111 @GuardedBy("mLock")
112 final SparseBooleanArray mForegroundUids = new SparseBooleanArray();
113
Makoto Onuki71755c92018-01-16 14:15:44 -0800114 /**
115 * System except-idle + user whitelist in the device idle controller.
116 */
Makoto Onuki9be01402017-11-10 13:22:26 -0800117 @GuardedBy("mLock")
Makoto Onuki2206af32017-11-21 16:25:35 -0800118 private int[] mPowerWhitelistedAllAppIds = new int[0];
119
Suprabh Shukla5bf49812018-05-24 18:38:50 -0700120 /**
121 * User whitelisted apps in the device idle controller.
122 */
123 @GuardedBy("mLock")
124 private int[] mPowerWhitelistedUserAppIds = new int[0];
125
Makoto Onuki2206af32017-11-21 16:25:35 -0800126 @GuardedBy("mLock")
127 private int[] mTempWhitelistedAppIds = mPowerWhitelistedAllAppIds;
128
Makoto Onukieb898f12018-01-23 15:26:27 -0800129 /**
130 * Per-user packages that are in the EXEMPT bucket.
131 */
132 @GuardedBy("mLock")
133 private final SparseSetArray<String> mExemptedPackages = new SparseSetArray<>();
134
Makoto Onuki2206af32017-11-21 16:25:35 -0800135 @GuardedBy("mLock")
Makoto Onuki9be01402017-11-10 13:22:26 -0800136 final ArraySet<Listener> mListeners = new ArraySet<>();
137
138 @GuardedBy("mLock")
139 boolean mStarted;
140
Nancy Zheng525aaa12018-01-12 11:45:37 -0800141 /**
142 * Only used for small battery use-case.
143 */
Makoto Onuki9be01402017-11-10 13:22:26 -0800144 @GuardedBy("mLock")
Nancy Zheng525aaa12018-01-12 11:45:37 -0800145 boolean mIsPluggedIn;
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800146
147 @GuardedBy("mLock")
Nancy Zheng525aaa12018-01-12 11:45:37 -0800148 boolean mBatterySaverEnabled;
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800149
Nancy Zheng525aaa12018-01-12 11:45:37 -0800150 /**
151 * True if the forced app standby is currently enabled
152 */
153 @GuardedBy("mLock")
154 boolean mForceAllAppsStandby;
155
156 /**
157 * True if the forced app standby for small battery devices feature is enabled in settings
158 */
159 @GuardedBy("mLock")
160 boolean mForceAllAppStandbyForSmallBattery;
161
162 /**
163 * True if the forced app standby feature is enabled in settings
164 */
165 @GuardedBy("mLock")
166 boolean mForcedAppStandbyEnabled;
167
Makoto Onukieb898f12018-01-23 15:26:27 -0800168 interface Stats {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800169 int UID_FG_STATE_CHANGED = 0;
170 int UID_ACTIVE_STATE_CHANGED = 1;
171 int RUN_ANY_CHANGED = 2;
172 int ALL_UNWHITELISTED = 3;
173 int ALL_WHITELIST_CHANGED = 4;
174 int TEMP_WHITELIST_CHANGED = 5;
175 int EXEMPT_CHANGED = 6;
176 int FORCE_ALL_CHANGED = 7;
177 int FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED = 8;
Makoto Onukie4918212018-02-06 11:30:15 -0800178
179 int IS_UID_ACTIVE_CACHED = 9;
180 int IS_UID_ACTIVE_RAW = 10;
Makoto Onukieb898f12018-01-23 15:26:27 -0800181 }
182
183 private final StatLogger mStatLogger = new StatLogger(new String[] {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800184 "UID_FG_STATE_CHANGED",
185 "UID_ACTIVE_STATE_CHANGED",
Makoto Onukieb898f12018-01-23 15:26:27 -0800186 "RUN_ANY_CHANGED",
187 "ALL_UNWHITELISTED",
188 "ALL_WHITELIST_CHANGED",
189 "TEMP_WHITELIST_CHANGED",
190 "EXEMPT_CHANGED",
191 "FORCE_ALL_CHANGED",
192 "FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED",
Makoto Onukie4918212018-02-06 11:30:15 -0800193
194 "IS_UID_ACTIVE_CACHED",
195 "IS_UID_ACTIVE_RAW",
Makoto Onukieb898f12018-01-23 15:26:27 -0800196 });
197
Nancy Zheng525aaa12018-01-12 11:45:37 -0800198 @VisibleForTesting
199 class FeatureFlagsObserver extends ContentObserver {
200 FeatureFlagsObserver() {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800201 super(null);
202 }
203
204 void register() {
205 mContext.getContentResolver().registerContentObserver(
206 Settings.Global.getUriFor(Settings.Global.FORCED_APP_STANDBY_ENABLED),
207 false, this);
Nancy Zheng525aaa12018-01-12 11:45:37 -0800208
209 mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor(
210 Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED), false, this);
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800211 }
212
213 boolean isForcedAppStandbyEnabled() {
Makoto Onukieb898f12018-01-23 15:26:27 -0800214 return injectGetGlobalSettingInt(Settings.Global.FORCED_APP_STANDBY_ENABLED, 1) == 1;
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800215 }
216
Nancy Zheng525aaa12018-01-12 11:45:37 -0800217 boolean isForcedAppStandbyForSmallBatteryEnabled() {
Makoto Onukieb898f12018-01-23 15:26:27 -0800218 return injectGetGlobalSettingInt(
Nancy Zheng525aaa12018-01-12 11:45:37 -0800219 Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED, 0) == 1;
220 }
221
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800222 @Override
Nancy Zheng525aaa12018-01-12 11:45:37 -0800223 public void onChange(boolean selfChange, Uri uri) {
224 if (Settings.Global.getUriFor(Settings.Global.FORCED_APP_STANDBY_ENABLED).equals(uri)) {
225 final boolean enabled = isForcedAppStandbyEnabled();
226 synchronized (mLock) {
227 if (mForcedAppStandbyEnabled == enabled) {
228 return;
229 }
230 mForcedAppStandbyEnabled = enabled;
231 if (DEBUG) {
232 Slog.d(TAG,"Forced app standby feature flag changed: "
233 + mForcedAppStandbyEnabled);
234 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800235 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800236 mHandler.notifyForcedAppStandbyFeatureFlagChanged();
237 } else if (Settings.Global.getUriFor(
238 Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED).equals(uri)) {
239 final boolean enabled = isForcedAppStandbyForSmallBatteryEnabled();
240 synchronized (mLock) {
241 if (mForceAllAppStandbyForSmallBattery == enabled) {
242 return;
243 }
244 mForceAllAppStandbyForSmallBattery = enabled;
245 if (DEBUG) {
246 Slog.d(TAG, "Forced app standby for small battery feature flag changed: "
247 + mForceAllAppStandbyForSmallBattery);
248 }
249 updateForceAllAppStandbyState();
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800250 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800251 } else {
252 Slog.w(TAG, "Unexpected feature flag uri encountered: " + uri);
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800253 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800254 }
255 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800256
257 public static abstract class Listener {
Makoto Onuki2206af32017-11-21 16:25:35 -0800258 /**
259 * This is called when the OP_RUN_ANY_IN_BACKGROUND appops changed for a package.
260 */
Makoto Onukie4918212018-02-06 11:30:15 -0800261 private void onRunAnyAppOpsChanged(AppStateTracker sender,
Makoto Onuki2206af32017-11-21 16:25:35 -0800262 int uid, @NonNull String packageName) {
Christopher Tate20afddd2018-02-28 15:19:19 -0800263 updateJobsForUidPackage(uid, packageName, sender.isUidActive(uid));
Makoto Onuki2206af32017-11-21 16:25:35 -0800264
Suprabh Shuklac25447d2018-01-19 16:43:35 -0800265 if (!sender.areAlarmsRestricted(uid, packageName, /*allowWhileIdle=*/ false)) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800266 unblockAlarmsForUidPackage(uid, packageName);
Suprabh Shuklac25447d2018-01-19 16:43:35 -0800267 } else if (!sender.areAlarmsRestricted(uid, packageName, /*allowWhileIdle=*/ true)){
268 // we need to deliver the allow-while-idle alarms for this uid, package
269 unblockAllUnrestrictedAlarms();
Makoto Onuki2206af32017-11-21 16:25:35 -0800270 }
Christopher Tatec7933ac2018-03-12 17:57:09 -0700271
272 if (!sender.isRunAnyInBackgroundAppOpsAllowed(uid, packageName)) {
273 Slog.v(TAG, "Package " + packageName + "/" + uid
274 + " toggled into fg service restriction");
275 stopForegroundServicesForUidPackage(uid, packageName);
276 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800277 }
278
Makoto Onuki2206af32017-11-21 16:25:35 -0800279 /**
280 * This is called when the foreground state changed for a UID.
281 */
Makoto Onukie4918212018-02-06 11:30:15 -0800282 private void onUidForegroundStateChanged(AppStateTracker sender, int uid) {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800283 onUidForeground(uid, sender.isUidInForeground(uid));
284 }
285
286 /**
287 * This is called when the active/idle state changed for a UID.
288 */
Makoto Onukie4918212018-02-06 11:30:15 -0800289 private void onUidActiveStateChanged(AppStateTracker sender, int uid) {
Christopher Tate20afddd2018-02-28 15:19:19 -0800290 final boolean isActive = sender.isUidActive(uid);
Makoto Onuki2206af32017-11-21 16:25:35 -0800291
Christopher Tate20afddd2018-02-28 15:19:19 -0800292 updateJobsForUid(uid, isActive);
293
294 if (isActive) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800295 unblockAlarmsForUid(uid);
296 }
297 }
298
299 /**
300 * This is called when an app-id(s) is removed from the power save whitelist.
301 */
Makoto Onukie4918212018-02-06 11:30:15 -0800302 private void onPowerSaveUnwhitelisted(AppStateTracker sender) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800303 updateAllJobs();
304 unblockAllUnrestrictedAlarms();
305 }
306
307 /**
308 * This is called when the power save whitelist changes, excluding the
309 * {@link #onPowerSaveUnwhitelisted} case.
310 */
Makoto Onukie4918212018-02-06 11:30:15 -0800311 private void onPowerSaveWhitelistedChanged(AppStateTracker sender) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800312 updateAllJobs();
313 }
314
315 /**
316 * This is called when the temp whitelist changes.
317 */
Makoto Onukie4918212018-02-06 11:30:15 -0800318 private void onTempPowerSaveWhitelistChanged(AppStateTracker sender) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800319
320 // TODO This case happens rather frequently; consider optimizing and update jobs
321 // only for affected app-ids.
322
323 updateAllJobs();
Makoto Onukieb898f12018-01-23 15:26:27 -0800324
325 // Note when an app is just put in the temp whitelist, we do *not* drain pending alarms.
326 }
327
328 /**
329 * This is called when the EXEMPT bucket is updated.
330 */
Makoto Onukie4918212018-02-06 11:30:15 -0800331 private void onExemptChanged(AppStateTracker sender) {
Makoto Onukieb898f12018-01-23 15:26:27 -0800332 // This doesn't happen very often, so just re-evaluate all jobs / alarms.
333 updateAllJobs();
334 unblockAllUnrestrictedAlarms();
Makoto Onuki2206af32017-11-21 16:25:35 -0800335 }
336
337 /**
338 * This is called when the global "force all apps standby" flag changes.
339 */
Makoto Onukie4918212018-02-06 11:30:15 -0800340 private void onForceAllAppsStandbyChanged(AppStateTracker sender) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800341 updateAllJobs();
342
343 if (!sender.isForceAllAppsStandbyEnabled()) {
344 unblockAllUnrestrictedAlarms();
345 }
346 }
347
348 /**
349 * Called when the job restrictions for multiple UIDs might have changed, so the job
350 * scheduler should re-evaluate all restrictions for all jobs.
351 */
352 public void updateAllJobs() {
353 }
354
355 /**
356 * Called when the job restrictions for a UID might have changed, so the job
357 * scheduler should re-evaluate all restrictions for all jobs.
358 */
Christopher Tate20afddd2018-02-28 15:19:19 -0800359 public void updateJobsForUid(int uid, boolean isNowActive) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800360 }
361
362 /**
363 * Called when the job restrictions for a UID - package might have changed, so the job
364 * scheduler should re-evaluate all restrictions for all jobs.
365 */
Christopher Tate20afddd2018-02-28 15:19:19 -0800366 public void updateJobsForUidPackage(int uid, String packageName, boolean isNowActive) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800367 }
368
369 /**
Christopher Tatec7933ac2018-03-12 17:57:09 -0700370 * Called when an app goes into forced app standby and its foreground
371 * services need to be removed from that state.
372 */
373 public void stopForegroundServicesForUidPackage(int uid, String packageName) {
374 }
375
376 /**
Makoto Onuki2206af32017-11-21 16:25:35 -0800377 * Called when the job restrictions for multiple UIDs might have changed, so the alarm
378 * manager should re-evaluate all restrictions for all blocked jobs.
379 */
380 public void unblockAllUnrestrictedAlarms() {
381 }
382
383 /**
384 * Called when all jobs for a specific UID are unblocked.
385 */
386 public void unblockAlarmsForUid(int uid) {
387 }
388
389 /**
390 * Called when all alarms for a specific UID - package are unblocked.
391 */
392 public void unblockAlarmsForUidPackage(int uid, String packageName) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800393 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800394
395 /**
396 * Called when a UID comes into the foreground or the background.
397 *
398 * @see #isUidInForeground(int)
399 */
400 public void onUidForeground(int uid, boolean foreground) {
401 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800402 }
403
Makoto Onukie4918212018-02-06 11:30:15 -0800404 public AppStateTracker(Context context, Looper looper) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800405 mContext = context;
Makoto Onuki2206af32017-11-21 16:25:35 -0800406 mHandler = new MyHandler(looper);
407 }
408
Makoto Onuki9be01402017-11-10 13:22:26 -0800409 /**
410 * Call it when the system is ready.
411 */
Makoto Onukie4918212018-02-06 11:30:15 -0800412 public void onSystemServicesReady() {
Makoto Onuki9be01402017-11-10 13:22:26 -0800413 synchronized (mLock) {
414 if (mStarted) {
415 return;
416 }
417 mStarted = true;
418
Makoto Onuki2206af32017-11-21 16:25:35 -0800419 mIActivityManager = Preconditions.checkNotNull(injectIActivityManager());
Makoto Onukie4918212018-02-06 11:30:15 -0800420 mActivityManagerInternal = Preconditions.checkNotNull(injectActivityManagerInternal());
Makoto Onuki2206af32017-11-21 16:25:35 -0800421 mAppOpsManager = Preconditions.checkNotNull(injectAppOpsManager());
422 mAppOpsService = Preconditions.checkNotNull(injectIAppOpsService());
423 mPowerManagerInternal = Preconditions.checkNotNull(injectPowerManagerInternal());
Makoto Onukieb898f12018-01-23 15:26:27 -0800424 mUsageStatsManagerInternal = Preconditions.checkNotNull(
425 injectUsageStatsManagerInternal());
426
Nancy Zheng525aaa12018-01-12 11:45:37 -0800427 mFlagsObserver = new FeatureFlagsObserver();
428 mFlagsObserver.register();
429 mForcedAppStandbyEnabled = mFlagsObserver.isForcedAppStandbyEnabled();
430 mForceAllAppStandbyForSmallBattery =
431 mFlagsObserver.isForcedAppStandbyForSmallBatteryEnabled();
Makoto Onukieb898f12018-01-23 15:26:27 -0800432 mStandbyTracker = new StandbyTracker();
433 mUsageStatsManagerInternal.addAppIdleStateChangeListener(mStandbyTracker);
Makoto Onuki9be01402017-11-10 13:22:26 -0800434
435 try {
Makoto Onuki2206af32017-11-21 16:25:35 -0800436 mIActivityManager.registerUidObserver(new UidObserver(),
Makoto Onukiadb50d82018-01-29 16:20:30 -0800437 ActivityManager.UID_OBSERVER_GONE
438 | ActivityManager.UID_OBSERVER_IDLE
439 | ActivityManager.UID_OBSERVER_ACTIVE
440 | ActivityManager.UID_OBSERVER_PROCSTATE,
Makoto Onuki9be01402017-11-10 13:22:26 -0800441 ActivityManager.PROCESS_STATE_UNKNOWN, null);
Makoto Onuki2206af32017-11-21 16:25:35 -0800442 mAppOpsService.startWatchingMode(TARGET_OP, null,
Makoto Onuki9be01402017-11-10 13:22:26 -0800443 new AppOpsWatcher());
444 } catch (RemoteException e) {
445 // shouldn't happen.
446 }
447
Makoto Onuki2206af32017-11-21 16:25:35 -0800448 IntentFilter filter = new IntentFilter();
449 filter.addAction(Intent.ACTION_USER_REMOVED);
Nancy Zheng525aaa12018-01-12 11:45:37 -0800450 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800451 mContext.registerReceiver(new MyReceiver(), filter);
Makoto Onuki9be01402017-11-10 13:22:26 -0800452
453 refreshForcedAppStandbyUidPackagesLocked();
Makoto Onuki2206af32017-11-21 16:25:35 -0800454
455 mPowerManagerInternal.registerLowPowerModeObserver(
456 ServiceType.FORCE_ALL_APPS_STANDBY,
Nancy Zheng525aaa12018-01-12 11:45:37 -0800457 (state) -> {
458 synchronized (mLock) {
459 mBatterySaverEnabled = state.batterySaverEnabled;
460 updateForceAllAppStandbyState();
461 }
462 });
Makoto Onuki2206af32017-11-21 16:25:35 -0800463
Nancy Zheng525aaa12018-01-12 11:45:37 -0800464 mBatterySaverEnabled = mPowerManagerInternal.getLowPowerState(
465 ServiceType.FORCE_ALL_APPS_STANDBY).batterySaverEnabled;
466
467 updateForceAllAppStandbyState();
Makoto Onuki9be01402017-11-10 13:22:26 -0800468 }
469 }
470
Makoto Onuki2206af32017-11-21 16:25:35 -0800471 @VisibleForTesting
472 AppOpsManager injectAppOpsManager() {
473 return mContext.getSystemService(AppOpsManager.class);
474 }
475
476 @VisibleForTesting
477 IAppOpsService injectIAppOpsService() {
478 return IAppOpsService.Stub.asInterface(
479 ServiceManager.getService(Context.APP_OPS_SERVICE));
480 }
481
482 @VisibleForTesting
483 IActivityManager injectIActivityManager() {
484 return ActivityManager.getService();
485 }
486
487 @VisibleForTesting
Makoto Onukie4918212018-02-06 11:30:15 -0800488 ActivityManagerInternal injectActivityManagerInternal() {
489 return LocalServices.getService(ActivityManagerInternal.class);
490 }
491
492 @VisibleForTesting
Makoto Onuki2206af32017-11-21 16:25:35 -0800493 PowerManagerInternal injectPowerManagerInternal() {
494 return LocalServices.getService(PowerManagerInternal.class);
495 }
496
Nancy Zheng525aaa12018-01-12 11:45:37 -0800497 @VisibleForTesting
Makoto Onukieb898f12018-01-23 15:26:27 -0800498 UsageStatsManagerInternal injectUsageStatsManagerInternal() {
499 return LocalServices.getService(UsageStatsManagerInternal.class);
500 }
501
502 @VisibleForTesting
Nancy Zheng525aaa12018-01-12 11:45:37 -0800503 boolean isSmallBatteryDevice() {
504 return ActivityManager.isSmallBatteryDevice();
505 }
506
Makoto Onukieb898f12018-01-23 15:26:27 -0800507 @VisibleForTesting
508 int injectGetGlobalSettingInt(String key, int def) {
509 return Settings.Global.getInt(mContext.getContentResolver(), key, def);
510 }
511
Makoto Onuki9be01402017-11-10 13:22:26 -0800512 /**
Makoto Onuki2206af32017-11-21 16:25:35 -0800513 * Update {@link #mRunAnyRestrictedPackages} with the current app ops state.
Makoto Onuki9be01402017-11-10 13:22:26 -0800514 */
Andreas Gampea36dc622018-02-05 17:19:22 -0800515 @GuardedBy("mLock")
Makoto Onuki9be01402017-11-10 13:22:26 -0800516 private void refreshForcedAppStandbyUidPackagesLocked() {
Makoto Onuki2206af32017-11-21 16:25:35 -0800517 mRunAnyRestrictedPackages.clear();
518 final List<PackageOps> ops = mAppOpsManager.getPackagesForOps(
519 new int[] {TARGET_OP});
Makoto Onuki9be01402017-11-10 13:22:26 -0800520
521 if (ops == null) {
522 return;
523 }
524 final int size = ops.size();
525 for (int i = 0; i < size; i++) {
526 final AppOpsManager.PackageOps pkg = ops.get(i);
527 final List<AppOpsManager.OpEntry> entries = ops.get(i).getOps();
528
529 for (int j = 0; j < entries.size(); j++) {
530 AppOpsManager.OpEntry ent = entries.get(j);
Makoto Onuki2206af32017-11-21 16:25:35 -0800531 if (ent.getOp() != TARGET_OP) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800532 continue;
533 }
534 if (ent.getMode() != AppOpsManager.MODE_ALLOWED) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800535 mRunAnyRestrictedPackages.add(Pair.create(
Makoto Onuki9be01402017-11-10 13:22:26 -0800536 pkg.getUid(), pkg.getPackageName()));
537 }
538 }
539 }
540 }
541
Nancy Zheng525aaa12018-01-12 11:45:37 -0800542 private void updateForceAllAppStandbyState() {
543 synchronized (mLock) {
544 if (mForceAllAppStandbyForSmallBattery && isSmallBatteryDevice()) {
545 toggleForceAllAppsStandbyLocked(!mIsPluggedIn);
546 } else {
547 toggleForceAllAppsStandbyLocked(mBatterySaverEnabled);
548 }
549 }
550 }
551
Makoto Onuki2206af32017-11-21 16:25:35 -0800552 /**
553 * Update {@link #mForceAllAppsStandby} and notifies the listeners.
554 */
Andreas Gampea36dc622018-02-05 17:19:22 -0800555 @GuardedBy("mLock")
Nancy Zheng525aaa12018-01-12 11:45:37 -0800556 private void toggleForceAllAppsStandbyLocked(boolean enable) {
557 if (enable == mForceAllAppsStandby) {
558 return;
Makoto Onuki12391f22018-01-18 21:44:28 +0000559 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800560 mForceAllAppsStandby = enable;
561
562 mHandler.notifyForceAllAppsStandbyChanged();
Makoto Onuki9be01402017-11-10 13:22:26 -0800563 }
564
Andreas Gampea36dc622018-02-05 17:19:22 -0800565 @GuardedBy("mLock")
Makoto Onuki9be01402017-11-10 13:22:26 -0800566 private int findForcedAppStandbyUidPackageIndexLocked(int uid, @NonNull String packageName) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800567 final int size = mRunAnyRestrictedPackages.size();
568 if (size > 8) {
569 return mRunAnyRestrictedPackages.indexOf(Pair.create(uid, packageName));
570 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800571 for (int i = 0; i < size; i++) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800572 final Pair<Integer, String> pair = mRunAnyRestrictedPackages.valueAt(i);
Makoto Onuki9be01402017-11-10 13:22:26 -0800573
574 if ((pair.first == uid) && packageName.equals(pair.second)) {
575 return i;
576 }
577 }
578 return -1;
579 }
580
581 /**
Makoto Onuki2206af32017-11-21 16:25:35 -0800582 * @return whether a uid package-name pair is in mRunAnyRestrictedPackages.
Makoto Onuki9be01402017-11-10 13:22:26 -0800583 */
Andreas Gampea36dc622018-02-05 17:19:22 -0800584 @GuardedBy("mLock")
Makoto Onuki2206af32017-11-21 16:25:35 -0800585 boolean isRunAnyRestrictedLocked(int uid, @NonNull String packageName) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800586 return findForcedAppStandbyUidPackageIndexLocked(uid, packageName) >= 0;
587 }
588
Makoto Onuki2206af32017-11-21 16:25:35 -0800589 /**
590 * Add to / remove from {@link #mRunAnyRestrictedPackages}.
591 */
Andreas Gampea36dc622018-02-05 17:19:22 -0800592 @GuardedBy("mLock")
Makoto Onuki2206af32017-11-21 16:25:35 -0800593 boolean updateForcedAppStandbyUidPackageLocked(int uid, @NonNull String packageName,
Makoto Onuki9be01402017-11-10 13:22:26 -0800594 boolean restricted) {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800595 final int index = findForcedAppStandbyUidPackageIndexLocked(uid, packageName);
Makoto Onuki9be01402017-11-10 13:22:26 -0800596 final boolean wasRestricted = index >= 0;
597 if (wasRestricted == restricted) {
598 return false;
599 }
600 if (restricted) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800601 mRunAnyRestrictedPackages.add(Pair.create(uid, packageName));
Makoto Onuki9be01402017-11-10 13:22:26 -0800602 } else {
Makoto Onuki2206af32017-11-21 16:25:35 -0800603 mRunAnyRestrictedPackages.removeAt(index);
Makoto Onuki9be01402017-11-10 13:22:26 -0800604 }
605 return true;
606 }
607
Makoto Onukiadb50d82018-01-29 16:20:30 -0800608 private static boolean addUidToArray(SparseBooleanArray array, int uid) {
609 if (UserHandle.isCore(uid)) {
610 return false;
Makoto Onuki9be01402017-11-10 13:22:26 -0800611 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800612 if (array.get(uid)) {
613 return false;
614 }
615 array.put(uid, true);
616 return true;
Makoto Onuki9be01402017-11-10 13:22:26 -0800617 }
618
Makoto Onukiadb50d82018-01-29 16:20:30 -0800619 private static boolean removeUidFromArray(SparseBooleanArray array, int uid, boolean remove) {
620 if (UserHandle.isCore(uid)) {
621 return false;
Makoto Onuki9be01402017-11-10 13:22:26 -0800622 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800623 if (!array.get(uid)) {
624 return false;
625 }
626 if (remove) {
627 array.delete(uid);
628 } else {
629 array.put(uid, false);
630 }
631 return true;
Makoto Onuki9be01402017-11-10 13:22:26 -0800632 }
633
Makoto Onuki2206af32017-11-21 16:25:35 -0800634 private final class UidObserver extends IUidObserver.Stub {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800635 @Override
636 public void onUidStateChanged(int uid, int procState, long procStateSeq) {
Makoto Onuki4d298b52018-02-05 10:54:58 -0800637 mHandler.onUidStateChanged(uid, procState);
Makoto Onuki9be01402017-11-10 13:22:26 -0800638 }
639
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800640 @Override
641 public void onUidActive(int uid) {
Makoto Onuki4d298b52018-02-05 10:54:58 -0800642 mHandler.onUidActive(uid);
643 }
644
645 @Override
646 public void onUidGone(int uid, boolean disabled) {
647 mHandler.onUidGone(uid, disabled);
Makoto Onuki9be01402017-11-10 13:22:26 -0800648 }
649
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800650 @Override
651 public void onUidIdle(int uid, boolean disabled) {
Makoto Onuki4d298b52018-02-05 10:54:58 -0800652 mHandler.onUidIdle(uid, disabled);
Makoto Onuki9be01402017-11-10 13:22:26 -0800653 }
654
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800655 @Override
656 public void onUidCachedChanged(int uid, boolean cached) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800657 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800658 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800659
660 private final class AppOpsWatcher extends IAppOpsCallback.Stub {
661 @Override
662 public void opChanged(int op, int uid, String packageName) throws RemoteException {
Makoto Onuki2206af32017-11-21 16:25:35 -0800663 boolean restricted = false;
664 try {
665 restricted = mAppOpsService.checkOperation(TARGET_OP,
666 uid, packageName) != AppOpsManager.MODE_ALLOWED;
667 } catch (RemoteException e) {
668 // Shouldn't happen
669 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800670 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800671 if (updateForcedAppStandbyUidPackageLocked(uid, packageName, restricted)) {
672 mHandler.notifyRunAnyAppOpsChanged(uid, packageName);
673 }
674 }
675 }
676 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800677
Makoto Onuki2206af32017-11-21 16:25:35 -0800678 private final class MyReceiver extends BroadcastReceiver {
679 @Override
680 public void onReceive(Context context, Intent intent) {
681 if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
682 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
683 if (userId > 0) {
684 mHandler.doUserRemoved(userId);
Makoto Onuki9be01402017-11-10 13:22:26 -0800685 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800686 } else if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
687 synchronized (mLock) {
688 mIsPluggedIn = (intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0);
689 }
690 updateForceAllAppStandbyState();
Makoto Onuki9be01402017-11-10 13:22:26 -0800691 }
692 }
693 }
694
Makoto Onukieb898f12018-01-23 15:26:27 -0800695 final class StandbyTracker extends AppIdleStateChangeListener {
696 @Override
697 public void onAppIdleStateChanged(String packageName, int userId, boolean idle,
Amith Yamasani119be9a2018-02-18 22:23:00 -0800698 int bucket, int reason) {
Makoto Onukieb898f12018-01-23 15:26:27 -0800699 if (DEBUG) {
700 Slog.d(TAG,"onAppIdleStateChanged: " + packageName + " u" + userId
701 + (idle ? " idle" : " active") + " " + bucket);
702 }
703 final boolean changed;
704 if (bucket == UsageStatsManager.STANDBY_BUCKET_EXEMPTED) {
705 changed = mExemptedPackages.add(userId, packageName);
706 } else {
707 changed = mExemptedPackages.remove(userId, packageName);
708 }
709 if (changed) {
710 mHandler.notifyExemptChanged();
711 }
712 }
713
714 @Override
715 public void onParoleStateChanged(boolean isParoleOn) {
716 }
717 }
718
Makoto Onuki9be01402017-11-10 13:22:26 -0800719 private Listener[] cloneListeners() {
720 synchronized (mLock) {
721 return mListeners.toArray(new Listener[mListeners.size()]);
722 }
723 }
724
Makoto Onuki2206af32017-11-21 16:25:35 -0800725 private class MyHandler extends Handler {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800726 private static final int MSG_UID_ACTIVE_STATE_CHANGED = 0;
727 private static final int MSG_UID_FG_STATE_CHANGED = 1;
728 private static final int MSG_RUN_ANY_CHANGED = 3;
729 private static final int MSG_ALL_UNWHITELISTED = 4;
730 private static final int MSG_ALL_WHITELIST_CHANGED = 5;
731 private static final int MSG_TEMP_WHITELIST_CHANGED = 6;
732 private static final int MSG_FORCE_ALL_CHANGED = 7;
733 private static final int MSG_USER_REMOVED = 8;
734 private static final int MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED = 9;
735 private static final int MSG_EXEMPT_CHANGED = 10;
Makoto Onuki9be01402017-11-10 13:22:26 -0800736
Makoto Onuki4d298b52018-02-05 10:54:58 -0800737 private static final int MSG_ON_UID_STATE_CHANGED = 11;
738 private static final int MSG_ON_UID_ACTIVE = 12;
739 private static final int MSG_ON_UID_GONE = 13;
740 private static final int MSG_ON_UID_IDLE = 14;
741
Makoto Onuki2206af32017-11-21 16:25:35 -0800742 public MyHandler(Looper looper) {
743 super(looper);
Makoto Onuki9be01402017-11-10 13:22:26 -0800744 }
Makoto Onuki2206af32017-11-21 16:25:35 -0800745
Makoto Onukiadb50d82018-01-29 16:20:30 -0800746 public void notifyUidActiveStateChanged(int uid) {
747 obtainMessage(MSG_UID_ACTIVE_STATE_CHANGED, uid, 0).sendToTarget();
748 }
749
Makoto Onuki2206af32017-11-21 16:25:35 -0800750 public void notifyUidForegroundStateChanged(int uid) {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800751 obtainMessage(MSG_UID_FG_STATE_CHANGED, uid, 0).sendToTarget();
Makoto Onuki2206af32017-11-21 16:25:35 -0800752 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800753
Makoto Onuki2206af32017-11-21 16:25:35 -0800754 public void notifyRunAnyAppOpsChanged(int uid, @NonNull String packageName) {
755 obtainMessage(MSG_RUN_ANY_CHANGED, uid, 0, packageName).sendToTarget();
756 }
757
758 public void notifyAllUnwhitelisted() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800759 removeMessages(MSG_ALL_UNWHITELISTED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800760 obtainMessage(MSG_ALL_UNWHITELISTED).sendToTarget();
761 }
762
763 public void notifyAllWhitelistChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800764 removeMessages(MSG_ALL_WHITELIST_CHANGED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800765 obtainMessage(MSG_ALL_WHITELIST_CHANGED).sendToTarget();
766 }
767
768 public void notifyTempWhitelistChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800769 removeMessages(MSG_TEMP_WHITELIST_CHANGED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800770 obtainMessage(MSG_TEMP_WHITELIST_CHANGED).sendToTarget();
771 }
772
773 public void notifyForceAllAppsStandbyChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800774 removeMessages(MSG_FORCE_ALL_CHANGED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800775 obtainMessage(MSG_FORCE_ALL_CHANGED).sendToTarget();
776 }
777
Nancy Zheng525aaa12018-01-12 11:45:37 -0800778 public void notifyForcedAppStandbyFeatureFlagChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800779 removeMessages(MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED);
Nancy Zheng525aaa12018-01-12 11:45:37 -0800780 obtainMessage(MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED).sendToTarget();
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800781 }
782
Makoto Onukieb898f12018-01-23 15:26:27 -0800783 public void notifyExemptChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800784 removeMessages(MSG_EXEMPT_CHANGED);
Makoto Onukieb898f12018-01-23 15:26:27 -0800785 obtainMessage(MSG_EXEMPT_CHANGED).sendToTarget();
786 }
787
Makoto Onuki2206af32017-11-21 16:25:35 -0800788 public void doUserRemoved(int userId) {
789 obtainMessage(MSG_USER_REMOVED, userId, 0).sendToTarget();
790 }
791
Makoto Onuki4d298b52018-02-05 10:54:58 -0800792 public void onUidStateChanged(int uid, int procState) {
793 obtainMessage(MSG_ON_UID_STATE_CHANGED, uid, procState).sendToTarget();
794 }
795
796 public void onUidActive(int uid) {
797 obtainMessage(MSG_ON_UID_ACTIVE, uid, 0).sendToTarget();
798 }
799
800 public void onUidGone(int uid, boolean disabled) {
801 obtainMessage(MSG_ON_UID_GONE, uid, disabled ? 1 : 0).sendToTarget();
802 }
803
804 public void onUidIdle(int uid, boolean disabled) {
805 obtainMessage(MSG_ON_UID_IDLE, uid, disabled ? 1 : 0).sendToTarget();
806 }
807
Makoto Onuki2206af32017-11-21 16:25:35 -0800808 @Override
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800809 public void handleMessage(Message msg) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800810 switch (msg.what) {
811 case MSG_USER_REMOVED:
812 handleUserRemoved(msg.arg1);
813 return;
814 }
815
816 // Only notify the listeners when started.
817 synchronized (mLock) {
818 if (!mStarted) {
819 return;
820 }
821 }
Makoto Onukie4918212018-02-06 11:30:15 -0800822 final AppStateTracker sender = AppStateTracker.this;
Makoto Onuki2206af32017-11-21 16:25:35 -0800823
Makoto Onukieb898f12018-01-23 15:26:27 -0800824 long start = mStatLogger.getTime();
Makoto Onuki2206af32017-11-21 16:25:35 -0800825 switch (msg.what) {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800826 case MSG_UID_ACTIVE_STATE_CHANGED:
827 for (Listener l : cloneListeners()) {
828 l.onUidActiveStateChanged(sender, msg.arg1);
829 }
830 mStatLogger.logDurationStat(Stats.UID_ACTIVE_STATE_CHANGED, start);
831 return;
832
833 case MSG_UID_FG_STATE_CHANGED:
Makoto Onuki2206af32017-11-21 16:25:35 -0800834 for (Listener l : cloneListeners()) {
835 l.onUidForegroundStateChanged(sender, msg.arg1);
836 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800837 mStatLogger.logDurationStat(Stats.UID_FG_STATE_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800838 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800839
Makoto Onuki2206af32017-11-21 16:25:35 -0800840 case MSG_RUN_ANY_CHANGED:
841 for (Listener l : cloneListeners()) {
842 l.onRunAnyAppOpsChanged(sender, msg.arg1, (String) msg.obj);
843 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800844 mStatLogger.logDurationStat(Stats.RUN_ANY_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800845 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800846
Makoto Onuki2206af32017-11-21 16:25:35 -0800847 case MSG_ALL_UNWHITELISTED:
848 for (Listener l : cloneListeners()) {
849 l.onPowerSaveUnwhitelisted(sender);
850 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800851 mStatLogger.logDurationStat(Stats.ALL_UNWHITELISTED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800852 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800853
Makoto Onuki2206af32017-11-21 16:25:35 -0800854 case MSG_ALL_WHITELIST_CHANGED:
855 for (Listener l : cloneListeners()) {
856 l.onPowerSaveWhitelistedChanged(sender);
857 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800858 mStatLogger.logDurationStat(Stats.ALL_WHITELIST_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800859 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800860
Makoto Onuki2206af32017-11-21 16:25:35 -0800861 case MSG_TEMP_WHITELIST_CHANGED:
862 for (Listener l : cloneListeners()) {
863 l.onTempPowerSaveWhitelistChanged(sender);
864 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800865 mStatLogger.logDurationStat(Stats.TEMP_WHITELIST_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800866 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800867
868 case MSG_EXEMPT_CHANGED:
869 for (Listener l : cloneListeners()) {
870 l.onExemptChanged(sender);
871 }
872 mStatLogger.logDurationStat(Stats.EXEMPT_CHANGED, start);
873 return;
874
Makoto Onuki2206af32017-11-21 16:25:35 -0800875 case MSG_FORCE_ALL_CHANGED:
876 for (Listener l : cloneListeners()) {
877 l.onForceAllAppsStandbyChanged(sender);
878 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800879 mStatLogger.logDurationStat(Stats.FORCE_ALL_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800880 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800881
Nancy Zheng525aaa12018-01-12 11:45:37 -0800882 case MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED:
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800883 // Feature flag for forced app standby changed.
884 final boolean unblockAlarms;
885 synchronized (mLock) {
886 unblockAlarms = !mForcedAppStandbyEnabled && !mForceAllAppsStandby;
887 }
Suprabh Shuklac25447d2018-01-19 16:43:35 -0800888 for (Listener l : cloneListeners()) {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800889 l.updateAllJobs();
890 if (unblockAlarms) {
891 l.unblockAllUnrestrictedAlarms();
892 }
893 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800894 mStatLogger.logDurationStat(
895 Stats.FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED, start);
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800896 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800897
Makoto Onuki2206af32017-11-21 16:25:35 -0800898 case MSG_USER_REMOVED:
899 handleUserRemoved(msg.arg1);
900 return;
Makoto Onuki4d298b52018-02-05 10:54:58 -0800901
902 case MSG_ON_UID_STATE_CHANGED:
903 handleUidStateChanged(msg.arg1, msg.arg2);
904 return;
905 case MSG_ON_UID_ACTIVE:
906 handleUidActive(msg.arg1);
907 return;
908 case MSG_ON_UID_GONE:
909 handleUidGone(msg.arg1, msg.arg1 != 0);
910 return;
911 case MSG_ON_UID_IDLE:
912 handleUidIdle(msg.arg1, msg.arg1 != 0);
913 return;
914 }
915 }
916
917 public void handleUidStateChanged(int uid, int procState) {
918 synchronized (mLock) {
919 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
920 if (removeUidFromArray(mForegroundUids, uid, false)) {
921 mHandler.notifyUidForegroundStateChanged(uid);
922 }
923 } else {
924 if (addUidToArray(mForegroundUids, uid)) {
925 mHandler.notifyUidForegroundStateChanged(uid);
926 }
927 }
928 }
929 }
930
931 public void handleUidActive(int uid) {
932 synchronized (mLock) {
933 if (addUidToArray(mActiveUids, uid)) {
934 mHandler.notifyUidActiveStateChanged(uid);
935 }
936 }
937 }
938
939 public void handleUidGone(int uid, boolean disabled) {
940 removeUid(uid, true);
941 }
942
943 public void handleUidIdle(int uid, boolean disabled) {
944 // Just to avoid excessive memcpy, don't remove from the array in this case.
945 removeUid(uid, false);
946 }
947
948 private void removeUid(int uid, boolean remove) {
949 synchronized (mLock) {
950 if (removeUidFromArray(mActiveUids, uid, remove)) {
951 mHandler.notifyUidActiveStateChanged(uid);
952 }
953 if (removeUidFromArray(mForegroundUids, uid, remove)) {
954 mHandler.notifyUidForegroundStateChanged(uid);
955 }
Makoto Onuki2206af32017-11-21 16:25:35 -0800956 }
957 }
958 }
959
960 void handleUserRemoved(int removedUserId) {
961 synchronized (mLock) {
962 for (int i = mRunAnyRestrictedPackages.size() - 1; i >= 0; i--) {
963 final Pair<Integer, String> pair = mRunAnyRestrictedPackages.valueAt(i);
964 final int uid = pair.first;
965 final int userId = UserHandle.getUserId(uid);
966
967 if (userId == removedUserId) {
968 mRunAnyRestrictedPackages.removeAt(i);
969 }
970 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800971 cleanUpArrayForUser(mActiveUids, removedUserId);
972 cleanUpArrayForUser(mForegroundUids, removedUserId);
Makoto Onukieb898f12018-01-23 15:26:27 -0800973 mExemptedPackages.remove(removedUserId);
Makoto Onuki2206af32017-11-21 16:25:35 -0800974 }
975 }
976
Makoto Onukiadb50d82018-01-29 16:20:30 -0800977 private void cleanUpArrayForUser(SparseBooleanArray array, int removedUserId) {
978 for (int i = array.size() - 1; i >= 0; i--) {
979 final int uid = array.keyAt(i);
980 final int userId = UserHandle.getUserId(uid);
981
982 if (userId == removedUserId) {
983 array.removeAt(i);
984 }
985 }
986 }
987
Makoto Onuki2206af32017-11-21 16:25:35 -0800988 /**
989 * Called by device idle controller to update the power save whitelists.
990 */
991 public void setPowerSaveWhitelistAppIds(
Suprabh Shukla5bf49812018-05-24 18:38:50 -0700992 int[] powerSaveWhitelistExceptIdleAppIdArray,
993 int[] powerSaveWhitelistUserAppIdArray,
994 int[] tempWhitelistAppIdArray) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800995 synchronized (mLock) {
996 final int[] previousWhitelist = mPowerWhitelistedAllAppIds;
997 final int[] previousTempWhitelist = mTempWhitelistedAppIds;
998
Suprabh Shukla5bf49812018-05-24 18:38:50 -0700999 mPowerWhitelistedAllAppIds = powerSaveWhitelistExceptIdleAppIdArray;
Makoto Onuki2206af32017-11-21 16:25:35 -08001000 mTempWhitelistedAppIds = tempWhitelistAppIdArray;
Suprabh Shukla5bf49812018-05-24 18:38:50 -07001001 mPowerWhitelistedUserAppIds = powerSaveWhitelistUserAppIdArray;
Makoto Onuki2206af32017-11-21 16:25:35 -08001002
1003 if (isAnyAppIdUnwhitelisted(previousWhitelist, mPowerWhitelistedAllAppIds)) {
1004 mHandler.notifyAllUnwhitelisted();
1005 } else if (!Arrays.equals(previousWhitelist, mPowerWhitelistedAllAppIds)) {
1006 mHandler.notifyAllWhitelistChanged();
1007 }
1008
1009 if (!Arrays.equals(previousTempWhitelist, mTempWhitelistedAppIds)) {
1010 mHandler.notifyTempWhitelistChanged();
1011 }
1012
1013 }
1014 }
1015
1016 /**
1017 * @retunr true if a sorted app-id array {@code prevArray} has at least one element
1018 * that's not in a sorted app-id array {@code newArray}.
1019 */
1020 @VisibleForTesting
1021 static boolean isAnyAppIdUnwhitelisted(int[] prevArray, int[] newArray) {
1022 int i1 = 0;
1023 int i2 = 0;
1024 boolean prevFinished;
1025 boolean newFinished;
1026
1027 for (;;) {
1028 prevFinished = i1 >= prevArray.length;
1029 newFinished = i2 >= newArray.length;
1030 if (prevFinished || newFinished) {
1031 break;
1032 }
1033 int a1 = prevArray[i1];
1034 int a2 = newArray[i2];
1035
1036 if (a1 == a2) {
1037 i1++;
1038 i2++;
1039 continue;
1040 }
1041 if (a1 < a2) {
1042 // prevArray has an element that's not in a2.
1043 return true;
1044 }
1045 i2++;
1046 }
1047 if (prevFinished) {
1048 return false;
1049 }
1050 return newFinished;
Makoto Onuki9be01402017-11-10 13:22:26 -08001051 }
1052
1053 // Public interface.
1054
1055 /**
1056 * Register a new listener.
1057 */
1058 public void addListener(@NonNull Listener listener) {
1059 synchronized (mLock) {
1060 mListeners.add(listener);
1061 }
1062 }
1063
1064 /**
Makoto Onuki2206af32017-11-21 16:25:35 -08001065 * @return whether alarms should be restricted for a UID package-name.
Makoto Onuki9be01402017-11-10 13:22:26 -08001066 */
Suprabh Shuklac25447d2018-01-19 16:43:35 -08001067 public boolean areAlarmsRestricted(int uid, @NonNull String packageName,
Christopher Tateda3dc922018-05-09 13:49:41 -07001068 boolean isExemptOnBatterySaver) {
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001069 return isRestricted(uid, packageName, /*useTempWhitelistToo=*/ false,
Christopher Tateda3dc922018-05-09 13:49:41 -07001070 isExemptOnBatterySaver);
Makoto Onuki2206af32017-11-21 16:25:35 -08001071 }
1072
1073 /**
1074 * @return whether jobs should be restricted for a UID package-name.
1075 */
Makoto Onuki15407842018-01-19 14:23:11 -08001076 public boolean areJobsRestricted(int uid, @NonNull String packageName,
1077 boolean hasForegroundExemption) {
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001078 return isRestricted(uid, packageName, /*useTempWhitelistToo=*/ true,
Makoto Onuki15407842018-01-19 14:23:11 -08001079 hasForegroundExemption);
Makoto Onuki2206af32017-11-21 16:25:35 -08001080 }
1081
1082 /**
Christopher Tatec7933ac2018-03-12 17:57:09 -07001083 * @return whether foreground services should be suppressed in the background
1084 * due to forced app standby for the given app
1085 */
1086 public boolean areForegroundServicesRestricted(int uid, @NonNull String packageName) {
1087 synchronized (mLock) {
1088 return isRunAnyRestrictedLocked(uid, packageName);
1089 }
1090 }
1091
1092 /**
Makoto Onuki2206af32017-11-21 16:25:35 -08001093 * @return whether force-app-standby is effective for a UID package-name.
1094 */
1095 private boolean isRestricted(int uid, @NonNull String packageName,
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001096 boolean useTempWhitelistToo, boolean exemptOnBatterySaver) {
Makoto Onukiadb50d82018-01-29 16:20:30 -08001097 if (isUidActive(uid)) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001098 return false;
1099 }
1100 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001101 // Whitelisted?
1102 final int appId = UserHandle.getAppId(uid);
1103 if (ArrayUtils.contains(mPowerWhitelistedAllAppIds, appId)) {
1104 return false;
1105 }
1106 if (useTempWhitelistToo &&
1107 ArrayUtils.contains(mTempWhitelistedAppIds, appId)) {
1108 return false;
1109 }
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001110 if (mForcedAppStandbyEnabled && isRunAnyRestrictedLocked(uid, packageName)) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001111 return true;
1112 }
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001113 if (exemptOnBatterySaver) {
1114 return false;
1115 }
Makoto Onukieb898f12018-01-23 15:26:27 -08001116 final int userId = UserHandle.getUserId(uid);
1117 if (mExemptedPackages.contains(userId, packageName)) {
1118 return false;
1119 }
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001120 return mForceAllAppsStandby;
Makoto Onuki9be01402017-11-10 13:22:26 -08001121 }
1122 }
1123
Makoto Onuki2206af32017-11-21 16:25:35 -08001124 /**
Makoto Onukie4918212018-02-06 11:30:15 -08001125 * @return whether a UID is in active or not *based on cached information.*
Makoto Onukiadb50d82018-01-29 16:20:30 -08001126 *
1127 * Note this information is based on the UID proc state callback, meaning it's updated
1128 * asynchronously and may subtly be stale. If the fresh data is needed, use
Makoto Onukie4918212018-02-06 11:30:15 -08001129 * {@link #isUidActiveSynced} instead.
Makoto Onukiadb50d82018-01-29 16:20:30 -08001130 */
1131 public boolean isUidActive(int uid) {
1132 if (UserHandle.isCore(uid)) {
1133 return true;
1134 }
1135 synchronized (mLock) {
1136 return mActiveUids.get(uid);
1137 }
1138 }
1139
1140 /**
Makoto Onukie4918212018-02-06 11:30:15 -08001141 * @return whether a UID is in active or not *right now.*
1142 *
1143 * This gives the fresh information, but may access the activity manager so is slower.
1144 */
1145 public boolean isUidActiveSynced(int uid) {
1146 if (isUidActive(uid)) { // Use the cached one first.
1147 return true;
1148 }
1149 final long start = mStatLogger.getTime();
1150
1151 final boolean ret = mActivityManagerInternal.isUidActive(uid);
1152 mStatLogger.logDurationStat(Stats.IS_UID_ACTIVE_RAW, start);
1153
1154 return ret;
1155 }
1156
1157 /**
Makoto Onuki2206af32017-11-21 16:25:35 -08001158 * @return whether a UID is in the foreground or not.
1159 *
Makoto Onuki15407842018-01-19 14:23:11 -08001160 * Note this information is based on the UID proc state callback, meaning it's updated
1161 * asynchronously and may subtly be stale. If the fresh data is needed, use
1162 * {@link ActivityManagerInternal#getUidProcessState} instead.
Makoto Onuki2206af32017-11-21 16:25:35 -08001163 */
Makoto Onukiadb50d82018-01-29 16:20:30 -08001164 public boolean isUidInForeground(int uid) {
Makoto Onuki9cc471c2018-01-23 12:33:56 -08001165 if (UserHandle.isCore(uid)) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001166 return true;
1167 }
1168 synchronized (mLock) {
1169 return mForegroundUids.get(uid);
1170 }
1171 }
1172
Makoto Onuki2206af32017-11-21 16:25:35 -08001173 /**
1174 * @return whether force all apps standby is enabled or not.
1175 *
Makoto Onuki2206af32017-11-21 16:25:35 -08001176 */
1177 boolean isForceAllAppsStandbyEnabled() {
Makoto Onuki9be01402017-11-10 13:22:26 -08001178 synchronized (mLock) {
1179 return mForceAllAppsStandby;
1180 }
1181 }
1182
Makoto Onuki2206af32017-11-21 16:25:35 -08001183 /**
1184 * @return whether a UID/package has {@code OP_RUN_ANY_IN_BACKGROUND} allowed or not.
1185 *
1186 * Note clients normally shouldn't need to access it. It's only for dumpsys.
1187 */
Makoto Onuki9be01402017-11-10 13:22:26 -08001188 public boolean isRunAnyInBackgroundAppOpsAllowed(int uid, @NonNull String packageName) {
1189 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001190 return !isRunAnyRestrictedLocked(uid, packageName);
Makoto Onuki9be01402017-11-10 13:22:26 -08001191 }
1192 }
1193
Makoto Onuki2206af32017-11-21 16:25:35 -08001194 /**
1195 * @return whether a UID is in the user / system defined power-save whitelist or not.
1196 *
1197 * Note clients normally shouldn't need to access it. It's only for dumpsys.
1198 */
1199 public boolean isUidPowerSaveWhitelisted(int uid) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001200 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001201 return ArrayUtils.contains(mPowerWhitelistedAllAppIds, UserHandle.getAppId(uid));
Makoto Onuki9be01402017-11-10 13:22:26 -08001202 }
1203 }
1204
Makoto Onuki2206af32017-11-21 16:25:35 -08001205 /**
Suprabh Shukla5bf49812018-05-24 18:38:50 -07001206 * @param uid the uid to check for
1207 * @return whether a UID is in the user defined power-save whitelist or not.
1208 */
1209 public boolean isUidPowerSaveUserWhitelisted(int uid) {
1210 synchronized (mLock) {
1211 return ArrayUtils.contains(mPowerWhitelistedUserAppIds, UserHandle.getAppId(uid));
1212 }
1213 }
1214
1215 /**
Makoto Onuki2206af32017-11-21 16:25:35 -08001216 * @return whether a UID is in the temp power-save whitelist or not.
1217 *
1218 * Note clients normally shouldn't need to access it. It's only for dumpsys.
1219 */
1220 public boolean isUidTempPowerSaveWhitelisted(int uid) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001221 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001222 return ArrayUtils.contains(mTempWhitelistedAppIds, UserHandle.getAppId(uid));
1223 }
1224 }
1225
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001226 @Deprecated
1227 public void dump(PrintWriter pw, String prefix) {
1228 dump(new IndentingPrintWriter(pw, " ").setIndent(prefix));
1229 }
1230
1231 public void dump(IndentingPrintWriter pw) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001232 synchronized (mLock) {
Suprabh Shukla4deb8522018-01-08 16:27:10 -08001233 pw.println("Forced App Standby Feature enabled: " + mForcedAppStandbyEnabled);
1234
Makoto Onuki2206af32017-11-21 16:25:35 -08001235 pw.print("Force all apps standby: ");
1236 pw.println(isForceAllAppsStandbyEnabled());
1237
Nancy Zheng525aaa12018-01-12 11:45:37 -08001238 pw.print("Small Battery Device: ");
1239 pw.println(isSmallBatteryDevice());
1240
Nancy Zheng525aaa12018-01-12 11:45:37 -08001241 pw.print("Force all apps standby for small battery device: ");
1242 pw.println(mForceAllAppStandbyForSmallBattery);
1243
Nancy Zheng525aaa12018-01-12 11:45:37 -08001244 pw.print("Plugged In: ");
1245 pw.println(mIsPluggedIn);
1246
Makoto Onukiadb50d82018-01-29 16:20:30 -08001247 pw.print("Active uids: ");
1248 dumpUids(pw, mActiveUids);
Makoto Onuki2206af32017-11-21 16:25:35 -08001249
Makoto Onukiadb50d82018-01-29 16:20:30 -08001250 pw.print("Foreground uids: ");
1251 dumpUids(pw, mForegroundUids);
Makoto Onuki2206af32017-11-21 16:25:35 -08001252
Suprabh Shukla5bf49812018-05-24 18:38:50 -07001253 pw.print("Except-idle + user whitelist appids: ");
Makoto Onuki2206af32017-11-21 16:25:35 -08001254 pw.println(Arrays.toString(mPowerWhitelistedAllAppIds));
1255
Suprabh Shukla5bf49812018-05-24 18:38:50 -07001256 pw.print("User whitelist appids: ");
1257 pw.println(Arrays.toString(mPowerWhitelistedUserAppIds));
1258
Makoto Onuki2206af32017-11-21 16:25:35 -08001259 pw.print("Temp whitelist appids: ");
1260 pw.println(Arrays.toString(mTempWhitelistedAppIds));
1261
Makoto Onukieb898f12018-01-23 15:26:27 -08001262 pw.println("Exempted packages:");
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001263 pw.increaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001264 for (int i = 0; i < mExemptedPackages.size(); i++) {
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001265 pw.print("User ");
Makoto Onukieb898f12018-01-23 15:26:27 -08001266 pw.print(mExemptedPackages.keyAt(i));
1267 pw.println();
1268
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001269 pw.increaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001270 for (int j = 0; j < mExemptedPackages.sizeAt(i); j++) {
Makoto Onukieb898f12018-01-23 15:26:27 -08001271 pw.print(mExemptedPackages.valueAt(i, j));
1272 pw.println();
1273 }
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001274 pw.decreaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001275 }
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001276 pw.decreaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001277 pw.println();
1278
Makoto Onuki2206af32017-11-21 16:25:35 -08001279 pw.println("Restricted packages:");
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001280 pw.increaseIndent();
Makoto Onuki2206af32017-11-21 16:25:35 -08001281 for (Pair<Integer, String> uidAndPackage : mRunAnyRestrictedPackages) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001282 pw.print(UserHandle.formatUid(uidAndPackage.first));
1283 pw.print(" ");
1284 pw.print(uidAndPackage.second);
1285 pw.println();
1286 }
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001287 pw.decreaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001288
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001289 mStatLogger.dump(pw);
Makoto Onuki2206af32017-11-21 16:25:35 -08001290 }
1291 }
1292
Makoto Onukiadb50d82018-01-29 16:20:30 -08001293 private void dumpUids(PrintWriter pw, SparseBooleanArray array) {
1294 pw.print("[");
1295
1296 String sep = "";
1297 for (int i = 0; i < array.size(); i++) {
1298 if (array.valueAt(i)) {
1299 pw.print(sep);
1300 pw.print(UserHandle.formatUid(array.keyAt(i)));
1301 sep = " ";
1302 }
1303 }
1304 pw.println("]");
1305 }
1306
Makoto Onuki2206af32017-11-21 16:25:35 -08001307 public void dumpProto(ProtoOutputStream proto, long fieldId) {
1308 synchronized (mLock) {
1309 final long token = proto.start(fieldId);
1310
1311 proto.write(ForceAppStandbyTrackerProto.FORCE_ALL_APPS_STANDBY, mForceAllAppsStandby);
Nancy Zheng525aaa12018-01-12 11:45:37 -08001312 proto.write(ForceAppStandbyTrackerProto.IS_SMALL_BATTERY_DEVICE,
1313 isSmallBatteryDevice());
1314 proto.write(ForceAppStandbyTrackerProto.FORCE_ALL_APPS_STANDBY_FOR_SMALL_BATTERY,
1315 mForceAllAppStandbyForSmallBattery);
Makoto Onukieb898f12018-01-23 15:26:27 -08001316 proto.write(ForceAppStandbyTrackerProto.IS_PLUGGED_IN, mIsPluggedIn);
Makoto Onuki2206af32017-11-21 16:25:35 -08001317
Makoto Onukiadb50d82018-01-29 16:20:30 -08001318 for (int i = 0; i < mActiveUids.size(); i++) {
1319 if (mActiveUids.valueAt(i)) {
1320 proto.write(ForceAppStandbyTrackerProto.ACTIVE_UIDS,
1321 mActiveUids.keyAt(i));
1322 }
1323 }
1324
Makoto Onuki2206af32017-11-21 16:25:35 -08001325 for (int i = 0; i < mForegroundUids.size(); i++) {
1326 if (mForegroundUids.valueAt(i)) {
1327 proto.write(ForceAppStandbyTrackerProto.FOREGROUND_UIDS,
1328 mForegroundUids.keyAt(i));
1329 }
1330 }
1331
1332 for (int appId : mPowerWhitelistedAllAppIds) {
1333 proto.write(ForceAppStandbyTrackerProto.POWER_SAVE_WHITELIST_APP_IDS, appId);
1334 }
1335
Suprabh Shukla5bf49812018-05-24 18:38:50 -07001336 for (int appId : mPowerWhitelistedUserAppIds) {
1337 proto.write(ForceAppStandbyTrackerProto.POWER_SAVE_USER_WHITELIST_APP_IDS, appId);
1338 }
1339
Makoto Onuki2206af32017-11-21 16:25:35 -08001340 for (int appId : mTempWhitelistedAppIds) {
1341 proto.write(ForceAppStandbyTrackerProto.TEMP_POWER_SAVE_WHITELIST_APP_IDS, appId);
1342 }
1343
Makoto Onukieb898f12018-01-23 15:26:27 -08001344 for (int i = 0; i < mExemptedPackages.size(); i++) {
1345 for (int j = 0; j < mExemptedPackages.sizeAt(i); j++) {
1346 final long token2 = proto.start(
1347 ForceAppStandbyTrackerProto.EXEMPTED_PACKAGES);
1348
1349 proto.write(ExemptedPackage.USER_ID, mExemptedPackages.keyAt(i));
1350 proto.write(ExemptedPackage.PACKAGE_NAME, mExemptedPackages.valueAt(i, j));
1351
1352 proto.end(token2);
1353 }
1354 }
1355
Makoto Onuki2206af32017-11-21 16:25:35 -08001356 for (Pair<Integer, String> uidAndPackage : mRunAnyRestrictedPackages) {
1357 final long token2 = proto.start(
1358 ForceAppStandbyTrackerProto.RUN_ANY_IN_BACKGROUND_RESTRICTED_PACKAGES);
1359 proto.write(RunAnyInBackgroundRestrictedPackages.UID, uidAndPackage.first);
1360 proto.write(RunAnyInBackgroundRestrictedPackages.PACKAGE_NAME,
1361 uidAndPackage.second);
1362 proto.end(token2);
1363 }
Makoto Onukieb898f12018-01-23 15:26:27 -08001364
1365 mStatLogger.dumpProto(proto, ForceAppStandbyTrackerProto.STATS);
1366
Makoto Onuki2206af32017-11-21 16:25:35 -08001367 proto.end(token);
Makoto Onuki9be01402017-11-10 13:22:26 -08001368 }
1369 }
1370}