blob: 6d773e6eb202b974dfa8fab2ace25ca89d289129 [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 Onuki2206af32017-11-21 16:25:35 -080073 * Test:
Makoto Onukie4918212018-02-06 11:30:15 -080074 atest $ANDROID_BUILD_TOP/frameworks/base/services/tests/servicestests/src/com/android/server/AppStateTrackerTest.java
Makoto Onuki9be01402017-11-10 13:22:26 -080075 */
Makoto Onukie4918212018-02-06 11:30:15 -080076public class AppStateTracker {
Makoto Onukic871c872018-03-19 09:39:56 -070077 private static final String TAG = "AppStateTracker";
78 private static final boolean DEBUG = false;
Makoto Onuki9be01402017-11-10 13:22:26 -080079
80 private final Object mLock = new Object();
81 private final Context mContext;
82
Makoto Onuki2206af32017-11-21 16:25:35 -080083 @VisibleForTesting
84 static final int TARGET_OP = AppOpsManager.OP_RUN_ANY_IN_BACKGROUND;
85
86 IActivityManager mIActivityManager;
Makoto Onukie4918212018-02-06 11:30:15 -080087 ActivityManagerInternal mActivityManagerInternal;
Makoto Onuki9be01402017-11-10 13:22:26 -080088 AppOpsManager mAppOpsManager;
89 IAppOpsService mAppOpsService;
90 PowerManagerInternal mPowerManagerInternal;
Makoto Onukieb898f12018-01-23 15:26:27 -080091 StandbyTracker mStandbyTracker;
92 UsageStatsManagerInternal mUsageStatsManagerInternal;
Makoto Onuki9be01402017-11-10 13:22:26 -080093
Makoto Onuki2206af32017-11-21 16:25:35 -080094 private final MyHandler mHandler;
Makoto Onuki9be01402017-11-10 13:22:26 -080095
Nancy Zheng525aaa12018-01-12 11:45:37 -080096 @VisibleForTesting
97 FeatureFlagsObserver mFlagsObserver;
98
Makoto Onuki9be01402017-11-10 13:22:26 -080099 /**
100 * Pair of (uid (not user-id), packageName) with OP_RUN_ANY_IN_BACKGROUND *not* allowed.
101 */
102 @GuardedBy("mLock")
Makoto Onuki2206af32017-11-21 16:25:35 -0800103 final ArraySet<Pair<Integer, String>> mRunAnyRestrictedPackages = new ArraySet<>();
Makoto Onuki9be01402017-11-10 13:22:26 -0800104
Makoto Onukiadb50d82018-01-29 16:20:30 -0800105 /** UIDs that are active. */
106 @GuardedBy("mLock")
107 final SparseBooleanArray mActiveUids = new SparseBooleanArray();
108
109 /** UIDs that are in the foreground. */
Makoto Onuki9be01402017-11-10 13:22:26 -0800110 @GuardedBy("mLock")
111 final SparseBooleanArray mForegroundUids = new SparseBooleanArray();
112
Makoto Onuki71755c92018-01-16 14:15:44 -0800113 /**
114 * System except-idle + user whitelist in the device idle controller.
115 */
Makoto Onuki9be01402017-11-10 13:22:26 -0800116 @GuardedBy("mLock")
Makoto Onuki2206af32017-11-21 16:25:35 -0800117 private int[] mPowerWhitelistedAllAppIds = new int[0];
118
119 @GuardedBy("mLock")
120 private int[] mTempWhitelistedAppIds = mPowerWhitelistedAllAppIds;
121
Makoto Onukieb898f12018-01-23 15:26:27 -0800122 /**
123 * Per-user packages that are in the EXEMPT bucket.
124 */
125 @GuardedBy("mLock")
126 private final SparseSetArray<String> mExemptedPackages = new SparseSetArray<>();
127
Makoto Onuki2206af32017-11-21 16:25:35 -0800128 @GuardedBy("mLock")
Makoto Onuki9be01402017-11-10 13:22:26 -0800129 final ArraySet<Listener> mListeners = new ArraySet<>();
130
131 @GuardedBy("mLock")
132 boolean mStarted;
133
Nancy Zheng525aaa12018-01-12 11:45:37 -0800134 /**
135 * Only used for small battery use-case.
136 */
Makoto Onuki9be01402017-11-10 13:22:26 -0800137 @GuardedBy("mLock")
Nancy Zheng525aaa12018-01-12 11:45:37 -0800138 boolean mIsPluggedIn;
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800139
140 @GuardedBy("mLock")
Nancy Zheng525aaa12018-01-12 11:45:37 -0800141 boolean mBatterySaverEnabled;
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800142
Nancy Zheng525aaa12018-01-12 11:45:37 -0800143 /**
144 * True if the forced app standby is currently enabled
145 */
146 @GuardedBy("mLock")
147 boolean mForceAllAppsStandby;
148
149 /**
150 * True if the forced app standby for small battery devices feature is enabled in settings
151 */
152 @GuardedBy("mLock")
153 boolean mForceAllAppStandbyForSmallBattery;
154
155 /**
156 * True if the forced app standby feature is enabled in settings
157 */
158 @GuardedBy("mLock")
159 boolean mForcedAppStandbyEnabled;
160
Makoto Onukieb898f12018-01-23 15:26:27 -0800161 interface Stats {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800162 int UID_FG_STATE_CHANGED = 0;
163 int UID_ACTIVE_STATE_CHANGED = 1;
164 int RUN_ANY_CHANGED = 2;
165 int ALL_UNWHITELISTED = 3;
166 int ALL_WHITELIST_CHANGED = 4;
167 int TEMP_WHITELIST_CHANGED = 5;
168 int EXEMPT_CHANGED = 6;
169 int FORCE_ALL_CHANGED = 7;
170 int FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED = 8;
Makoto Onukie4918212018-02-06 11:30:15 -0800171
172 int IS_UID_ACTIVE_CACHED = 9;
173 int IS_UID_ACTIVE_RAW = 10;
Makoto Onukieb898f12018-01-23 15:26:27 -0800174 }
175
176 private final StatLogger mStatLogger = new StatLogger(new String[] {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800177 "UID_FG_STATE_CHANGED",
178 "UID_ACTIVE_STATE_CHANGED",
Makoto Onukieb898f12018-01-23 15:26:27 -0800179 "RUN_ANY_CHANGED",
180 "ALL_UNWHITELISTED",
181 "ALL_WHITELIST_CHANGED",
182 "TEMP_WHITELIST_CHANGED",
183 "EXEMPT_CHANGED",
184 "FORCE_ALL_CHANGED",
185 "FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED",
Makoto Onukie4918212018-02-06 11:30:15 -0800186
187 "IS_UID_ACTIVE_CACHED",
188 "IS_UID_ACTIVE_RAW",
Makoto Onukieb898f12018-01-23 15:26:27 -0800189 });
190
Nancy Zheng525aaa12018-01-12 11:45:37 -0800191 @VisibleForTesting
192 class FeatureFlagsObserver extends ContentObserver {
193 FeatureFlagsObserver() {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800194 super(null);
195 }
196
197 void register() {
198 mContext.getContentResolver().registerContentObserver(
199 Settings.Global.getUriFor(Settings.Global.FORCED_APP_STANDBY_ENABLED),
200 false, this);
Nancy Zheng525aaa12018-01-12 11:45:37 -0800201
202 mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor(
203 Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED), false, this);
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800204 }
205
206 boolean isForcedAppStandbyEnabled() {
Makoto Onukieb898f12018-01-23 15:26:27 -0800207 return injectGetGlobalSettingInt(Settings.Global.FORCED_APP_STANDBY_ENABLED, 1) == 1;
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800208 }
209
Nancy Zheng525aaa12018-01-12 11:45:37 -0800210 boolean isForcedAppStandbyForSmallBatteryEnabled() {
Makoto Onukieb898f12018-01-23 15:26:27 -0800211 return injectGetGlobalSettingInt(
Nancy Zheng525aaa12018-01-12 11:45:37 -0800212 Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED, 0) == 1;
213 }
214
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800215 @Override
Nancy Zheng525aaa12018-01-12 11:45:37 -0800216 public void onChange(boolean selfChange, Uri uri) {
217 if (Settings.Global.getUriFor(Settings.Global.FORCED_APP_STANDBY_ENABLED).equals(uri)) {
218 final boolean enabled = isForcedAppStandbyEnabled();
219 synchronized (mLock) {
220 if (mForcedAppStandbyEnabled == enabled) {
221 return;
222 }
223 mForcedAppStandbyEnabled = enabled;
224 if (DEBUG) {
225 Slog.d(TAG,"Forced app standby feature flag changed: "
226 + mForcedAppStandbyEnabled);
227 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800228 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800229 mHandler.notifyForcedAppStandbyFeatureFlagChanged();
230 } else if (Settings.Global.getUriFor(
231 Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED).equals(uri)) {
232 final boolean enabled = isForcedAppStandbyForSmallBatteryEnabled();
233 synchronized (mLock) {
234 if (mForceAllAppStandbyForSmallBattery == enabled) {
235 return;
236 }
237 mForceAllAppStandbyForSmallBattery = enabled;
238 if (DEBUG) {
239 Slog.d(TAG, "Forced app standby for small battery feature flag changed: "
240 + mForceAllAppStandbyForSmallBattery);
241 }
242 updateForceAllAppStandbyState();
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800243 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800244 } else {
245 Slog.w(TAG, "Unexpected feature flag uri encountered: " + uri);
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800246 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800247 }
248 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800249
250 public static abstract class Listener {
Makoto Onuki2206af32017-11-21 16:25:35 -0800251 /**
252 * This is called when the OP_RUN_ANY_IN_BACKGROUND appops changed for a package.
253 */
Makoto Onukie4918212018-02-06 11:30:15 -0800254 private void onRunAnyAppOpsChanged(AppStateTracker sender,
Makoto Onuki2206af32017-11-21 16:25:35 -0800255 int uid, @NonNull String packageName) {
Christopher Tate20afddd2018-02-28 15:19:19 -0800256 updateJobsForUidPackage(uid, packageName, sender.isUidActive(uid));
Makoto Onuki2206af32017-11-21 16:25:35 -0800257
Suprabh Shuklac25447d2018-01-19 16:43:35 -0800258 if (!sender.areAlarmsRestricted(uid, packageName, /*allowWhileIdle=*/ false)) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800259 unblockAlarmsForUidPackage(uid, packageName);
Suprabh Shuklac25447d2018-01-19 16:43:35 -0800260 } else if (!sender.areAlarmsRestricted(uid, packageName, /*allowWhileIdle=*/ true)){
261 // we need to deliver the allow-while-idle alarms for this uid, package
262 unblockAllUnrestrictedAlarms();
Makoto Onuki2206af32017-11-21 16:25:35 -0800263 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800264 }
265
Makoto Onuki2206af32017-11-21 16:25:35 -0800266 /**
267 * This is called when the foreground state changed for a UID.
268 */
Makoto Onukie4918212018-02-06 11:30:15 -0800269 private void onUidForegroundStateChanged(AppStateTracker sender, int uid) {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800270 onUidForeground(uid, sender.isUidInForeground(uid));
271 }
272
273 /**
274 * This is called when the active/idle state changed for a UID.
275 */
Makoto Onukie4918212018-02-06 11:30:15 -0800276 private void onUidActiveStateChanged(AppStateTracker sender, int uid) {
Christopher Tate20afddd2018-02-28 15:19:19 -0800277 final boolean isActive = sender.isUidActive(uid);
Makoto Onuki2206af32017-11-21 16:25:35 -0800278
Christopher Tate20afddd2018-02-28 15:19:19 -0800279 updateJobsForUid(uid, isActive);
280
281 if (isActive) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800282 unblockAlarmsForUid(uid);
283 }
284 }
285
286 /**
287 * This is called when an app-id(s) is removed from the power save whitelist.
288 */
Makoto Onukie4918212018-02-06 11:30:15 -0800289 private void onPowerSaveUnwhitelisted(AppStateTracker sender) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800290 updateAllJobs();
291 unblockAllUnrestrictedAlarms();
292 }
293
294 /**
295 * This is called when the power save whitelist changes, excluding the
296 * {@link #onPowerSaveUnwhitelisted} case.
297 */
Makoto Onukie4918212018-02-06 11:30:15 -0800298 private void onPowerSaveWhitelistedChanged(AppStateTracker sender) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800299 updateAllJobs();
300 }
301
302 /**
303 * This is called when the temp whitelist changes.
304 */
Makoto Onukie4918212018-02-06 11:30:15 -0800305 private void onTempPowerSaveWhitelistChanged(AppStateTracker sender) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800306
307 // TODO This case happens rather frequently; consider optimizing and update jobs
308 // only for affected app-ids.
309
310 updateAllJobs();
Makoto Onukieb898f12018-01-23 15:26:27 -0800311
312 // Note when an app is just put in the temp whitelist, we do *not* drain pending alarms.
313 }
314
315 /**
316 * This is called when the EXEMPT bucket is updated.
317 */
Makoto Onukie4918212018-02-06 11:30:15 -0800318 private void onExemptChanged(AppStateTracker sender) {
Makoto Onukieb898f12018-01-23 15:26:27 -0800319 // This doesn't happen very often, so just re-evaluate all jobs / alarms.
320 updateAllJobs();
321 unblockAllUnrestrictedAlarms();
Makoto Onuki2206af32017-11-21 16:25:35 -0800322 }
323
324 /**
325 * This is called when the global "force all apps standby" flag changes.
326 */
Makoto Onukie4918212018-02-06 11:30:15 -0800327 private void onForceAllAppsStandbyChanged(AppStateTracker sender) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800328 updateAllJobs();
329
330 if (!sender.isForceAllAppsStandbyEnabled()) {
331 unblockAllUnrestrictedAlarms();
332 }
333 }
334
335 /**
336 * Called when the job restrictions for multiple UIDs might have changed, so the job
337 * scheduler should re-evaluate all restrictions for all jobs.
338 */
339 public void updateAllJobs() {
340 }
341
342 /**
343 * Called when the job restrictions for a UID might have changed, so the job
344 * scheduler should re-evaluate all restrictions for all jobs.
345 */
Christopher Tate20afddd2018-02-28 15:19:19 -0800346 public void updateJobsForUid(int uid, boolean isNowActive) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800347 }
348
349 /**
350 * Called when the job restrictions for a UID - package might have changed, so the job
351 * scheduler should re-evaluate all restrictions for all jobs.
352 */
Christopher Tate20afddd2018-02-28 15:19:19 -0800353 public void updateJobsForUidPackage(int uid, String packageName, boolean isNowActive) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800354 }
355
356 /**
357 * Called when the job restrictions for multiple UIDs might have changed, so the alarm
358 * manager should re-evaluate all restrictions for all blocked jobs.
359 */
360 public void unblockAllUnrestrictedAlarms() {
361 }
362
363 /**
364 * Called when all jobs for a specific UID are unblocked.
365 */
366 public void unblockAlarmsForUid(int uid) {
367 }
368
369 /**
370 * Called when all alarms for a specific UID - package are unblocked.
371 */
372 public void unblockAlarmsForUidPackage(int uid, String packageName) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800373 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800374
375 /**
376 * Called when a UID comes into the foreground or the background.
377 *
378 * @see #isUidInForeground(int)
379 */
380 public void onUidForeground(int uid, boolean foreground) {
381 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800382 }
383
Makoto Onukie4918212018-02-06 11:30:15 -0800384 public AppStateTracker(Context context, Looper looper) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800385 mContext = context;
Makoto Onuki2206af32017-11-21 16:25:35 -0800386 mHandler = new MyHandler(looper);
387 }
388
Makoto Onuki9be01402017-11-10 13:22:26 -0800389 /**
390 * Call it when the system is ready.
391 */
Makoto Onukie4918212018-02-06 11:30:15 -0800392 public void onSystemServicesReady() {
Makoto Onuki9be01402017-11-10 13:22:26 -0800393 synchronized (mLock) {
394 if (mStarted) {
395 return;
396 }
397 mStarted = true;
398
Makoto Onuki2206af32017-11-21 16:25:35 -0800399 mIActivityManager = Preconditions.checkNotNull(injectIActivityManager());
Makoto Onukie4918212018-02-06 11:30:15 -0800400 mActivityManagerInternal = Preconditions.checkNotNull(injectActivityManagerInternal());
Makoto Onuki2206af32017-11-21 16:25:35 -0800401 mAppOpsManager = Preconditions.checkNotNull(injectAppOpsManager());
402 mAppOpsService = Preconditions.checkNotNull(injectIAppOpsService());
403 mPowerManagerInternal = Preconditions.checkNotNull(injectPowerManagerInternal());
Makoto Onukieb898f12018-01-23 15:26:27 -0800404 mUsageStatsManagerInternal = Preconditions.checkNotNull(
405 injectUsageStatsManagerInternal());
406
Nancy Zheng525aaa12018-01-12 11:45:37 -0800407 mFlagsObserver = new FeatureFlagsObserver();
408 mFlagsObserver.register();
409 mForcedAppStandbyEnabled = mFlagsObserver.isForcedAppStandbyEnabled();
410 mForceAllAppStandbyForSmallBattery =
411 mFlagsObserver.isForcedAppStandbyForSmallBatteryEnabled();
Makoto Onukieb898f12018-01-23 15:26:27 -0800412 mStandbyTracker = new StandbyTracker();
413 mUsageStatsManagerInternal.addAppIdleStateChangeListener(mStandbyTracker);
Makoto Onuki9be01402017-11-10 13:22:26 -0800414
415 try {
Makoto Onuki2206af32017-11-21 16:25:35 -0800416 mIActivityManager.registerUidObserver(new UidObserver(),
Makoto Onukiadb50d82018-01-29 16:20:30 -0800417 ActivityManager.UID_OBSERVER_GONE
418 | ActivityManager.UID_OBSERVER_IDLE
419 | ActivityManager.UID_OBSERVER_ACTIVE
420 | ActivityManager.UID_OBSERVER_PROCSTATE,
Makoto Onuki9be01402017-11-10 13:22:26 -0800421 ActivityManager.PROCESS_STATE_UNKNOWN, null);
Makoto Onuki2206af32017-11-21 16:25:35 -0800422 mAppOpsService.startWatchingMode(TARGET_OP, null,
Makoto Onuki9be01402017-11-10 13:22:26 -0800423 new AppOpsWatcher());
424 } catch (RemoteException e) {
425 // shouldn't happen.
426 }
427
Makoto Onuki2206af32017-11-21 16:25:35 -0800428 IntentFilter filter = new IntentFilter();
429 filter.addAction(Intent.ACTION_USER_REMOVED);
Nancy Zheng525aaa12018-01-12 11:45:37 -0800430 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800431 mContext.registerReceiver(new MyReceiver(), filter);
Makoto Onuki9be01402017-11-10 13:22:26 -0800432
433 refreshForcedAppStandbyUidPackagesLocked();
Makoto Onuki2206af32017-11-21 16:25:35 -0800434
435 mPowerManagerInternal.registerLowPowerModeObserver(
436 ServiceType.FORCE_ALL_APPS_STANDBY,
Nancy Zheng525aaa12018-01-12 11:45:37 -0800437 (state) -> {
438 synchronized (mLock) {
439 mBatterySaverEnabled = state.batterySaverEnabled;
440 updateForceAllAppStandbyState();
441 }
442 });
Makoto Onuki2206af32017-11-21 16:25:35 -0800443
Nancy Zheng525aaa12018-01-12 11:45:37 -0800444 mBatterySaverEnabled = mPowerManagerInternal.getLowPowerState(
445 ServiceType.FORCE_ALL_APPS_STANDBY).batterySaverEnabled;
446
447 updateForceAllAppStandbyState();
Makoto Onuki9be01402017-11-10 13:22:26 -0800448 }
449 }
450
Makoto Onuki2206af32017-11-21 16:25:35 -0800451 @VisibleForTesting
452 AppOpsManager injectAppOpsManager() {
453 return mContext.getSystemService(AppOpsManager.class);
454 }
455
456 @VisibleForTesting
457 IAppOpsService injectIAppOpsService() {
458 return IAppOpsService.Stub.asInterface(
459 ServiceManager.getService(Context.APP_OPS_SERVICE));
460 }
461
462 @VisibleForTesting
463 IActivityManager injectIActivityManager() {
464 return ActivityManager.getService();
465 }
466
467 @VisibleForTesting
Makoto Onukie4918212018-02-06 11:30:15 -0800468 ActivityManagerInternal injectActivityManagerInternal() {
469 return LocalServices.getService(ActivityManagerInternal.class);
470 }
471
472 @VisibleForTesting
Makoto Onuki2206af32017-11-21 16:25:35 -0800473 PowerManagerInternal injectPowerManagerInternal() {
474 return LocalServices.getService(PowerManagerInternal.class);
475 }
476
Nancy Zheng525aaa12018-01-12 11:45:37 -0800477 @VisibleForTesting
Makoto Onukieb898f12018-01-23 15:26:27 -0800478 UsageStatsManagerInternal injectUsageStatsManagerInternal() {
479 return LocalServices.getService(UsageStatsManagerInternal.class);
480 }
481
482 @VisibleForTesting
Nancy Zheng525aaa12018-01-12 11:45:37 -0800483 boolean isSmallBatteryDevice() {
484 return ActivityManager.isSmallBatteryDevice();
485 }
486
Makoto Onukieb898f12018-01-23 15:26:27 -0800487 @VisibleForTesting
488 int injectGetGlobalSettingInt(String key, int def) {
489 return Settings.Global.getInt(mContext.getContentResolver(), key, def);
490 }
491
Makoto Onuki9be01402017-11-10 13:22:26 -0800492 /**
Makoto Onuki2206af32017-11-21 16:25:35 -0800493 * Update {@link #mRunAnyRestrictedPackages} with the current app ops state.
Makoto Onuki9be01402017-11-10 13:22:26 -0800494 */
Andreas Gampea36dc622018-02-05 17:19:22 -0800495 @GuardedBy("mLock")
Makoto Onuki9be01402017-11-10 13:22:26 -0800496 private void refreshForcedAppStandbyUidPackagesLocked() {
Makoto Onuki2206af32017-11-21 16:25:35 -0800497 mRunAnyRestrictedPackages.clear();
498 final List<PackageOps> ops = mAppOpsManager.getPackagesForOps(
499 new int[] {TARGET_OP});
Makoto Onuki9be01402017-11-10 13:22:26 -0800500
501 if (ops == null) {
502 return;
503 }
504 final int size = ops.size();
505 for (int i = 0; i < size; i++) {
506 final AppOpsManager.PackageOps pkg = ops.get(i);
507 final List<AppOpsManager.OpEntry> entries = ops.get(i).getOps();
508
509 for (int j = 0; j < entries.size(); j++) {
510 AppOpsManager.OpEntry ent = entries.get(j);
Makoto Onuki2206af32017-11-21 16:25:35 -0800511 if (ent.getOp() != TARGET_OP) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800512 continue;
513 }
514 if (ent.getMode() != AppOpsManager.MODE_ALLOWED) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800515 mRunAnyRestrictedPackages.add(Pair.create(
Makoto Onuki9be01402017-11-10 13:22:26 -0800516 pkg.getUid(), pkg.getPackageName()));
517 }
518 }
519 }
520 }
521
Nancy Zheng525aaa12018-01-12 11:45:37 -0800522 private void updateForceAllAppStandbyState() {
523 synchronized (mLock) {
524 if (mForceAllAppStandbyForSmallBattery && isSmallBatteryDevice()) {
525 toggleForceAllAppsStandbyLocked(!mIsPluggedIn);
526 } else {
527 toggleForceAllAppsStandbyLocked(mBatterySaverEnabled);
528 }
529 }
530 }
531
Makoto Onuki2206af32017-11-21 16:25:35 -0800532 /**
533 * Update {@link #mForceAllAppsStandby} and notifies the listeners.
534 */
Andreas Gampea36dc622018-02-05 17:19:22 -0800535 @GuardedBy("mLock")
Nancy Zheng525aaa12018-01-12 11:45:37 -0800536 private void toggleForceAllAppsStandbyLocked(boolean enable) {
537 if (enable == mForceAllAppsStandby) {
538 return;
Makoto Onuki12391f22018-01-18 21:44:28 +0000539 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800540 mForceAllAppsStandby = enable;
541
542 mHandler.notifyForceAllAppsStandbyChanged();
Makoto Onuki9be01402017-11-10 13:22:26 -0800543 }
544
Andreas Gampea36dc622018-02-05 17:19:22 -0800545 @GuardedBy("mLock")
Makoto Onuki9be01402017-11-10 13:22:26 -0800546 private int findForcedAppStandbyUidPackageIndexLocked(int uid, @NonNull String packageName) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800547 final int size = mRunAnyRestrictedPackages.size();
548 if (size > 8) {
549 return mRunAnyRestrictedPackages.indexOf(Pair.create(uid, packageName));
550 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800551 for (int i = 0; i < size; i++) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800552 final Pair<Integer, String> pair = mRunAnyRestrictedPackages.valueAt(i);
Makoto Onuki9be01402017-11-10 13:22:26 -0800553
554 if ((pair.first == uid) && packageName.equals(pair.second)) {
555 return i;
556 }
557 }
558 return -1;
559 }
560
561 /**
Makoto Onuki2206af32017-11-21 16:25:35 -0800562 * @return whether a uid package-name pair is in mRunAnyRestrictedPackages.
Makoto Onuki9be01402017-11-10 13:22:26 -0800563 */
Andreas Gampea36dc622018-02-05 17:19:22 -0800564 @GuardedBy("mLock")
Makoto Onuki2206af32017-11-21 16:25:35 -0800565 boolean isRunAnyRestrictedLocked(int uid, @NonNull String packageName) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800566 return findForcedAppStandbyUidPackageIndexLocked(uid, packageName) >= 0;
567 }
568
Makoto Onuki2206af32017-11-21 16:25:35 -0800569 /**
570 * Add to / remove from {@link #mRunAnyRestrictedPackages}.
571 */
Andreas Gampea36dc622018-02-05 17:19:22 -0800572 @GuardedBy("mLock")
Makoto Onuki2206af32017-11-21 16:25:35 -0800573 boolean updateForcedAppStandbyUidPackageLocked(int uid, @NonNull String packageName,
Makoto Onuki9be01402017-11-10 13:22:26 -0800574 boolean restricted) {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800575 final int index = findForcedAppStandbyUidPackageIndexLocked(uid, packageName);
Makoto Onuki9be01402017-11-10 13:22:26 -0800576 final boolean wasRestricted = index >= 0;
577 if (wasRestricted == restricted) {
578 return false;
579 }
580 if (restricted) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800581 mRunAnyRestrictedPackages.add(Pair.create(uid, packageName));
Makoto Onuki9be01402017-11-10 13:22:26 -0800582 } else {
Makoto Onuki2206af32017-11-21 16:25:35 -0800583 mRunAnyRestrictedPackages.removeAt(index);
Makoto Onuki9be01402017-11-10 13:22:26 -0800584 }
585 return true;
586 }
587
Makoto Onukiadb50d82018-01-29 16:20:30 -0800588 private static boolean addUidToArray(SparseBooleanArray array, int uid) {
589 if (UserHandle.isCore(uid)) {
590 return false;
Makoto Onuki9be01402017-11-10 13:22:26 -0800591 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800592 if (array.get(uid)) {
593 return false;
594 }
595 array.put(uid, true);
596 return true;
Makoto Onuki9be01402017-11-10 13:22:26 -0800597 }
598
Makoto Onukiadb50d82018-01-29 16:20:30 -0800599 private static boolean removeUidFromArray(SparseBooleanArray array, int uid, boolean remove) {
600 if (UserHandle.isCore(uid)) {
601 return false;
Makoto Onuki9be01402017-11-10 13:22:26 -0800602 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800603 if (!array.get(uid)) {
604 return false;
605 }
606 if (remove) {
607 array.delete(uid);
608 } else {
609 array.put(uid, false);
610 }
611 return true;
Makoto Onuki9be01402017-11-10 13:22:26 -0800612 }
613
Makoto Onuki2206af32017-11-21 16:25:35 -0800614 private final class UidObserver extends IUidObserver.Stub {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800615 @Override
616 public void onUidStateChanged(int uid, int procState, long procStateSeq) {
Makoto Onuki4d298b52018-02-05 10:54:58 -0800617 mHandler.onUidStateChanged(uid, procState);
Makoto Onuki9be01402017-11-10 13:22:26 -0800618 }
619
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800620 @Override
621 public void onUidActive(int uid) {
Makoto Onuki4d298b52018-02-05 10:54:58 -0800622 mHandler.onUidActive(uid);
623 }
624
625 @Override
626 public void onUidGone(int uid, boolean disabled) {
627 mHandler.onUidGone(uid, disabled);
Makoto Onuki9be01402017-11-10 13:22:26 -0800628 }
629
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800630 @Override
631 public void onUidIdle(int uid, boolean disabled) {
Makoto Onuki4d298b52018-02-05 10:54:58 -0800632 mHandler.onUidIdle(uid, disabled);
Makoto Onuki9be01402017-11-10 13:22:26 -0800633 }
634
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800635 @Override
636 public void onUidCachedChanged(int uid, boolean cached) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800637 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800638 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800639
640 private final class AppOpsWatcher extends IAppOpsCallback.Stub {
641 @Override
642 public void opChanged(int op, int uid, String packageName) throws RemoteException {
Makoto Onuki2206af32017-11-21 16:25:35 -0800643 boolean restricted = false;
644 try {
645 restricted = mAppOpsService.checkOperation(TARGET_OP,
646 uid, packageName) != AppOpsManager.MODE_ALLOWED;
647 } catch (RemoteException e) {
648 // Shouldn't happen
649 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800650 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800651 if (updateForcedAppStandbyUidPackageLocked(uid, packageName, restricted)) {
652 mHandler.notifyRunAnyAppOpsChanged(uid, packageName);
653 }
654 }
655 }
656 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800657
Makoto Onuki2206af32017-11-21 16:25:35 -0800658 private final class MyReceiver extends BroadcastReceiver {
659 @Override
660 public void onReceive(Context context, Intent intent) {
661 if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
662 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
663 if (userId > 0) {
664 mHandler.doUserRemoved(userId);
Makoto Onuki9be01402017-11-10 13:22:26 -0800665 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800666 } else if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
667 synchronized (mLock) {
668 mIsPluggedIn = (intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0);
669 }
670 updateForceAllAppStandbyState();
Makoto Onuki9be01402017-11-10 13:22:26 -0800671 }
672 }
673 }
674
Makoto Onukieb898f12018-01-23 15:26:27 -0800675 final class StandbyTracker extends AppIdleStateChangeListener {
676 @Override
677 public void onAppIdleStateChanged(String packageName, int userId, boolean idle,
Amith Yamasani119be9a2018-02-18 22:23:00 -0800678 int bucket, int reason) {
Makoto Onukieb898f12018-01-23 15:26:27 -0800679 if (DEBUG) {
680 Slog.d(TAG,"onAppIdleStateChanged: " + packageName + " u" + userId
681 + (idle ? " idle" : " active") + " " + bucket);
682 }
683 final boolean changed;
684 if (bucket == UsageStatsManager.STANDBY_BUCKET_EXEMPTED) {
685 changed = mExemptedPackages.add(userId, packageName);
686 } else {
687 changed = mExemptedPackages.remove(userId, packageName);
688 }
689 if (changed) {
690 mHandler.notifyExemptChanged();
691 }
692 }
693
694 @Override
695 public void onParoleStateChanged(boolean isParoleOn) {
696 }
697 }
698
Makoto Onuki9be01402017-11-10 13:22:26 -0800699 private Listener[] cloneListeners() {
700 synchronized (mLock) {
701 return mListeners.toArray(new Listener[mListeners.size()]);
702 }
703 }
704
Makoto Onuki2206af32017-11-21 16:25:35 -0800705 private class MyHandler extends Handler {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800706 private static final int MSG_UID_ACTIVE_STATE_CHANGED = 0;
707 private static final int MSG_UID_FG_STATE_CHANGED = 1;
708 private static final int MSG_RUN_ANY_CHANGED = 3;
709 private static final int MSG_ALL_UNWHITELISTED = 4;
710 private static final int MSG_ALL_WHITELIST_CHANGED = 5;
711 private static final int MSG_TEMP_WHITELIST_CHANGED = 6;
712 private static final int MSG_FORCE_ALL_CHANGED = 7;
713 private static final int MSG_USER_REMOVED = 8;
714 private static final int MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED = 9;
715 private static final int MSG_EXEMPT_CHANGED = 10;
Makoto Onuki9be01402017-11-10 13:22:26 -0800716
Makoto Onuki4d298b52018-02-05 10:54:58 -0800717 private static final int MSG_ON_UID_STATE_CHANGED = 11;
718 private static final int MSG_ON_UID_ACTIVE = 12;
719 private static final int MSG_ON_UID_GONE = 13;
720 private static final int MSG_ON_UID_IDLE = 14;
721
Makoto Onuki2206af32017-11-21 16:25:35 -0800722 public MyHandler(Looper looper) {
723 super(looper);
Makoto Onuki9be01402017-11-10 13:22:26 -0800724 }
Makoto Onuki2206af32017-11-21 16:25:35 -0800725
Makoto Onukiadb50d82018-01-29 16:20:30 -0800726 public void notifyUidActiveStateChanged(int uid) {
727 obtainMessage(MSG_UID_ACTIVE_STATE_CHANGED, uid, 0).sendToTarget();
728 }
729
Makoto Onuki2206af32017-11-21 16:25:35 -0800730 public void notifyUidForegroundStateChanged(int uid) {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800731 obtainMessage(MSG_UID_FG_STATE_CHANGED, uid, 0).sendToTarget();
Makoto Onuki2206af32017-11-21 16:25:35 -0800732 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800733
Makoto Onuki2206af32017-11-21 16:25:35 -0800734 public void notifyRunAnyAppOpsChanged(int uid, @NonNull String packageName) {
735 obtainMessage(MSG_RUN_ANY_CHANGED, uid, 0, packageName).sendToTarget();
736 }
737
738 public void notifyAllUnwhitelisted() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800739 removeMessages(MSG_ALL_UNWHITELISTED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800740 obtainMessage(MSG_ALL_UNWHITELISTED).sendToTarget();
741 }
742
743 public void notifyAllWhitelistChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800744 removeMessages(MSG_ALL_WHITELIST_CHANGED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800745 obtainMessage(MSG_ALL_WHITELIST_CHANGED).sendToTarget();
746 }
747
748 public void notifyTempWhitelistChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800749 removeMessages(MSG_TEMP_WHITELIST_CHANGED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800750 obtainMessage(MSG_TEMP_WHITELIST_CHANGED).sendToTarget();
751 }
752
753 public void notifyForceAllAppsStandbyChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800754 removeMessages(MSG_FORCE_ALL_CHANGED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800755 obtainMessage(MSG_FORCE_ALL_CHANGED).sendToTarget();
756 }
757
Nancy Zheng525aaa12018-01-12 11:45:37 -0800758 public void notifyForcedAppStandbyFeatureFlagChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800759 removeMessages(MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED);
Nancy Zheng525aaa12018-01-12 11:45:37 -0800760 obtainMessage(MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED).sendToTarget();
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800761 }
762
Makoto Onukieb898f12018-01-23 15:26:27 -0800763 public void notifyExemptChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800764 removeMessages(MSG_EXEMPT_CHANGED);
Makoto Onukieb898f12018-01-23 15:26:27 -0800765 obtainMessage(MSG_EXEMPT_CHANGED).sendToTarget();
766 }
767
Makoto Onuki2206af32017-11-21 16:25:35 -0800768 public void doUserRemoved(int userId) {
769 obtainMessage(MSG_USER_REMOVED, userId, 0).sendToTarget();
770 }
771
Makoto Onuki4d298b52018-02-05 10:54:58 -0800772 public void onUidStateChanged(int uid, int procState) {
773 obtainMessage(MSG_ON_UID_STATE_CHANGED, uid, procState).sendToTarget();
774 }
775
776 public void onUidActive(int uid) {
777 obtainMessage(MSG_ON_UID_ACTIVE, uid, 0).sendToTarget();
778 }
779
780 public void onUidGone(int uid, boolean disabled) {
781 obtainMessage(MSG_ON_UID_GONE, uid, disabled ? 1 : 0).sendToTarget();
782 }
783
784 public void onUidIdle(int uid, boolean disabled) {
785 obtainMessage(MSG_ON_UID_IDLE, uid, disabled ? 1 : 0).sendToTarget();
786 }
787
Makoto Onuki2206af32017-11-21 16:25:35 -0800788 @Override
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800789 public void handleMessage(Message msg) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800790 switch (msg.what) {
791 case MSG_USER_REMOVED:
792 handleUserRemoved(msg.arg1);
793 return;
794 }
795
796 // Only notify the listeners when started.
797 synchronized (mLock) {
798 if (!mStarted) {
799 return;
800 }
801 }
Makoto Onukie4918212018-02-06 11:30:15 -0800802 final AppStateTracker sender = AppStateTracker.this;
Makoto Onuki2206af32017-11-21 16:25:35 -0800803
Makoto Onukieb898f12018-01-23 15:26:27 -0800804 long start = mStatLogger.getTime();
Makoto Onuki2206af32017-11-21 16:25:35 -0800805 switch (msg.what) {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800806 case MSG_UID_ACTIVE_STATE_CHANGED:
807 for (Listener l : cloneListeners()) {
808 l.onUidActiveStateChanged(sender, msg.arg1);
809 }
810 mStatLogger.logDurationStat(Stats.UID_ACTIVE_STATE_CHANGED, start);
811 return;
812
813 case MSG_UID_FG_STATE_CHANGED:
Makoto Onuki2206af32017-11-21 16:25:35 -0800814 for (Listener l : cloneListeners()) {
815 l.onUidForegroundStateChanged(sender, msg.arg1);
816 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800817 mStatLogger.logDurationStat(Stats.UID_FG_STATE_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800818 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800819
Makoto Onuki2206af32017-11-21 16:25:35 -0800820 case MSG_RUN_ANY_CHANGED:
821 for (Listener l : cloneListeners()) {
822 l.onRunAnyAppOpsChanged(sender, msg.arg1, (String) msg.obj);
823 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800824 mStatLogger.logDurationStat(Stats.RUN_ANY_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800825 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800826
Makoto Onuki2206af32017-11-21 16:25:35 -0800827 case MSG_ALL_UNWHITELISTED:
828 for (Listener l : cloneListeners()) {
829 l.onPowerSaveUnwhitelisted(sender);
830 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800831 mStatLogger.logDurationStat(Stats.ALL_UNWHITELISTED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800832 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800833
Makoto Onuki2206af32017-11-21 16:25:35 -0800834 case MSG_ALL_WHITELIST_CHANGED:
835 for (Listener l : cloneListeners()) {
836 l.onPowerSaveWhitelistedChanged(sender);
837 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800838 mStatLogger.logDurationStat(Stats.ALL_WHITELIST_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800839 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800840
Makoto Onuki2206af32017-11-21 16:25:35 -0800841 case MSG_TEMP_WHITELIST_CHANGED:
842 for (Listener l : cloneListeners()) {
843 l.onTempPowerSaveWhitelistChanged(sender);
844 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800845 mStatLogger.logDurationStat(Stats.TEMP_WHITELIST_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800846 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800847
848 case MSG_EXEMPT_CHANGED:
849 for (Listener l : cloneListeners()) {
850 l.onExemptChanged(sender);
851 }
852 mStatLogger.logDurationStat(Stats.EXEMPT_CHANGED, start);
853 return;
854
Makoto Onuki2206af32017-11-21 16:25:35 -0800855 case MSG_FORCE_ALL_CHANGED:
856 for (Listener l : cloneListeners()) {
857 l.onForceAllAppsStandbyChanged(sender);
858 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800859 mStatLogger.logDurationStat(Stats.FORCE_ALL_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800860 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800861
Nancy Zheng525aaa12018-01-12 11:45:37 -0800862 case MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED:
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800863 // Feature flag for forced app standby changed.
864 final boolean unblockAlarms;
865 synchronized (mLock) {
866 unblockAlarms = !mForcedAppStandbyEnabled && !mForceAllAppsStandby;
867 }
Suprabh Shuklac25447d2018-01-19 16:43:35 -0800868 for (Listener l : cloneListeners()) {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800869 l.updateAllJobs();
870 if (unblockAlarms) {
871 l.unblockAllUnrestrictedAlarms();
872 }
873 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800874 mStatLogger.logDurationStat(
875 Stats.FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED, start);
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800876 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800877
Makoto Onuki2206af32017-11-21 16:25:35 -0800878 case MSG_USER_REMOVED:
879 handleUserRemoved(msg.arg1);
880 return;
Makoto Onuki4d298b52018-02-05 10:54:58 -0800881
882 case MSG_ON_UID_STATE_CHANGED:
883 handleUidStateChanged(msg.arg1, msg.arg2);
884 return;
885 case MSG_ON_UID_ACTIVE:
886 handleUidActive(msg.arg1);
887 return;
888 case MSG_ON_UID_GONE:
889 handleUidGone(msg.arg1, msg.arg1 != 0);
890 return;
891 case MSG_ON_UID_IDLE:
892 handleUidIdle(msg.arg1, msg.arg1 != 0);
893 return;
894 }
895 }
896
897 public void handleUidStateChanged(int uid, int procState) {
898 synchronized (mLock) {
899 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
900 if (removeUidFromArray(mForegroundUids, uid, false)) {
901 mHandler.notifyUidForegroundStateChanged(uid);
902 }
903 } else {
904 if (addUidToArray(mForegroundUids, uid)) {
905 mHandler.notifyUidForegroundStateChanged(uid);
906 }
907 }
908 }
909 }
910
911 public void handleUidActive(int uid) {
912 synchronized (mLock) {
913 if (addUidToArray(mActiveUids, uid)) {
914 mHandler.notifyUidActiveStateChanged(uid);
915 }
916 }
917 }
918
919 public void handleUidGone(int uid, boolean disabled) {
920 removeUid(uid, true);
921 }
922
923 public void handleUidIdle(int uid, boolean disabled) {
924 // Just to avoid excessive memcpy, don't remove from the array in this case.
925 removeUid(uid, false);
926 }
927
928 private void removeUid(int uid, boolean remove) {
929 synchronized (mLock) {
930 if (removeUidFromArray(mActiveUids, uid, remove)) {
931 mHandler.notifyUidActiveStateChanged(uid);
932 }
933 if (removeUidFromArray(mForegroundUids, uid, remove)) {
934 mHandler.notifyUidForegroundStateChanged(uid);
935 }
Makoto Onuki2206af32017-11-21 16:25:35 -0800936 }
937 }
938 }
939
940 void handleUserRemoved(int removedUserId) {
941 synchronized (mLock) {
942 for (int i = mRunAnyRestrictedPackages.size() - 1; i >= 0; i--) {
943 final Pair<Integer, String> pair = mRunAnyRestrictedPackages.valueAt(i);
944 final int uid = pair.first;
945 final int userId = UserHandle.getUserId(uid);
946
947 if (userId == removedUserId) {
948 mRunAnyRestrictedPackages.removeAt(i);
949 }
950 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800951 cleanUpArrayForUser(mActiveUids, removedUserId);
952 cleanUpArrayForUser(mForegroundUids, removedUserId);
Makoto Onukieb898f12018-01-23 15:26:27 -0800953 mExemptedPackages.remove(removedUserId);
Makoto Onuki2206af32017-11-21 16:25:35 -0800954 }
955 }
956
Makoto Onukiadb50d82018-01-29 16:20:30 -0800957 private void cleanUpArrayForUser(SparseBooleanArray array, int removedUserId) {
958 for (int i = array.size() - 1; i >= 0; i--) {
959 final int uid = array.keyAt(i);
960 final int userId = UserHandle.getUserId(uid);
961
962 if (userId == removedUserId) {
963 array.removeAt(i);
964 }
965 }
966 }
967
Makoto Onuki2206af32017-11-21 16:25:35 -0800968 /**
969 * Called by device idle controller to update the power save whitelists.
970 */
971 public void setPowerSaveWhitelistAppIds(
972 int[] powerSaveWhitelistAllAppIdArray, int[] tempWhitelistAppIdArray) {
973 synchronized (mLock) {
974 final int[] previousWhitelist = mPowerWhitelistedAllAppIds;
975 final int[] previousTempWhitelist = mTempWhitelistedAppIds;
976
977 mPowerWhitelistedAllAppIds = powerSaveWhitelistAllAppIdArray;
978 mTempWhitelistedAppIds = tempWhitelistAppIdArray;
979
980 if (isAnyAppIdUnwhitelisted(previousWhitelist, mPowerWhitelistedAllAppIds)) {
981 mHandler.notifyAllUnwhitelisted();
982 } else if (!Arrays.equals(previousWhitelist, mPowerWhitelistedAllAppIds)) {
983 mHandler.notifyAllWhitelistChanged();
984 }
985
986 if (!Arrays.equals(previousTempWhitelist, mTempWhitelistedAppIds)) {
987 mHandler.notifyTempWhitelistChanged();
988 }
989
990 }
991 }
992
993 /**
994 * @retunr true if a sorted app-id array {@code prevArray} has at least one element
995 * that's not in a sorted app-id array {@code newArray}.
996 */
997 @VisibleForTesting
998 static boolean isAnyAppIdUnwhitelisted(int[] prevArray, int[] newArray) {
999 int i1 = 0;
1000 int i2 = 0;
1001 boolean prevFinished;
1002 boolean newFinished;
1003
1004 for (;;) {
1005 prevFinished = i1 >= prevArray.length;
1006 newFinished = i2 >= newArray.length;
1007 if (prevFinished || newFinished) {
1008 break;
1009 }
1010 int a1 = prevArray[i1];
1011 int a2 = newArray[i2];
1012
1013 if (a1 == a2) {
1014 i1++;
1015 i2++;
1016 continue;
1017 }
1018 if (a1 < a2) {
1019 // prevArray has an element that's not in a2.
1020 return true;
1021 }
1022 i2++;
1023 }
1024 if (prevFinished) {
1025 return false;
1026 }
1027 return newFinished;
Makoto Onuki9be01402017-11-10 13:22:26 -08001028 }
1029
1030 // Public interface.
1031
1032 /**
1033 * Register a new listener.
1034 */
1035 public void addListener(@NonNull Listener listener) {
1036 synchronized (mLock) {
1037 mListeners.add(listener);
1038 }
1039 }
1040
1041 /**
Makoto Onuki2206af32017-11-21 16:25:35 -08001042 * @return whether alarms should be restricted for a UID package-name.
Makoto Onuki9be01402017-11-10 13:22:26 -08001043 */
Suprabh Shuklac25447d2018-01-19 16:43:35 -08001044 public boolean areAlarmsRestricted(int uid, @NonNull String packageName,
1045 boolean allowWhileIdle) {
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001046 return isRestricted(uid, packageName, /*useTempWhitelistToo=*/ false,
Suprabh Shuklac25447d2018-01-19 16:43:35 -08001047 /* exemptOnBatterySaver =*/ allowWhileIdle);
Makoto Onuki2206af32017-11-21 16:25:35 -08001048 }
1049
1050 /**
1051 * @return whether jobs should be restricted for a UID package-name.
1052 */
Makoto Onuki15407842018-01-19 14:23:11 -08001053 public boolean areJobsRestricted(int uid, @NonNull String packageName,
1054 boolean hasForegroundExemption) {
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001055 return isRestricted(uid, packageName, /*useTempWhitelistToo=*/ true,
Makoto Onuki15407842018-01-19 14:23:11 -08001056 hasForegroundExemption);
Makoto Onuki2206af32017-11-21 16:25:35 -08001057 }
1058
1059 /**
1060 * @return whether force-app-standby is effective for a UID package-name.
1061 */
1062 private boolean isRestricted(int uid, @NonNull String packageName,
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001063 boolean useTempWhitelistToo, boolean exemptOnBatterySaver) {
Makoto Onukiadb50d82018-01-29 16:20:30 -08001064 if (isUidActive(uid)) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001065 return false;
1066 }
1067 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001068 // Whitelisted?
1069 final int appId = UserHandle.getAppId(uid);
1070 if (ArrayUtils.contains(mPowerWhitelistedAllAppIds, appId)) {
1071 return false;
1072 }
1073 if (useTempWhitelistToo &&
1074 ArrayUtils.contains(mTempWhitelistedAppIds, appId)) {
1075 return false;
1076 }
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001077 if (mForcedAppStandbyEnabled && isRunAnyRestrictedLocked(uid, packageName)) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001078 return true;
1079 }
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001080 if (exemptOnBatterySaver) {
1081 return false;
1082 }
Makoto Onukieb898f12018-01-23 15:26:27 -08001083 final int userId = UserHandle.getUserId(uid);
1084 if (mExemptedPackages.contains(userId, packageName)) {
1085 return false;
1086 }
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001087 return mForceAllAppsStandby;
Makoto Onuki9be01402017-11-10 13:22:26 -08001088 }
1089 }
1090
Makoto Onuki2206af32017-11-21 16:25:35 -08001091 /**
Makoto Onukie4918212018-02-06 11:30:15 -08001092 * @return whether a UID is in active or not *based on cached information.*
Makoto Onukiadb50d82018-01-29 16:20:30 -08001093 *
1094 * Note this information is based on the UID proc state callback, meaning it's updated
1095 * asynchronously and may subtly be stale. If the fresh data is needed, use
Makoto Onukie4918212018-02-06 11:30:15 -08001096 * {@link #isUidActiveSynced} instead.
Makoto Onukiadb50d82018-01-29 16:20:30 -08001097 */
1098 public boolean isUidActive(int uid) {
1099 if (UserHandle.isCore(uid)) {
1100 return true;
1101 }
1102 synchronized (mLock) {
1103 return mActiveUids.get(uid);
1104 }
1105 }
1106
1107 /**
Makoto Onukie4918212018-02-06 11:30:15 -08001108 * @return whether a UID is in active or not *right now.*
1109 *
1110 * This gives the fresh information, but may access the activity manager so is slower.
1111 */
1112 public boolean isUidActiveSynced(int uid) {
1113 if (isUidActive(uid)) { // Use the cached one first.
1114 return true;
1115 }
1116 final long start = mStatLogger.getTime();
1117
1118 final boolean ret = mActivityManagerInternal.isUidActive(uid);
1119 mStatLogger.logDurationStat(Stats.IS_UID_ACTIVE_RAW, start);
1120
1121 return ret;
1122 }
1123
1124 /**
Makoto Onuki2206af32017-11-21 16:25:35 -08001125 * @return whether a UID is in the foreground or not.
1126 *
Makoto Onuki15407842018-01-19 14:23:11 -08001127 * 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
1129 * {@link ActivityManagerInternal#getUidProcessState} instead.
Makoto Onuki2206af32017-11-21 16:25:35 -08001130 */
Makoto Onukiadb50d82018-01-29 16:20:30 -08001131 public boolean isUidInForeground(int uid) {
Makoto Onuki9cc471c2018-01-23 12:33:56 -08001132 if (UserHandle.isCore(uid)) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001133 return true;
1134 }
1135 synchronized (mLock) {
1136 return mForegroundUids.get(uid);
1137 }
1138 }
1139
Makoto Onuki2206af32017-11-21 16:25:35 -08001140 /**
1141 * @return whether force all apps standby is enabled or not.
1142 *
Makoto Onuki2206af32017-11-21 16:25:35 -08001143 */
1144 boolean isForceAllAppsStandbyEnabled() {
Makoto Onuki9be01402017-11-10 13:22:26 -08001145 synchronized (mLock) {
1146 return mForceAllAppsStandby;
1147 }
1148 }
1149
Makoto Onuki2206af32017-11-21 16:25:35 -08001150 /**
1151 * @return whether a UID/package has {@code OP_RUN_ANY_IN_BACKGROUND} allowed or not.
1152 *
1153 * Note clients normally shouldn't need to access it. It's only for dumpsys.
1154 */
Makoto Onuki9be01402017-11-10 13:22:26 -08001155 public boolean isRunAnyInBackgroundAppOpsAllowed(int uid, @NonNull String packageName) {
1156 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001157 return !isRunAnyRestrictedLocked(uid, packageName);
Makoto Onuki9be01402017-11-10 13:22:26 -08001158 }
1159 }
1160
Makoto Onuki2206af32017-11-21 16:25:35 -08001161 /**
1162 * @return whether a UID is in the user / system defined power-save whitelist or not.
1163 *
1164 * Note clients normally shouldn't need to access it. It's only for dumpsys.
1165 */
1166 public boolean isUidPowerSaveWhitelisted(int uid) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001167 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001168 return ArrayUtils.contains(mPowerWhitelistedAllAppIds, UserHandle.getAppId(uid));
Makoto Onuki9be01402017-11-10 13:22:26 -08001169 }
1170 }
1171
Makoto Onuki2206af32017-11-21 16:25:35 -08001172 /**
1173 * @return whether a UID is in the temp power-save whitelist or not.
1174 *
1175 * Note clients normally shouldn't need to access it. It's only for dumpsys.
1176 */
1177 public boolean isUidTempPowerSaveWhitelisted(int uid) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001178 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001179 return ArrayUtils.contains(mTempWhitelistedAppIds, UserHandle.getAppId(uid));
1180 }
1181 }
1182
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001183 @Deprecated
1184 public void dump(PrintWriter pw, String prefix) {
1185 dump(new IndentingPrintWriter(pw, " ").setIndent(prefix));
1186 }
1187
1188 public void dump(IndentingPrintWriter pw) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001189 synchronized (mLock) {
Suprabh Shukla4deb8522018-01-08 16:27:10 -08001190 pw.println("Forced App Standby Feature enabled: " + mForcedAppStandbyEnabled);
1191
Makoto Onuki2206af32017-11-21 16:25:35 -08001192 pw.print("Force all apps standby: ");
1193 pw.println(isForceAllAppsStandbyEnabled());
1194
Nancy Zheng525aaa12018-01-12 11:45:37 -08001195 pw.print("Small Battery Device: ");
1196 pw.println(isSmallBatteryDevice());
1197
Nancy Zheng525aaa12018-01-12 11:45:37 -08001198 pw.print("Force all apps standby for small battery device: ");
1199 pw.println(mForceAllAppStandbyForSmallBattery);
1200
Nancy Zheng525aaa12018-01-12 11:45:37 -08001201 pw.print("Plugged In: ");
1202 pw.println(mIsPluggedIn);
1203
Makoto Onukiadb50d82018-01-29 16:20:30 -08001204 pw.print("Active uids: ");
1205 dumpUids(pw, mActiveUids);
Makoto Onuki2206af32017-11-21 16:25:35 -08001206
Makoto Onukiadb50d82018-01-29 16:20:30 -08001207 pw.print("Foreground uids: ");
1208 dumpUids(pw, mForegroundUids);
Makoto Onuki2206af32017-11-21 16:25:35 -08001209
Makoto Onuki2206af32017-11-21 16:25:35 -08001210 pw.print("Whitelist appids: ");
1211 pw.println(Arrays.toString(mPowerWhitelistedAllAppIds));
1212
Makoto Onuki2206af32017-11-21 16:25:35 -08001213 pw.print("Temp whitelist appids: ");
1214 pw.println(Arrays.toString(mTempWhitelistedAppIds));
1215
Makoto Onukieb898f12018-01-23 15:26:27 -08001216 pw.println("Exempted packages:");
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001217 pw.increaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001218 for (int i = 0; i < mExemptedPackages.size(); i++) {
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001219 pw.print("User ");
Makoto Onukieb898f12018-01-23 15:26:27 -08001220 pw.print(mExemptedPackages.keyAt(i));
1221 pw.println();
1222
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001223 pw.increaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001224 for (int j = 0; j < mExemptedPackages.sizeAt(i); j++) {
Makoto Onukieb898f12018-01-23 15:26:27 -08001225 pw.print(mExemptedPackages.valueAt(i, j));
1226 pw.println();
1227 }
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001228 pw.decreaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001229 }
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001230 pw.decreaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001231 pw.println();
1232
Makoto Onuki2206af32017-11-21 16:25:35 -08001233 pw.println("Restricted packages:");
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001234 pw.increaseIndent();
Makoto Onuki2206af32017-11-21 16:25:35 -08001235 for (Pair<Integer, String> uidAndPackage : mRunAnyRestrictedPackages) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001236 pw.print(UserHandle.formatUid(uidAndPackage.first));
1237 pw.print(" ");
1238 pw.print(uidAndPackage.second);
1239 pw.println();
1240 }
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001241 pw.decreaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001242
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001243 mStatLogger.dump(pw);
Makoto Onuki2206af32017-11-21 16:25:35 -08001244 }
1245 }
1246
Makoto Onukiadb50d82018-01-29 16:20:30 -08001247 private void dumpUids(PrintWriter pw, SparseBooleanArray array) {
1248 pw.print("[");
1249
1250 String sep = "";
1251 for (int i = 0; i < array.size(); i++) {
1252 if (array.valueAt(i)) {
1253 pw.print(sep);
1254 pw.print(UserHandle.formatUid(array.keyAt(i)));
1255 sep = " ";
1256 }
1257 }
1258 pw.println("]");
1259 }
1260
Makoto Onuki2206af32017-11-21 16:25:35 -08001261 public void dumpProto(ProtoOutputStream proto, long fieldId) {
1262 synchronized (mLock) {
1263 final long token = proto.start(fieldId);
1264
1265 proto.write(ForceAppStandbyTrackerProto.FORCE_ALL_APPS_STANDBY, mForceAllAppsStandby);
Nancy Zheng525aaa12018-01-12 11:45:37 -08001266 proto.write(ForceAppStandbyTrackerProto.IS_SMALL_BATTERY_DEVICE,
1267 isSmallBatteryDevice());
1268 proto.write(ForceAppStandbyTrackerProto.FORCE_ALL_APPS_STANDBY_FOR_SMALL_BATTERY,
1269 mForceAllAppStandbyForSmallBattery);
Makoto Onukieb898f12018-01-23 15:26:27 -08001270 proto.write(ForceAppStandbyTrackerProto.IS_PLUGGED_IN, mIsPluggedIn);
Makoto Onuki2206af32017-11-21 16:25:35 -08001271
Makoto Onukiadb50d82018-01-29 16:20:30 -08001272 for (int i = 0; i < mActiveUids.size(); i++) {
1273 if (mActiveUids.valueAt(i)) {
1274 proto.write(ForceAppStandbyTrackerProto.ACTIVE_UIDS,
1275 mActiveUids.keyAt(i));
1276 }
1277 }
1278
Makoto Onuki2206af32017-11-21 16:25:35 -08001279 for (int i = 0; i < mForegroundUids.size(); i++) {
1280 if (mForegroundUids.valueAt(i)) {
1281 proto.write(ForceAppStandbyTrackerProto.FOREGROUND_UIDS,
1282 mForegroundUids.keyAt(i));
1283 }
1284 }
1285
1286 for (int appId : mPowerWhitelistedAllAppIds) {
1287 proto.write(ForceAppStandbyTrackerProto.POWER_SAVE_WHITELIST_APP_IDS, appId);
1288 }
1289
1290 for (int appId : mTempWhitelistedAppIds) {
1291 proto.write(ForceAppStandbyTrackerProto.TEMP_POWER_SAVE_WHITELIST_APP_IDS, appId);
1292 }
1293
Makoto Onukieb898f12018-01-23 15:26:27 -08001294 for (int i = 0; i < mExemptedPackages.size(); i++) {
1295 for (int j = 0; j < mExemptedPackages.sizeAt(i); j++) {
1296 final long token2 = proto.start(
1297 ForceAppStandbyTrackerProto.EXEMPTED_PACKAGES);
1298
1299 proto.write(ExemptedPackage.USER_ID, mExemptedPackages.keyAt(i));
1300 proto.write(ExemptedPackage.PACKAGE_NAME, mExemptedPackages.valueAt(i, j));
1301
1302 proto.end(token2);
1303 }
1304 }
1305
Makoto Onuki2206af32017-11-21 16:25:35 -08001306 for (Pair<Integer, String> uidAndPackage : mRunAnyRestrictedPackages) {
1307 final long token2 = proto.start(
1308 ForceAppStandbyTrackerProto.RUN_ANY_IN_BACKGROUND_RESTRICTED_PACKAGES);
1309 proto.write(RunAnyInBackgroundRestrictedPackages.UID, uidAndPackage.first);
1310 proto.write(RunAnyInBackgroundRestrictedPackages.PACKAGE_NAME,
1311 uidAndPackage.second);
1312 proto.end(token2);
1313 }
Makoto Onukieb898f12018-01-23 15:26:27 -08001314
1315 mStatLogger.dumpProto(proto, ForceAppStandbyTrackerProto.STATS);
1316
Makoto Onuki2206af32017-11-21 16:25:35 -08001317 proto.end(token);
Makoto Onuki9be01402017-11-10 13:22:26 -08001318 }
1319 }
1320}