blob: 16be680b17709cb3c10bb8f88582e13b86cd84ed [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 Onukieb898f12018-01-23 15:26:27 -080058import com.android.server.ForceAppStandbyTrackerProto.ExemptedPackage;
Makoto Onuki2206af32017-11-21 16:25:35 -080059import com.android.server.ForceAppStandbyTrackerProto.RunAnyInBackgroundRestrictedPackages;
Makoto Onuki9be01402017-11-10 13:22:26 -080060
Makoto Onuki2206af32017-11-21 16:25:35 -080061import java.io.PrintWriter;
62import java.util.Arrays;
Makoto Onuki9be01402017-11-10 13:22:26 -080063import java.util.List;
64
65/**
Makoto Onuki2206af32017-11-21 16:25:35 -080066 * Class to keep track of the information related to "force app standby", which includes:
67 * - OP_RUN_ANY_IN_BACKGROUND for each package
Makoto Onukiadb50d82018-01-29 16:20:30 -080068 * - UID foreground/active state
Makoto Onuki2206af32017-11-21 16:25:35 -080069 * - User+system power save whitelist
70 * - Temporary power save whitelist
71 * - Global "force all apps standby" mode enforced by battery saver.
Makoto Onuki9be01402017-11-10 13:22:26 -080072 *
Makoto Onukiadb50d82018-01-29 16:20:30 -080073 * TODO: Make it a LocalService.
Makoto Onuki2206af32017-11-21 16:25:35 -080074 *
75 * Test:
Makoto Onukie4918212018-02-06 11:30:15 -080076 atest $ANDROID_BUILD_TOP/frameworks/base/services/tests/servicestests/src/com/android/server/AppStateTrackerTest.java
Makoto Onuki9be01402017-11-10 13:22:26 -080077 */
Makoto Onukie4918212018-02-06 11:30:15 -080078public class AppStateTracker {
Makoto Onuki9be01402017-11-10 13:22:26 -080079 private static final String TAG = "ForceAppStandbyTracker";
Makoto Onukieb898f12018-01-23 15:26:27 -080080 private static final boolean DEBUG = true;
Makoto Onuki9be01402017-11-10 13:22:26 -080081
Makoto Onukie4918212018-02-06 11:30:15 -080082 @GuardedBy("AppStateTracker.class")
83 private static AppStateTracker sInstance;
Makoto Onuki9be01402017-11-10 13:22:26 -080084
85 private final Object mLock = new Object();
86 private final Context mContext;
87
Makoto Onuki2206af32017-11-21 16:25:35 -080088 @VisibleForTesting
89 static final int TARGET_OP = AppOpsManager.OP_RUN_ANY_IN_BACKGROUND;
90
91 IActivityManager mIActivityManager;
Makoto Onukie4918212018-02-06 11:30:15 -080092 ActivityManagerInternal mActivityManagerInternal;
Makoto Onuki9be01402017-11-10 13:22:26 -080093 AppOpsManager mAppOpsManager;
94 IAppOpsService mAppOpsService;
95 PowerManagerInternal mPowerManagerInternal;
Makoto Onukieb898f12018-01-23 15:26:27 -080096 StandbyTracker mStandbyTracker;
97 UsageStatsManagerInternal mUsageStatsManagerInternal;
Makoto Onuki9be01402017-11-10 13:22:26 -080098
Makoto Onuki2206af32017-11-21 16:25:35 -080099 private final MyHandler mHandler;
Makoto Onuki9be01402017-11-10 13:22:26 -0800100
Nancy Zheng525aaa12018-01-12 11:45:37 -0800101 @VisibleForTesting
102 FeatureFlagsObserver mFlagsObserver;
103
Makoto Onuki9be01402017-11-10 13:22:26 -0800104 /**
105 * Pair of (uid (not user-id), packageName) with OP_RUN_ANY_IN_BACKGROUND *not* allowed.
106 */
107 @GuardedBy("mLock")
Makoto Onuki2206af32017-11-21 16:25:35 -0800108 final ArraySet<Pair<Integer, String>> mRunAnyRestrictedPackages = new ArraySet<>();
Makoto Onuki9be01402017-11-10 13:22:26 -0800109
Makoto Onukiadb50d82018-01-29 16:20:30 -0800110 /** UIDs that are active. */
111 @GuardedBy("mLock")
112 final SparseBooleanArray mActiveUids = new SparseBooleanArray();
113
114 /** UIDs that are in the foreground. */
Makoto Onuki9be01402017-11-10 13:22:26 -0800115 @GuardedBy("mLock")
116 final SparseBooleanArray mForegroundUids = new SparseBooleanArray();
117
Makoto Onuki71755c92018-01-16 14:15:44 -0800118 /**
119 * System except-idle + user whitelist in the device idle controller.
120 */
Makoto Onuki9be01402017-11-10 13:22:26 -0800121 @GuardedBy("mLock")
Makoto Onuki2206af32017-11-21 16:25:35 -0800122 private int[] mPowerWhitelistedAllAppIds = new int[0];
123
124 @GuardedBy("mLock")
125 private int[] mTempWhitelistedAppIds = mPowerWhitelistedAllAppIds;
126
Makoto Onukieb898f12018-01-23 15:26:27 -0800127 /**
128 * Per-user packages that are in the EXEMPT bucket.
129 */
130 @GuardedBy("mLock")
131 private final SparseSetArray<String> mExemptedPackages = new SparseSetArray<>();
132
Makoto Onuki2206af32017-11-21 16:25:35 -0800133 @GuardedBy("mLock")
Makoto Onuki9be01402017-11-10 13:22:26 -0800134 final ArraySet<Listener> mListeners = new ArraySet<>();
135
136 @GuardedBy("mLock")
137 boolean mStarted;
138
Nancy Zheng525aaa12018-01-12 11:45:37 -0800139 /**
140 * Only used for small battery use-case.
141 */
Makoto Onuki9be01402017-11-10 13:22:26 -0800142 @GuardedBy("mLock")
Nancy Zheng525aaa12018-01-12 11:45:37 -0800143 boolean mIsPluggedIn;
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800144
145 @GuardedBy("mLock")
Nancy Zheng525aaa12018-01-12 11:45:37 -0800146 boolean mBatterySaverEnabled;
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800147
Nancy Zheng525aaa12018-01-12 11:45:37 -0800148 /**
149 * True if the forced app standby is currently enabled
150 */
151 @GuardedBy("mLock")
152 boolean mForceAllAppsStandby;
153
154 /**
155 * True if the forced app standby for small battery devices feature is enabled in settings
156 */
157 @GuardedBy("mLock")
158 boolean mForceAllAppStandbyForSmallBattery;
159
160 /**
161 * True if the forced app standby feature is enabled in settings
162 */
163 @GuardedBy("mLock")
164 boolean mForcedAppStandbyEnabled;
165
Makoto Onukieb898f12018-01-23 15:26:27 -0800166 interface Stats {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800167 int UID_FG_STATE_CHANGED = 0;
168 int UID_ACTIVE_STATE_CHANGED = 1;
169 int RUN_ANY_CHANGED = 2;
170 int ALL_UNWHITELISTED = 3;
171 int ALL_WHITELIST_CHANGED = 4;
172 int TEMP_WHITELIST_CHANGED = 5;
173 int EXEMPT_CHANGED = 6;
174 int FORCE_ALL_CHANGED = 7;
175 int FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED = 8;
Makoto Onukie4918212018-02-06 11:30:15 -0800176
177 int IS_UID_ACTIVE_CACHED = 9;
178 int IS_UID_ACTIVE_RAW = 10;
Makoto Onukieb898f12018-01-23 15:26:27 -0800179 }
180
181 private final StatLogger mStatLogger = new StatLogger(new String[] {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800182 "UID_FG_STATE_CHANGED",
183 "UID_ACTIVE_STATE_CHANGED",
Makoto Onukieb898f12018-01-23 15:26:27 -0800184 "RUN_ANY_CHANGED",
185 "ALL_UNWHITELISTED",
186 "ALL_WHITELIST_CHANGED",
187 "TEMP_WHITELIST_CHANGED",
188 "EXEMPT_CHANGED",
189 "FORCE_ALL_CHANGED",
190 "FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED",
Makoto Onukie4918212018-02-06 11:30:15 -0800191
192 "IS_UID_ACTIVE_CACHED",
193 "IS_UID_ACTIVE_RAW",
Makoto Onukieb898f12018-01-23 15:26:27 -0800194 });
195
Nancy Zheng525aaa12018-01-12 11:45:37 -0800196 @VisibleForTesting
197 class FeatureFlagsObserver extends ContentObserver {
198 FeatureFlagsObserver() {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800199 super(null);
200 }
201
202 void register() {
203 mContext.getContentResolver().registerContentObserver(
204 Settings.Global.getUriFor(Settings.Global.FORCED_APP_STANDBY_ENABLED),
205 false, this);
Nancy Zheng525aaa12018-01-12 11:45:37 -0800206
207 mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor(
208 Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED), false, this);
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800209 }
210
211 boolean isForcedAppStandbyEnabled() {
Makoto Onukieb898f12018-01-23 15:26:27 -0800212 return injectGetGlobalSettingInt(Settings.Global.FORCED_APP_STANDBY_ENABLED, 1) == 1;
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800213 }
214
Nancy Zheng525aaa12018-01-12 11:45:37 -0800215 boolean isForcedAppStandbyForSmallBatteryEnabled() {
Makoto Onukieb898f12018-01-23 15:26:27 -0800216 return injectGetGlobalSettingInt(
Nancy Zheng525aaa12018-01-12 11:45:37 -0800217 Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED, 0) == 1;
218 }
219
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800220 @Override
Nancy Zheng525aaa12018-01-12 11:45:37 -0800221 public void onChange(boolean selfChange, Uri uri) {
222 if (Settings.Global.getUriFor(Settings.Global.FORCED_APP_STANDBY_ENABLED).equals(uri)) {
223 final boolean enabled = isForcedAppStandbyEnabled();
224 synchronized (mLock) {
225 if (mForcedAppStandbyEnabled == enabled) {
226 return;
227 }
228 mForcedAppStandbyEnabled = enabled;
229 if (DEBUG) {
230 Slog.d(TAG,"Forced app standby feature flag changed: "
231 + mForcedAppStandbyEnabled);
232 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800233 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800234 mHandler.notifyForcedAppStandbyFeatureFlagChanged();
235 } else if (Settings.Global.getUriFor(
236 Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED).equals(uri)) {
237 final boolean enabled = isForcedAppStandbyForSmallBatteryEnabled();
238 synchronized (mLock) {
239 if (mForceAllAppStandbyForSmallBattery == enabled) {
240 return;
241 }
242 mForceAllAppStandbyForSmallBattery = enabled;
243 if (DEBUG) {
244 Slog.d(TAG, "Forced app standby for small battery feature flag changed: "
245 + mForceAllAppStandbyForSmallBattery);
246 }
247 updateForceAllAppStandbyState();
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800248 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800249 } else {
250 Slog.w(TAG, "Unexpected feature flag uri encountered: " + uri);
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800251 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800252 }
253 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800254
255 public static abstract class Listener {
Makoto Onuki2206af32017-11-21 16:25:35 -0800256 /**
257 * This is called when the OP_RUN_ANY_IN_BACKGROUND appops changed for a package.
258 */
Makoto Onukie4918212018-02-06 11:30:15 -0800259 private void onRunAnyAppOpsChanged(AppStateTracker sender,
Makoto Onuki2206af32017-11-21 16:25:35 -0800260 int uid, @NonNull String packageName) {
Christopher Tate20afddd2018-02-28 15:19:19 -0800261 updateJobsForUidPackage(uid, packageName, sender.isUidActive(uid));
Makoto Onuki2206af32017-11-21 16:25:35 -0800262
Suprabh Shuklac25447d2018-01-19 16:43:35 -0800263 if (!sender.areAlarmsRestricted(uid, packageName, /*allowWhileIdle=*/ false)) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800264 unblockAlarmsForUidPackage(uid, packageName);
Suprabh Shuklac25447d2018-01-19 16:43:35 -0800265 } else if (!sender.areAlarmsRestricted(uid, packageName, /*allowWhileIdle=*/ true)){
266 // we need to deliver the allow-while-idle alarms for this uid, package
267 unblockAllUnrestrictedAlarms();
Makoto Onuki2206af32017-11-21 16:25:35 -0800268 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800269 }
270
Makoto Onuki2206af32017-11-21 16:25:35 -0800271 /**
272 * This is called when the foreground state changed for a UID.
273 */
Makoto Onukie4918212018-02-06 11:30:15 -0800274 private void onUidForegroundStateChanged(AppStateTracker sender, int uid) {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800275 onUidForeground(uid, sender.isUidInForeground(uid));
276 }
277
278 /**
279 * This is called when the active/idle state changed for a UID.
280 */
Makoto Onukie4918212018-02-06 11:30:15 -0800281 private void onUidActiveStateChanged(AppStateTracker sender, int uid) {
Christopher Tate20afddd2018-02-28 15:19:19 -0800282 final boolean isActive = sender.isUidActive(uid);
Makoto Onuki2206af32017-11-21 16:25:35 -0800283
Christopher Tate20afddd2018-02-28 15:19:19 -0800284 updateJobsForUid(uid, isActive);
285
286 if (isActive) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800287 unblockAlarmsForUid(uid);
288 }
289 }
290
291 /**
292 * This is called when an app-id(s) is removed from the power save whitelist.
293 */
Makoto Onukie4918212018-02-06 11:30:15 -0800294 private void onPowerSaveUnwhitelisted(AppStateTracker sender) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800295 updateAllJobs();
296 unblockAllUnrestrictedAlarms();
297 }
298
299 /**
300 * This is called when the power save whitelist changes, excluding the
301 * {@link #onPowerSaveUnwhitelisted} case.
302 */
Makoto Onukie4918212018-02-06 11:30:15 -0800303 private void onPowerSaveWhitelistedChanged(AppStateTracker sender) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800304 updateAllJobs();
305 }
306
307 /**
308 * This is called when the temp whitelist changes.
309 */
Makoto Onukie4918212018-02-06 11:30:15 -0800310 private void onTempPowerSaveWhitelistChanged(AppStateTracker sender) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800311
312 // TODO This case happens rather frequently; consider optimizing and update jobs
313 // only for affected app-ids.
314
315 updateAllJobs();
Makoto Onukieb898f12018-01-23 15:26:27 -0800316
317 // Note when an app is just put in the temp whitelist, we do *not* drain pending alarms.
318 }
319
320 /**
321 * This is called when the EXEMPT bucket is updated.
322 */
Makoto Onukie4918212018-02-06 11:30:15 -0800323 private void onExemptChanged(AppStateTracker sender) {
Makoto Onukieb898f12018-01-23 15:26:27 -0800324 // This doesn't happen very often, so just re-evaluate all jobs / alarms.
325 updateAllJobs();
326 unblockAllUnrestrictedAlarms();
Makoto Onuki2206af32017-11-21 16:25:35 -0800327 }
328
329 /**
330 * This is called when the global "force all apps standby" flag changes.
331 */
Makoto Onukie4918212018-02-06 11:30:15 -0800332 private void onForceAllAppsStandbyChanged(AppStateTracker sender) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800333 updateAllJobs();
334
335 if (!sender.isForceAllAppsStandbyEnabled()) {
336 unblockAllUnrestrictedAlarms();
337 }
338 }
339
340 /**
341 * Called when the job restrictions for multiple UIDs might have changed, so the job
342 * scheduler should re-evaluate all restrictions for all jobs.
343 */
344 public void updateAllJobs() {
345 }
346
347 /**
348 * Called when the job restrictions for a UID might have changed, so the job
349 * scheduler should re-evaluate all restrictions for all jobs.
350 */
Christopher Tate20afddd2018-02-28 15:19:19 -0800351 public void updateJobsForUid(int uid, boolean isNowActive) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800352 }
353
354 /**
355 * Called when the job restrictions for a UID - package might have changed, so the job
356 * scheduler should re-evaluate all restrictions for all jobs.
357 */
Christopher Tate20afddd2018-02-28 15:19:19 -0800358 public void updateJobsForUidPackage(int uid, String packageName, boolean isNowActive) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800359 }
360
361 /**
362 * Called when the job restrictions for multiple UIDs might have changed, so the alarm
363 * manager should re-evaluate all restrictions for all blocked jobs.
364 */
365 public void unblockAllUnrestrictedAlarms() {
366 }
367
368 /**
369 * Called when all jobs for a specific UID are unblocked.
370 */
371 public void unblockAlarmsForUid(int uid) {
372 }
373
374 /**
375 * Called when all alarms for a specific UID - package are unblocked.
376 */
377 public void unblockAlarmsForUidPackage(int uid, String packageName) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800378 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800379
380 /**
381 * Called when a UID comes into the foreground or the background.
382 *
383 * @see #isUidInForeground(int)
384 */
385 public void onUidForeground(int uid, boolean foreground) {
386 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800387 }
388
Makoto Onukie4918212018-02-06 11:30:15 -0800389 public AppStateTracker(Context context, Looper looper) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800390 mContext = context;
Makoto Onuki2206af32017-11-21 16:25:35 -0800391 mHandler = new MyHandler(looper);
392 }
393
Makoto Onuki9be01402017-11-10 13:22:26 -0800394 /**
395 * Call it when the system is ready.
396 */
Makoto Onukie4918212018-02-06 11:30:15 -0800397 public void onSystemServicesReady() {
Makoto Onuki9be01402017-11-10 13:22:26 -0800398 synchronized (mLock) {
399 if (mStarted) {
400 return;
401 }
402 mStarted = true;
403
Makoto Onuki2206af32017-11-21 16:25:35 -0800404 mIActivityManager = Preconditions.checkNotNull(injectIActivityManager());
Makoto Onukie4918212018-02-06 11:30:15 -0800405 mActivityManagerInternal = Preconditions.checkNotNull(injectActivityManagerInternal());
Makoto Onuki2206af32017-11-21 16:25:35 -0800406 mAppOpsManager = Preconditions.checkNotNull(injectAppOpsManager());
407 mAppOpsService = Preconditions.checkNotNull(injectIAppOpsService());
408 mPowerManagerInternal = Preconditions.checkNotNull(injectPowerManagerInternal());
Makoto Onukieb898f12018-01-23 15:26:27 -0800409 mUsageStatsManagerInternal = Preconditions.checkNotNull(
410 injectUsageStatsManagerInternal());
411
Nancy Zheng525aaa12018-01-12 11:45:37 -0800412 mFlagsObserver = new FeatureFlagsObserver();
413 mFlagsObserver.register();
414 mForcedAppStandbyEnabled = mFlagsObserver.isForcedAppStandbyEnabled();
415 mForceAllAppStandbyForSmallBattery =
416 mFlagsObserver.isForcedAppStandbyForSmallBatteryEnabled();
Makoto Onukieb898f12018-01-23 15:26:27 -0800417 mStandbyTracker = new StandbyTracker();
418 mUsageStatsManagerInternal.addAppIdleStateChangeListener(mStandbyTracker);
Makoto Onuki9be01402017-11-10 13:22:26 -0800419
420 try {
Makoto Onuki2206af32017-11-21 16:25:35 -0800421 mIActivityManager.registerUidObserver(new UidObserver(),
Makoto Onukiadb50d82018-01-29 16:20:30 -0800422 ActivityManager.UID_OBSERVER_GONE
423 | ActivityManager.UID_OBSERVER_IDLE
424 | ActivityManager.UID_OBSERVER_ACTIVE
425 | ActivityManager.UID_OBSERVER_PROCSTATE,
Makoto Onuki9be01402017-11-10 13:22:26 -0800426 ActivityManager.PROCESS_STATE_UNKNOWN, null);
Makoto Onuki2206af32017-11-21 16:25:35 -0800427 mAppOpsService.startWatchingMode(TARGET_OP, null,
Makoto Onuki9be01402017-11-10 13:22:26 -0800428 new AppOpsWatcher());
429 } catch (RemoteException e) {
430 // shouldn't happen.
431 }
432
Makoto Onuki2206af32017-11-21 16:25:35 -0800433 IntentFilter filter = new IntentFilter();
434 filter.addAction(Intent.ACTION_USER_REMOVED);
Nancy Zheng525aaa12018-01-12 11:45:37 -0800435 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800436 mContext.registerReceiver(new MyReceiver(), filter);
Makoto Onuki9be01402017-11-10 13:22:26 -0800437
438 refreshForcedAppStandbyUidPackagesLocked();
Makoto Onuki2206af32017-11-21 16:25:35 -0800439
440 mPowerManagerInternal.registerLowPowerModeObserver(
441 ServiceType.FORCE_ALL_APPS_STANDBY,
Nancy Zheng525aaa12018-01-12 11:45:37 -0800442 (state) -> {
443 synchronized (mLock) {
444 mBatterySaverEnabled = state.batterySaverEnabled;
445 updateForceAllAppStandbyState();
446 }
447 });
Makoto Onuki2206af32017-11-21 16:25:35 -0800448
Nancy Zheng525aaa12018-01-12 11:45:37 -0800449 mBatterySaverEnabled = mPowerManagerInternal.getLowPowerState(
450 ServiceType.FORCE_ALL_APPS_STANDBY).batterySaverEnabled;
451
452 updateForceAllAppStandbyState();
Makoto Onuki9be01402017-11-10 13:22:26 -0800453 }
454 }
455
Makoto Onuki2206af32017-11-21 16:25:35 -0800456 @VisibleForTesting
457 AppOpsManager injectAppOpsManager() {
458 return mContext.getSystemService(AppOpsManager.class);
459 }
460
461 @VisibleForTesting
462 IAppOpsService injectIAppOpsService() {
463 return IAppOpsService.Stub.asInterface(
464 ServiceManager.getService(Context.APP_OPS_SERVICE));
465 }
466
467 @VisibleForTesting
468 IActivityManager injectIActivityManager() {
469 return ActivityManager.getService();
470 }
471
472 @VisibleForTesting
Makoto Onukie4918212018-02-06 11:30:15 -0800473 ActivityManagerInternal injectActivityManagerInternal() {
474 return LocalServices.getService(ActivityManagerInternal.class);
475 }
476
477 @VisibleForTesting
Makoto Onuki2206af32017-11-21 16:25:35 -0800478 PowerManagerInternal injectPowerManagerInternal() {
479 return LocalServices.getService(PowerManagerInternal.class);
480 }
481
Nancy Zheng525aaa12018-01-12 11:45:37 -0800482 @VisibleForTesting
Makoto Onukieb898f12018-01-23 15:26:27 -0800483 UsageStatsManagerInternal injectUsageStatsManagerInternal() {
484 return LocalServices.getService(UsageStatsManagerInternal.class);
485 }
486
487 @VisibleForTesting
Nancy Zheng525aaa12018-01-12 11:45:37 -0800488 boolean isSmallBatteryDevice() {
489 return ActivityManager.isSmallBatteryDevice();
490 }
491
Makoto Onukieb898f12018-01-23 15:26:27 -0800492 @VisibleForTesting
493 int injectGetGlobalSettingInt(String key, int def) {
494 return Settings.Global.getInt(mContext.getContentResolver(), key, def);
495 }
496
Makoto Onuki9be01402017-11-10 13:22:26 -0800497 /**
Makoto Onuki2206af32017-11-21 16:25:35 -0800498 * Update {@link #mRunAnyRestrictedPackages} with the current app ops state.
Makoto Onuki9be01402017-11-10 13:22:26 -0800499 */
Andreas Gampea36dc622018-02-05 17:19:22 -0800500 @GuardedBy("mLock")
Makoto Onuki9be01402017-11-10 13:22:26 -0800501 private void refreshForcedAppStandbyUidPackagesLocked() {
Makoto Onuki2206af32017-11-21 16:25:35 -0800502 mRunAnyRestrictedPackages.clear();
503 final List<PackageOps> ops = mAppOpsManager.getPackagesForOps(
504 new int[] {TARGET_OP});
Makoto Onuki9be01402017-11-10 13:22:26 -0800505
506 if (ops == null) {
507 return;
508 }
509 final int size = ops.size();
510 for (int i = 0; i < size; i++) {
511 final AppOpsManager.PackageOps pkg = ops.get(i);
512 final List<AppOpsManager.OpEntry> entries = ops.get(i).getOps();
513
514 for (int j = 0; j < entries.size(); j++) {
515 AppOpsManager.OpEntry ent = entries.get(j);
Makoto Onuki2206af32017-11-21 16:25:35 -0800516 if (ent.getOp() != TARGET_OP) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800517 continue;
518 }
519 if (ent.getMode() != AppOpsManager.MODE_ALLOWED) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800520 mRunAnyRestrictedPackages.add(Pair.create(
Makoto Onuki9be01402017-11-10 13:22:26 -0800521 pkg.getUid(), pkg.getPackageName()));
522 }
523 }
524 }
525 }
526
Nancy Zheng525aaa12018-01-12 11:45:37 -0800527 private void updateForceAllAppStandbyState() {
528 synchronized (mLock) {
529 if (mForceAllAppStandbyForSmallBattery && isSmallBatteryDevice()) {
530 toggleForceAllAppsStandbyLocked(!mIsPluggedIn);
531 } else {
532 toggleForceAllAppsStandbyLocked(mBatterySaverEnabled);
533 }
534 }
535 }
536
Makoto Onuki2206af32017-11-21 16:25:35 -0800537 /**
538 * Update {@link #mForceAllAppsStandby} and notifies the listeners.
539 */
Andreas Gampea36dc622018-02-05 17:19:22 -0800540 @GuardedBy("mLock")
Nancy Zheng525aaa12018-01-12 11:45:37 -0800541 private void toggleForceAllAppsStandbyLocked(boolean enable) {
542 if (enable == mForceAllAppsStandby) {
543 return;
Makoto Onuki12391f22018-01-18 21:44:28 +0000544 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800545 mForceAllAppsStandby = enable;
546
547 mHandler.notifyForceAllAppsStandbyChanged();
Makoto Onuki9be01402017-11-10 13:22:26 -0800548 }
549
Andreas Gampea36dc622018-02-05 17:19:22 -0800550 @GuardedBy("mLock")
Makoto Onuki9be01402017-11-10 13:22:26 -0800551 private int findForcedAppStandbyUidPackageIndexLocked(int uid, @NonNull String packageName) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800552 final int size = mRunAnyRestrictedPackages.size();
553 if (size > 8) {
554 return mRunAnyRestrictedPackages.indexOf(Pair.create(uid, packageName));
555 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800556 for (int i = 0; i < size; i++) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800557 final Pair<Integer, String> pair = mRunAnyRestrictedPackages.valueAt(i);
Makoto Onuki9be01402017-11-10 13:22:26 -0800558
559 if ((pair.first == uid) && packageName.equals(pair.second)) {
560 return i;
561 }
562 }
563 return -1;
564 }
565
566 /**
Makoto Onuki2206af32017-11-21 16:25:35 -0800567 * @return whether a uid package-name pair is in mRunAnyRestrictedPackages.
Makoto Onuki9be01402017-11-10 13:22:26 -0800568 */
Andreas Gampea36dc622018-02-05 17:19:22 -0800569 @GuardedBy("mLock")
Makoto Onuki2206af32017-11-21 16:25:35 -0800570 boolean isRunAnyRestrictedLocked(int uid, @NonNull String packageName) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800571 return findForcedAppStandbyUidPackageIndexLocked(uid, packageName) >= 0;
572 }
573
Makoto Onuki2206af32017-11-21 16:25:35 -0800574 /**
575 * Add to / remove from {@link #mRunAnyRestrictedPackages}.
576 */
Andreas Gampea36dc622018-02-05 17:19:22 -0800577 @GuardedBy("mLock")
Makoto Onuki2206af32017-11-21 16:25:35 -0800578 boolean updateForcedAppStandbyUidPackageLocked(int uid, @NonNull String packageName,
Makoto Onuki9be01402017-11-10 13:22:26 -0800579 boolean restricted) {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800580 final int index = findForcedAppStandbyUidPackageIndexLocked(uid, packageName);
Makoto Onuki9be01402017-11-10 13:22:26 -0800581 final boolean wasRestricted = index >= 0;
582 if (wasRestricted == restricted) {
583 return false;
584 }
585 if (restricted) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800586 mRunAnyRestrictedPackages.add(Pair.create(uid, packageName));
Makoto Onuki9be01402017-11-10 13:22:26 -0800587 } else {
Makoto Onuki2206af32017-11-21 16:25:35 -0800588 mRunAnyRestrictedPackages.removeAt(index);
Makoto Onuki9be01402017-11-10 13:22:26 -0800589 }
590 return true;
591 }
592
Makoto Onukiadb50d82018-01-29 16:20:30 -0800593 private static boolean addUidToArray(SparseBooleanArray array, int uid) {
594 if (UserHandle.isCore(uid)) {
595 return false;
Makoto Onuki9be01402017-11-10 13:22:26 -0800596 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800597 if (array.get(uid)) {
598 return false;
599 }
600 array.put(uid, true);
601 return true;
Makoto Onuki9be01402017-11-10 13:22:26 -0800602 }
603
Makoto Onukiadb50d82018-01-29 16:20:30 -0800604 private static boolean removeUidFromArray(SparseBooleanArray array, int uid, boolean remove) {
605 if (UserHandle.isCore(uid)) {
606 return false;
Makoto Onuki9be01402017-11-10 13:22:26 -0800607 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800608 if (!array.get(uid)) {
609 return false;
610 }
611 if (remove) {
612 array.delete(uid);
613 } else {
614 array.put(uid, false);
615 }
616 return true;
Makoto Onuki9be01402017-11-10 13:22:26 -0800617 }
618
Makoto Onuki2206af32017-11-21 16:25:35 -0800619 private final class UidObserver extends IUidObserver.Stub {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800620 @Override
621 public void onUidStateChanged(int uid, int procState, long procStateSeq) {
Makoto Onuki4d298b52018-02-05 10:54:58 -0800622 mHandler.onUidStateChanged(uid, procState);
Makoto Onuki9be01402017-11-10 13:22:26 -0800623 }
624
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800625 @Override
626 public void onUidActive(int uid) {
Makoto Onuki4d298b52018-02-05 10:54:58 -0800627 mHandler.onUidActive(uid);
628 }
629
630 @Override
631 public void onUidGone(int uid, boolean disabled) {
632 mHandler.onUidGone(uid, disabled);
Makoto Onuki9be01402017-11-10 13:22:26 -0800633 }
634
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800635 @Override
636 public void onUidIdle(int uid, boolean disabled) {
Makoto Onuki4d298b52018-02-05 10:54:58 -0800637 mHandler.onUidIdle(uid, disabled);
Makoto Onuki9be01402017-11-10 13:22:26 -0800638 }
639
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800640 @Override
641 public void onUidCachedChanged(int uid, boolean cached) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800642 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800643 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800644
645 private final class AppOpsWatcher extends IAppOpsCallback.Stub {
646 @Override
647 public void opChanged(int op, int uid, String packageName) throws RemoteException {
Makoto Onuki2206af32017-11-21 16:25:35 -0800648 boolean restricted = false;
649 try {
650 restricted = mAppOpsService.checkOperation(TARGET_OP,
651 uid, packageName) != AppOpsManager.MODE_ALLOWED;
652 } catch (RemoteException e) {
653 // Shouldn't happen
654 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800655 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800656 if (updateForcedAppStandbyUidPackageLocked(uid, packageName, restricted)) {
657 mHandler.notifyRunAnyAppOpsChanged(uid, packageName);
658 }
659 }
660 }
661 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800662
Makoto Onuki2206af32017-11-21 16:25:35 -0800663 private final class MyReceiver extends BroadcastReceiver {
664 @Override
665 public void onReceive(Context context, Intent intent) {
666 if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
667 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
668 if (userId > 0) {
669 mHandler.doUserRemoved(userId);
Makoto Onuki9be01402017-11-10 13:22:26 -0800670 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800671 } else if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
672 synchronized (mLock) {
673 mIsPluggedIn = (intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0);
674 }
675 updateForceAllAppStandbyState();
Makoto Onuki9be01402017-11-10 13:22:26 -0800676 }
677 }
678 }
679
Makoto Onukieb898f12018-01-23 15:26:27 -0800680 final class StandbyTracker extends AppIdleStateChangeListener {
681 @Override
682 public void onAppIdleStateChanged(String packageName, int userId, boolean idle,
Amith Yamasani119be9a2018-02-18 22:23:00 -0800683 int bucket, int reason) {
Makoto Onukieb898f12018-01-23 15:26:27 -0800684 if (DEBUG) {
685 Slog.d(TAG,"onAppIdleStateChanged: " + packageName + " u" + userId
686 + (idle ? " idle" : " active") + " " + bucket);
687 }
688 final boolean changed;
689 if (bucket == UsageStatsManager.STANDBY_BUCKET_EXEMPTED) {
690 changed = mExemptedPackages.add(userId, packageName);
691 } else {
692 changed = mExemptedPackages.remove(userId, packageName);
693 }
694 if (changed) {
695 mHandler.notifyExemptChanged();
696 }
697 }
698
699 @Override
700 public void onParoleStateChanged(boolean isParoleOn) {
701 }
702 }
703
Makoto Onuki9be01402017-11-10 13:22:26 -0800704 private Listener[] cloneListeners() {
705 synchronized (mLock) {
706 return mListeners.toArray(new Listener[mListeners.size()]);
707 }
708 }
709
Makoto Onuki2206af32017-11-21 16:25:35 -0800710 private class MyHandler extends Handler {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800711 private static final int MSG_UID_ACTIVE_STATE_CHANGED = 0;
712 private static final int MSG_UID_FG_STATE_CHANGED = 1;
713 private static final int MSG_RUN_ANY_CHANGED = 3;
714 private static final int MSG_ALL_UNWHITELISTED = 4;
715 private static final int MSG_ALL_WHITELIST_CHANGED = 5;
716 private static final int MSG_TEMP_WHITELIST_CHANGED = 6;
717 private static final int MSG_FORCE_ALL_CHANGED = 7;
718 private static final int MSG_USER_REMOVED = 8;
719 private static final int MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED = 9;
720 private static final int MSG_EXEMPT_CHANGED = 10;
Makoto Onuki9be01402017-11-10 13:22:26 -0800721
Makoto Onuki4d298b52018-02-05 10:54:58 -0800722 private static final int MSG_ON_UID_STATE_CHANGED = 11;
723 private static final int MSG_ON_UID_ACTIVE = 12;
724 private static final int MSG_ON_UID_GONE = 13;
725 private static final int MSG_ON_UID_IDLE = 14;
726
Makoto Onuki2206af32017-11-21 16:25:35 -0800727 public MyHandler(Looper looper) {
728 super(looper);
Makoto Onuki9be01402017-11-10 13:22:26 -0800729 }
Makoto Onuki2206af32017-11-21 16:25:35 -0800730
Makoto Onukiadb50d82018-01-29 16:20:30 -0800731 public void notifyUidActiveStateChanged(int uid) {
732 obtainMessage(MSG_UID_ACTIVE_STATE_CHANGED, uid, 0).sendToTarget();
733 }
734
Makoto Onuki2206af32017-11-21 16:25:35 -0800735 public void notifyUidForegroundStateChanged(int uid) {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800736 obtainMessage(MSG_UID_FG_STATE_CHANGED, uid, 0).sendToTarget();
Makoto Onuki2206af32017-11-21 16:25:35 -0800737 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800738
Makoto Onuki2206af32017-11-21 16:25:35 -0800739 public void notifyRunAnyAppOpsChanged(int uid, @NonNull String packageName) {
740 obtainMessage(MSG_RUN_ANY_CHANGED, uid, 0, packageName).sendToTarget();
741 }
742
743 public void notifyAllUnwhitelisted() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800744 removeMessages(MSG_ALL_UNWHITELISTED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800745 obtainMessage(MSG_ALL_UNWHITELISTED).sendToTarget();
746 }
747
748 public void notifyAllWhitelistChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800749 removeMessages(MSG_ALL_WHITELIST_CHANGED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800750 obtainMessage(MSG_ALL_WHITELIST_CHANGED).sendToTarget();
751 }
752
753 public void notifyTempWhitelistChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800754 removeMessages(MSG_TEMP_WHITELIST_CHANGED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800755 obtainMessage(MSG_TEMP_WHITELIST_CHANGED).sendToTarget();
756 }
757
758 public void notifyForceAllAppsStandbyChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800759 removeMessages(MSG_FORCE_ALL_CHANGED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800760 obtainMessage(MSG_FORCE_ALL_CHANGED).sendToTarget();
761 }
762
Nancy Zheng525aaa12018-01-12 11:45:37 -0800763 public void notifyForcedAppStandbyFeatureFlagChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800764 removeMessages(MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED);
Nancy Zheng525aaa12018-01-12 11:45:37 -0800765 obtainMessage(MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED).sendToTarget();
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800766 }
767
Makoto Onukieb898f12018-01-23 15:26:27 -0800768 public void notifyExemptChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800769 removeMessages(MSG_EXEMPT_CHANGED);
Makoto Onukieb898f12018-01-23 15:26:27 -0800770 obtainMessage(MSG_EXEMPT_CHANGED).sendToTarget();
771 }
772
Makoto Onuki2206af32017-11-21 16:25:35 -0800773 public void doUserRemoved(int userId) {
774 obtainMessage(MSG_USER_REMOVED, userId, 0).sendToTarget();
775 }
776
Makoto Onuki4d298b52018-02-05 10:54:58 -0800777 public void onUidStateChanged(int uid, int procState) {
778 obtainMessage(MSG_ON_UID_STATE_CHANGED, uid, procState).sendToTarget();
779 }
780
781 public void onUidActive(int uid) {
782 obtainMessage(MSG_ON_UID_ACTIVE, uid, 0).sendToTarget();
783 }
784
785 public void onUidGone(int uid, boolean disabled) {
786 obtainMessage(MSG_ON_UID_GONE, uid, disabled ? 1 : 0).sendToTarget();
787 }
788
789 public void onUidIdle(int uid, boolean disabled) {
790 obtainMessage(MSG_ON_UID_IDLE, uid, disabled ? 1 : 0).sendToTarget();
791 }
792
Makoto Onuki2206af32017-11-21 16:25:35 -0800793 @Override
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800794 public void handleMessage(Message msg) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800795 switch (msg.what) {
796 case MSG_USER_REMOVED:
797 handleUserRemoved(msg.arg1);
798 return;
799 }
800
801 // Only notify the listeners when started.
802 synchronized (mLock) {
803 if (!mStarted) {
804 return;
805 }
806 }
Makoto Onukie4918212018-02-06 11:30:15 -0800807 final AppStateTracker sender = AppStateTracker.this;
Makoto Onuki2206af32017-11-21 16:25:35 -0800808
Makoto Onukieb898f12018-01-23 15:26:27 -0800809 long start = mStatLogger.getTime();
Makoto Onuki2206af32017-11-21 16:25:35 -0800810 switch (msg.what) {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800811 case MSG_UID_ACTIVE_STATE_CHANGED:
812 for (Listener l : cloneListeners()) {
813 l.onUidActiveStateChanged(sender, msg.arg1);
814 }
815 mStatLogger.logDurationStat(Stats.UID_ACTIVE_STATE_CHANGED, start);
816 return;
817
818 case MSG_UID_FG_STATE_CHANGED:
Makoto Onuki2206af32017-11-21 16:25:35 -0800819 for (Listener l : cloneListeners()) {
820 l.onUidForegroundStateChanged(sender, msg.arg1);
821 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800822 mStatLogger.logDurationStat(Stats.UID_FG_STATE_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800823 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800824
Makoto Onuki2206af32017-11-21 16:25:35 -0800825 case MSG_RUN_ANY_CHANGED:
826 for (Listener l : cloneListeners()) {
827 l.onRunAnyAppOpsChanged(sender, msg.arg1, (String) msg.obj);
828 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800829 mStatLogger.logDurationStat(Stats.RUN_ANY_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800830 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800831
Makoto Onuki2206af32017-11-21 16:25:35 -0800832 case MSG_ALL_UNWHITELISTED:
833 for (Listener l : cloneListeners()) {
834 l.onPowerSaveUnwhitelisted(sender);
835 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800836 mStatLogger.logDurationStat(Stats.ALL_UNWHITELISTED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800837 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800838
Makoto Onuki2206af32017-11-21 16:25:35 -0800839 case MSG_ALL_WHITELIST_CHANGED:
840 for (Listener l : cloneListeners()) {
841 l.onPowerSaveWhitelistedChanged(sender);
842 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800843 mStatLogger.logDurationStat(Stats.ALL_WHITELIST_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800844 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800845
Makoto Onuki2206af32017-11-21 16:25:35 -0800846 case MSG_TEMP_WHITELIST_CHANGED:
847 for (Listener l : cloneListeners()) {
848 l.onTempPowerSaveWhitelistChanged(sender);
849 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800850 mStatLogger.logDurationStat(Stats.TEMP_WHITELIST_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800851 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800852
853 case MSG_EXEMPT_CHANGED:
854 for (Listener l : cloneListeners()) {
855 l.onExemptChanged(sender);
856 }
857 mStatLogger.logDurationStat(Stats.EXEMPT_CHANGED, start);
858 return;
859
Makoto Onuki2206af32017-11-21 16:25:35 -0800860 case MSG_FORCE_ALL_CHANGED:
861 for (Listener l : cloneListeners()) {
862 l.onForceAllAppsStandbyChanged(sender);
863 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800864 mStatLogger.logDurationStat(Stats.FORCE_ALL_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800865 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800866
Nancy Zheng525aaa12018-01-12 11:45:37 -0800867 case MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED:
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800868 // Feature flag for forced app standby changed.
869 final boolean unblockAlarms;
870 synchronized (mLock) {
871 unblockAlarms = !mForcedAppStandbyEnabled && !mForceAllAppsStandby;
872 }
Suprabh Shuklac25447d2018-01-19 16:43:35 -0800873 for (Listener l : cloneListeners()) {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800874 l.updateAllJobs();
875 if (unblockAlarms) {
876 l.unblockAllUnrestrictedAlarms();
877 }
878 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800879 mStatLogger.logDurationStat(
880 Stats.FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED, start);
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800881 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800882
Makoto Onuki2206af32017-11-21 16:25:35 -0800883 case MSG_USER_REMOVED:
884 handleUserRemoved(msg.arg1);
885 return;
Makoto Onuki4d298b52018-02-05 10:54:58 -0800886
887 case MSG_ON_UID_STATE_CHANGED:
888 handleUidStateChanged(msg.arg1, msg.arg2);
889 return;
890 case MSG_ON_UID_ACTIVE:
891 handleUidActive(msg.arg1);
892 return;
893 case MSG_ON_UID_GONE:
894 handleUidGone(msg.arg1, msg.arg1 != 0);
895 return;
896 case MSG_ON_UID_IDLE:
897 handleUidIdle(msg.arg1, msg.arg1 != 0);
898 return;
899 }
900 }
901
902 public void handleUidStateChanged(int uid, int procState) {
903 synchronized (mLock) {
904 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
905 if (removeUidFromArray(mForegroundUids, uid, false)) {
906 mHandler.notifyUidForegroundStateChanged(uid);
907 }
908 } else {
909 if (addUidToArray(mForegroundUids, uid)) {
910 mHandler.notifyUidForegroundStateChanged(uid);
911 }
912 }
913 }
914 }
915
916 public void handleUidActive(int uid) {
917 synchronized (mLock) {
918 if (addUidToArray(mActiveUids, uid)) {
919 mHandler.notifyUidActiveStateChanged(uid);
920 }
921 }
922 }
923
924 public void handleUidGone(int uid, boolean disabled) {
925 removeUid(uid, true);
926 }
927
928 public void handleUidIdle(int uid, boolean disabled) {
929 // Just to avoid excessive memcpy, don't remove from the array in this case.
930 removeUid(uid, false);
931 }
932
933 private void removeUid(int uid, boolean remove) {
934 synchronized (mLock) {
935 if (removeUidFromArray(mActiveUids, uid, remove)) {
936 mHandler.notifyUidActiveStateChanged(uid);
937 }
938 if (removeUidFromArray(mForegroundUids, uid, remove)) {
939 mHandler.notifyUidForegroundStateChanged(uid);
940 }
Makoto Onuki2206af32017-11-21 16:25:35 -0800941 }
942 }
943 }
944
945 void handleUserRemoved(int removedUserId) {
946 synchronized (mLock) {
947 for (int i = mRunAnyRestrictedPackages.size() - 1; i >= 0; i--) {
948 final Pair<Integer, String> pair = mRunAnyRestrictedPackages.valueAt(i);
949 final int uid = pair.first;
950 final int userId = UserHandle.getUserId(uid);
951
952 if (userId == removedUserId) {
953 mRunAnyRestrictedPackages.removeAt(i);
954 }
955 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800956 cleanUpArrayForUser(mActiveUids, removedUserId);
957 cleanUpArrayForUser(mForegroundUids, removedUserId);
Makoto Onukieb898f12018-01-23 15:26:27 -0800958 mExemptedPackages.remove(removedUserId);
Makoto Onuki2206af32017-11-21 16:25:35 -0800959 }
960 }
961
Makoto Onukiadb50d82018-01-29 16:20:30 -0800962 private void cleanUpArrayForUser(SparseBooleanArray array, int removedUserId) {
963 for (int i = array.size() - 1; i >= 0; i--) {
964 final int uid = array.keyAt(i);
965 final int userId = UserHandle.getUserId(uid);
966
967 if (userId == removedUserId) {
968 array.removeAt(i);
969 }
970 }
971 }
972
Makoto Onuki2206af32017-11-21 16:25:35 -0800973 /**
974 * Called by device idle controller to update the power save whitelists.
975 */
976 public void setPowerSaveWhitelistAppIds(
977 int[] powerSaveWhitelistAllAppIdArray, int[] tempWhitelistAppIdArray) {
978 synchronized (mLock) {
979 final int[] previousWhitelist = mPowerWhitelistedAllAppIds;
980 final int[] previousTempWhitelist = mTempWhitelistedAppIds;
981
982 mPowerWhitelistedAllAppIds = powerSaveWhitelistAllAppIdArray;
983 mTempWhitelistedAppIds = tempWhitelistAppIdArray;
984
985 if (isAnyAppIdUnwhitelisted(previousWhitelist, mPowerWhitelistedAllAppIds)) {
986 mHandler.notifyAllUnwhitelisted();
987 } else if (!Arrays.equals(previousWhitelist, mPowerWhitelistedAllAppIds)) {
988 mHandler.notifyAllWhitelistChanged();
989 }
990
991 if (!Arrays.equals(previousTempWhitelist, mTempWhitelistedAppIds)) {
992 mHandler.notifyTempWhitelistChanged();
993 }
994
995 }
996 }
997
998 /**
999 * @retunr true if a sorted app-id array {@code prevArray} has at least one element
1000 * that's not in a sorted app-id array {@code newArray}.
1001 */
1002 @VisibleForTesting
1003 static boolean isAnyAppIdUnwhitelisted(int[] prevArray, int[] newArray) {
1004 int i1 = 0;
1005 int i2 = 0;
1006 boolean prevFinished;
1007 boolean newFinished;
1008
1009 for (;;) {
1010 prevFinished = i1 >= prevArray.length;
1011 newFinished = i2 >= newArray.length;
1012 if (prevFinished || newFinished) {
1013 break;
1014 }
1015 int a1 = prevArray[i1];
1016 int a2 = newArray[i2];
1017
1018 if (a1 == a2) {
1019 i1++;
1020 i2++;
1021 continue;
1022 }
1023 if (a1 < a2) {
1024 // prevArray has an element that's not in a2.
1025 return true;
1026 }
1027 i2++;
1028 }
1029 if (prevFinished) {
1030 return false;
1031 }
1032 return newFinished;
Makoto Onuki9be01402017-11-10 13:22:26 -08001033 }
1034
1035 // Public interface.
1036
1037 /**
1038 * Register a new listener.
1039 */
1040 public void addListener(@NonNull Listener listener) {
1041 synchronized (mLock) {
1042 mListeners.add(listener);
1043 }
1044 }
1045
1046 /**
Makoto Onuki2206af32017-11-21 16:25:35 -08001047 * @return whether alarms should be restricted for a UID package-name.
Makoto Onuki9be01402017-11-10 13:22:26 -08001048 */
Suprabh Shuklac25447d2018-01-19 16:43:35 -08001049 public boolean areAlarmsRestricted(int uid, @NonNull String packageName,
1050 boolean allowWhileIdle) {
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001051 return isRestricted(uid, packageName, /*useTempWhitelistToo=*/ false,
Suprabh Shuklac25447d2018-01-19 16:43:35 -08001052 /* exemptOnBatterySaver =*/ allowWhileIdle);
Makoto Onuki2206af32017-11-21 16:25:35 -08001053 }
1054
1055 /**
1056 * @return whether jobs should be restricted for a UID package-name.
1057 */
Makoto Onuki15407842018-01-19 14:23:11 -08001058 public boolean areJobsRestricted(int uid, @NonNull String packageName,
1059 boolean hasForegroundExemption) {
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001060 return isRestricted(uid, packageName, /*useTempWhitelistToo=*/ true,
Makoto Onuki15407842018-01-19 14:23:11 -08001061 hasForegroundExemption);
Makoto Onuki2206af32017-11-21 16:25:35 -08001062 }
1063
1064 /**
1065 * @return whether force-app-standby is effective for a UID package-name.
1066 */
1067 private boolean isRestricted(int uid, @NonNull String packageName,
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001068 boolean useTempWhitelistToo, boolean exemptOnBatterySaver) {
Makoto Onukiadb50d82018-01-29 16:20:30 -08001069 if (isUidActive(uid)) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001070 return false;
1071 }
1072 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001073 // Whitelisted?
1074 final int appId = UserHandle.getAppId(uid);
1075 if (ArrayUtils.contains(mPowerWhitelistedAllAppIds, appId)) {
1076 return false;
1077 }
1078 if (useTempWhitelistToo &&
1079 ArrayUtils.contains(mTempWhitelistedAppIds, appId)) {
1080 return false;
1081 }
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001082 if (mForcedAppStandbyEnabled && isRunAnyRestrictedLocked(uid, packageName)) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001083 return true;
1084 }
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001085 if (exemptOnBatterySaver) {
1086 return false;
1087 }
Makoto Onukieb898f12018-01-23 15:26:27 -08001088 final int userId = UserHandle.getUserId(uid);
1089 if (mExemptedPackages.contains(userId, packageName)) {
1090 return false;
1091 }
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001092 return mForceAllAppsStandby;
Makoto Onuki9be01402017-11-10 13:22:26 -08001093 }
1094 }
1095
Makoto Onuki2206af32017-11-21 16:25:35 -08001096 /**
Makoto Onukie4918212018-02-06 11:30:15 -08001097 * @return whether a UID is in active or not *based on cached information.*
Makoto Onukiadb50d82018-01-29 16:20:30 -08001098 *
1099 * Note this information is based on the UID proc state callback, meaning it's updated
1100 * asynchronously and may subtly be stale. If the fresh data is needed, use
Makoto Onukie4918212018-02-06 11:30:15 -08001101 * {@link #isUidActiveSynced} instead.
Makoto Onukiadb50d82018-01-29 16:20:30 -08001102 */
1103 public boolean isUidActive(int uid) {
1104 if (UserHandle.isCore(uid)) {
1105 return true;
1106 }
1107 synchronized (mLock) {
1108 return mActiveUids.get(uid);
1109 }
1110 }
1111
1112 /**
Makoto Onukie4918212018-02-06 11:30:15 -08001113 * @return whether a UID is in active or not *right now.*
1114 *
1115 * This gives the fresh information, but may access the activity manager so is slower.
1116 */
1117 public boolean isUidActiveSynced(int uid) {
1118 if (isUidActive(uid)) { // Use the cached one first.
1119 return true;
1120 }
1121 final long start = mStatLogger.getTime();
1122
1123 final boolean ret = mActivityManagerInternal.isUidActive(uid);
1124 mStatLogger.logDurationStat(Stats.IS_UID_ACTIVE_RAW, start);
1125
1126 return ret;
1127 }
1128
1129 /**
Makoto Onuki2206af32017-11-21 16:25:35 -08001130 * @return whether a UID is in the foreground or not.
1131 *
Makoto Onuki15407842018-01-19 14:23:11 -08001132 * Note this information is based on the UID proc state callback, meaning it's updated
1133 * asynchronously and may subtly be stale. If the fresh data is needed, use
1134 * {@link ActivityManagerInternal#getUidProcessState} instead.
Makoto Onuki2206af32017-11-21 16:25:35 -08001135 */
Makoto Onukiadb50d82018-01-29 16:20:30 -08001136 public boolean isUidInForeground(int uid) {
Makoto Onuki9cc471c2018-01-23 12:33:56 -08001137 if (UserHandle.isCore(uid)) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001138 return true;
1139 }
1140 synchronized (mLock) {
1141 return mForegroundUids.get(uid);
1142 }
1143 }
1144
Makoto Onuki2206af32017-11-21 16:25:35 -08001145 /**
1146 * @return whether force all apps standby is enabled or not.
1147 *
Makoto Onuki2206af32017-11-21 16:25:35 -08001148 */
1149 boolean isForceAllAppsStandbyEnabled() {
Makoto Onuki9be01402017-11-10 13:22:26 -08001150 synchronized (mLock) {
1151 return mForceAllAppsStandby;
1152 }
1153 }
1154
Makoto Onuki2206af32017-11-21 16:25:35 -08001155 /**
1156 * @return whether a UID/package has {@code OP_RUN_ANY_IN_BACKGROUND} allowed or not.
1157 *
1158 * Note clients normally shouldn't need to access it. It's only for dumpsys.
1159 */
Makoto Onuki9be01402017-11-10 13:22:26 -08001160 public boolean isRunAnyInBackgroundAppOpsAllowed(int uid, @NonNull String packageName) {
1161 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001162 return !isRunAnyRestrictedLocked(uid, packageName);
Makoto Onuki9be01402017-11-10 13:22:26 -08001163 }
1164 }
1165
Makoto Onuki2206af32017-11-21 16:25:35 -08001166 /**
1167 * @return whether a UID is in the user / system defined power-save whitelist or not.
1168 *
1169 * Note clients normally shouldn't need to access it. It's only for dumpsys.
1170 */
1171 public boolean isUidPowerSaveWhitelisted(int uid) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001172 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001173 return ArrayUtils.contains(mPowerWhitelistedAllAppIds, UserHandle.getAppId(uid));
Makoto Onuki9be01402017-11-10 13:22:26 -08001174 }
1175 }
1176
Makoto Onuki2206af32017-11-21 16:25:35 -08001177 /**
1178 * @return whether a UID is in the temp power-save whitelist or not.
1179 *
1180 * Note clients normally shouldn't need to access it. It's only for dumpsys.
1181 */
1182 public boolean isUidTempPowerSaveWhitelisted(int uid) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001183 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001184 return ArrayUtils.contains(mTempWhitelistedAppIds, UserHandle.getAppId(uid));
1185 }
1186 }
1187
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001188 @Deprecated
1189 public void dump(PrintWriter pw, String prefix) {
1190 dump(new IndentingPrintWriter(pw, " ").setIndent(prefix));
1191 }
1192
1193 public void dump(IndentingPrintWriter pw) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001194 synchronized (mLock) {
Suprabh Shukla4deb8522018-01-08 16:27:10 -08001195 pw.println("Forced App Standby Feature enabled: " + mForcedAppStandbyEnabled);
1196
Makoto Onuki2206af32017-11-21 16:25:35 -08001197 pw.print("Force all apps standby: ");
1198 pw.println(isForceAllAppsStandbyEnabled());
1199
Nancy Zheng525aaa12018-01-12 11:45:37 -08001200 pw.print("Small Battery Device: ");
1201 pw.println(isSmallBatteryDevice());
1202
Nancy Zheng525aaa12018-01-12 11:45:37 -08001203 pw.print("Force all apps standby for small battery device: ");
1204 pw.println(mForceAllAppStandbyForSmallBattery);
1205
Nancy Zheng525aaa12018-01-12 11:45:37 -08001206 pw.print("Plugged In: ");
1207 pw.println(mIsPluggedIn);
1208
Makoto Onukiadb50d82018-01-29 16:20:30 -08001209 pw.print("Active uids: ");
1210 dumpUids(pw, mActiveUids);
Makoto Onuki2206af32017-11-21 16:25:35 -08001211
Makoto Onukiadb50d82018-01-29 16:20:30 -08001212 pw.print("Foreground uids: ");
1213 dumpUids(pw, mForegroundUids);
Makoto Onuki2206af32017-11-21 16:25:35 -08001214
Makoto Onuki2206af32017-11-21 16:25:35 -08001215 pw.print("Whitelist appids: ");
1216 pw.println(Arrays.toString(mPowerWhitelistedAllAppIds));
1217
Makoto Onuki2206af32017-11-21 16:25:35 -08001218 pw.print("Temp whitelist appids: ");
1219 pw.println(Arrays.toString(mTempWhitelistedAppIds));
1220
Makoto Onukieb898f12018-01-23 15:26:27 -08001221 pw.println("Exempted packages:");
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001222 pw.increaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001223 for (int i = 0; i < mExemptedPackages.size(); i++) {
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001224 pw.print("User ");
Makoto Onukieb898f12018-01-23 15:26:27 -08001225 pw.print(mExemptedPackages.keyAt(i));
1226 pw.println();
1227
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001228 pw.increaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001229 for (int j = 0; j < mExemptedPackages.sizeAt(i); j++) {
Makoto Onukieb898f12018-01-23 15:26:27 -08001230 pw.print(mExemptedPackages.valueAt(i, j));
1231 pw.println();
1232 }
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001233 pw.decreaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001234 }
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001235 pw.decreaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001236 pw.println();
1237
Makoto Onuki2206af32017-11-21 16:25:35 -08001238 pw.println("Restricted packages:");
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001239 pw.increaseIndent();
Makoto Onuki2206af32017-11-21 16:25:35 -08001240 for (Pair<Integer, String> uidAndPackage : mRunAnyRestrictedPackages) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001241 pw.print(UserHandle.formatUid(uidAndPackage.first));
1242 pw.print(" ");
1243 pw.print(uidAndPackage.second);
1244 pw.println();
1245 }
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001246 pw.decreaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001247
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001248 mStatLogger.dump(pw);
Makoto Onuki2206af32017-11-21 16:25:35 -08001249 }
1250 }
1251
Makoto Onukiadb50d82018-01-29 16:20:30 -08001252 private void dumpUids(PrintWriter pw, SparseBooleanArray array) {
1253 pw.print("[");
1254
1255 String sep = "";
1256 for (int i = 0; i < array.size(); i++) {
1257 if (array.valueAt(i)) {
1258 pw.print(sep);
1259 pw.print(UserHandle.formatUid(array.keyAt(i)));
1260 sep = " ";
1261 }
1262 }
1263 pw.println("]");
1264 }
1265
Makoto Onuki2206af32017-11-21 16:25:35 -08001266 public void dumpProto(ProtoOutputStream proto, long fieldId) {
1267 synchronized (mLock) {
1268 final long token = proto.start(fieldId);
1269
1270 proto.write(ForceAppStandbyTrackerProto.FORCE_ALL_APPS_STANDBY, mForceAllAppsStandby);
Nancy Zheng525aaa12018-01-12 11:45:37 -08001271 proto.write(ForceAppStandbyTrackerProto.IS_SMALL_BATTERY_DEVICE,
1272 isSmallBatteryDevice());
1273 proto.write(ForceAppStandbyTrackerProto.FORCE_ALL_APPS_STANDBY_FOR_SMALL_BATTERY,
1274 mForceAllAppStandbyForSmallBattery);
Makoto Onukieb898f12018-01-23 15:26:27 -08001275 proto.write(ForceAppStandbyTrackerProto.IS_PLUGGED_IN, mIsPluggedIn);
Makoto Onuki2206af32017-11-21 16:25:35 -08001276
Makoto Onukiadb50d82018-01-29 16:20:30 -08001277 for (int i = 0; i < mActiveUids.size(); i++) {
1278 if (mActiveUids.valueAt(i)) {
1279 proto.write(ForceAppStandbyTrackerProto.ACTIVE_UIDS,
1280 mActiveUids.keyAt(i));
1281 }
1282 }
1283
Makoto Onuki2206af32017-11-21 16:25:35 -08001284 for (int i = 0; i < mForegroundUids.size(); i++) {
1285 if (mForegroundUids.valueAt(i)) {
1286 proto.write(ForceAppStandbyTrackerProto.FOREGROUND_UIDS,
1287 mForegroundUids.keyAt(i));
1288 }
1289 }
1290
1291 for (int appId : mPowerWhitelistedAllAppIds) {
1292 proto.write(ForceAppStandbyTrackerProto.POWER_SAVE_WHITELIST_APP_IDS, appId);
1293 }
1294
1295 for (int appId : mTempWhitelistedAppIds) {
1296 proto.write(ForceAppStandbyTrackerProto.TEMP_POWER_SAVE_WHITELIST_APP_IDS, appId);
1297 }
1298
Makoto Onukieb898f12018-01-23 15:26:27 -08001299 for (int i = 0; i < mExemptedPackages.size(); i++) {
1300 for (int j = 0; j < mExemptedPackages.sizeAt(i); j++) {
1301 final long token2 = proto.start(
1302 ForceAppStandbyTrackerProto.EXEMPTED_PACKAGES);
1303
1304 proto.write(ExemptedPackage.USER_ID, mExemptedPackages.keyAt(i));
1305 proto.write(ExemptedPackage.PACKAGE_NAME, mExemptedPackages.valueAt(i, j));
1306
1307 proto.end(token2);
1308 }
1309 }
1310
Makoto Onuki2206af32017-11-21 16:25:35 -08001311 for (Pair<Integer, String> uidAndPackage : mRunAnyRestrictedPackages) {
1312 final long token2 = proto.start(
1313 ForceAppStandbyTrackerProto.RUN_ANY_IN_BACKGROUND_RESTRICTED_PACKAGES);
1314 proto.write(RunAnyInBackgroundRestrictedPackages.UID, uidAndPackage.first);
1315 proto.write(RunAnyInBackgroundRestrictedPackages.PACKAGE_NAME,
1316 uidAndPackage.second);
1317 proto.end(token2);
1318 }
Makoto Onukieb898f12018-01-23 15:26:27 -08001319
1320 mStatLogger.dumpProto(proto, ForceAppStandbyTrackerProto.STATS);
1321
Makoto Onuki2206af32017-11-21 16:25:35 -08001322 proto.end(token);
Makoto Onuki9be01402017-11-10 13:22:26 -08001323 }
1324 }
1325}