blob: cec4f1a0bdd7398a18ff779260ff085922319fde [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 }
Christopher Tatec7933ac2018-03-12 17:57:09 -0700264
265 if (!sender.isRunAnyInBackgroundAppOpsAllowed(uid, packageName)) {
266 Slog.v(TAG, "Package " + packageName + "/" + uid
267 + " toggled into fg service restriction");
268 stopForegroundServicesForUidPackage(uid, packageName);
269 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800270 }
271
Makoto Onuki2206af32017-11-21 16:25:35 -0800272 /**
273 * This is called when the foreground state changed for a UID.
274 */
Makoto Onukie4918212018-02-06 11:30:15 -0800275 private void onUidForegroundStateChanged(AppStateTracker sender, int uid) {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800276 onUidForeground(uid, sender.isUidInForeground(uid));
277 }
278
279 /**
280 * This is called when the active/idle state changed for a UID.
281 */
Makoto Onukie4918212018-02-06 11:30:15 -0800282 private void onUidActiveStateChanged(AppStateTracker sender, int uid) {
Christopher Tate20afddd2018-02-28 15:19:19 -0800283 final boolean isActive = sender.isUidActive(uid);
Makoto Onuki2206af32017-11-21 16:25:35 -0800284
Christopher Tate20afddd2018-02-28 15:19:19 -0800285 updateJobsForUid(uid, isActive);
286
287 if (isActive) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800288 unblockAlarmsForUid(uid);
289 }
290 }
291
292 /**
293 * This is called when an app-id(s) is removed from the power save whitelist.
294 */
Makoto Onukie4918212018-02-06 11:30:15 -0800295 private void onPowerSaveUnwhitelisted(AppStateTracker sender) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800296 updateAllJobs();
297 unblockAllUnrestrictedAlarms();
298 }
299
300 /**
301 * This is called when the power save whitelist changes, excluding the
302 * {@link #onPowerSaveUnwhitelisted} case.
303 */
Makoto Onukie4918212018-02-06 11:30:15 -0800304 private void onPowerSaveWhitelistedChanged(AppStateTracker sender) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800305 updateAllJobs();
306 }
307
308 /**
309 * This is called when the temp whitelist changes.
310 */
Makoto Onukie4918212018-02-06 11:30:15 -0800311 private void onTempPowerSaveWhitelistChanged(AppStateTracker sender) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800312
313 // TODO This case happens rather frequently; consider optimizing and update jobs
314 // only for affected app-ids.
315
316 updateAllJobs();
Makoto Onukieb898f12018-01-23 15:26:27 -0800317
318 // Note when an app is just put in the temp whitelist, we do *not* drain pending alarms.
319 }
320
321 /**
322 * This is called when the EXEMPT bucket is updated.
323 */
Makoto Onukie4918212018-02-06 11:30:15 -0800324 private void onExemptChanged(AppStateTracker sender) {
Makoto Onukieb898f12018-01-23 15:26:27 -0800325 // This doesn't happen very often, so just re-evaluate all jobs / alarms.
326 updateAllJobs();
327 unblockAllUnrestrictedAlarms();
Makoto Onuki2206af32017-11-21 16:25:35 -0800328 }
329
330 /**
331 * This is called when the global "force all apps standby" flag changes.
332 */
Makoto Onukie4918212018-02-06 11:30:15 -0800333 private void onForceAllAppsStandbyChanged(AppStateTracker sender) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800334 updateAllJobs();
335
336 if (!sender.isForceAllAppsStandbyEnabled()) {
337 unblockAllUnrestrictedAlarms();
338 }
339 }
340
341 /**
342 * Called when the job restrictions for multiple UIDs might have changed, so the job
343 * scheduler should re-evaluate all restrictions for all jobs.
344 */
345 public void updateAllJobs() {
346 }
347
348 /**
349 * Called when the job restrictions for a UID might have changed, so the job
350 * scheduler should re-evaluate all restrictions for all jobs.
351 */
Christopher Tate20afddd2018-02-28 15:19:19 -0800352 public void updateJobsForUid(int uid, boolean isNowActive) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800353 }
354
355 /**
356 * Called when the job restrictions for a UID - package might have changed, so the job
357 * scheduler should re-evaluate all restrictions for all jobs.
358 */
Christopher Tate20afddd2018-02-28 15:19:19 -0800359 public void updateJobsForUidPackage(int uid, String packageName, boolean isNowActive) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800360 }
361
362 /**
Christopher Tatec7933ac2018-03-12 17:57:09 -0700363 * Called when an app goes into forced app standby and its foreground
364 * services need to be removed from that state.
365 */
366 public void stopForegroundServicesForUidPackage(int uid, String packageName) {
367 }
368
369 /**
Makoto Onuki2206af32017-11-21 16:25:35 -0800370 * Called when the job restrictions for multiple UIDs might have changed, so the alarm
371 * manager should re-evaluate all restrictions for all blocked jobs.
372 */
373 public void unblockAllUnrestrictedAlarms() {
374 }
375
376 /**
377 * Called when all jobs for a specific UID are unblocked.
378 */
379 public void unblockAlarmsForUid(int uid) {
380 }
381
382 /**
383 * Called when all alarms for a specific UID - package are unblocked.
384 */
385 public void unblockAlarmsForUidPackage(int uid, String packageName) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800386 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800387
388 /**
389 * Called when a UID comes into the foreground or the background.
390 *
391 * @see #isUidInForeground(int)
392 */
393 public void onUidForeground(int uid, boolean foreground) {
394 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800395 }
396
Makoto Onukie4918212018-02-06 11:30:15 -0800397 public AppStateTracker(Context context, Looper looper) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800398 mContext = context;
Makoto Onuki2206af32017-11-21 16:25:35 -0800399 mHandler = new MyHandler(looper);
400 }
401
Makoto Onuki9be01402017-11-10 13:22:26 -0800402 /**
403 * Call it when the system is ready.
404 */
Makoto Onukie4918212018-02-06 11:30:15 -0800405 public void onSystemServicesReady() {
Makoto Onuki9be01402017-11-10 13:22:26 -0800406 synchronized (mLock) {
407 if (mStarted) {
408 return;
409 }
410 mStarted = true;
411
Makoto Onuki2206af32017-11-21 16:25:35 -0800412 mIActivityManager = Preconditions.checkNotNull(injectIActivityManager());
Makoto Onukie4918212018-02-06 11:30:15 -0800413 mActivityManagerInternal = Preconditions.checkNotNull(injectActivityManagerInternal());
Makoto Onuki2206af32017-11-21 16:25:35 -0800414 mAppOpsManager = Preconditions.checkNotNull(injectAppOpsManager());
415 mAppOpsService = Preconditions.checkNotNull(injectIAppOpsService());
416 mPowerManagerInternal = Preconditions.checkNotNull(injectPowerManagerInternal());
Makoto Onukieb898f12018-01-23 15:26:27 -0800417 mUsageStatsManagerInternal = Preconditions.checkNotNull(
418 injectUsageStatsManagerInternal());
419
Nancy Zheng525aaa12018-01-12 11:45:37 -0800420 mFlagsObserver = new FeatureFlagsObserver();
421 mFlagsObserver.register();
422 mForcedAppStandbyEnabled = mFlagsObserver.isForcedAppStandbyEnabled();
423 mForceAllAppStandbyForSmallBattery =
424 mFlagsObserver.isForcedAppStandbyForSmallBatteryEnabled();
Makoto Onukieb898f12018-01-23 15:26:27 -0800425 mStandbyTracker = new StandbyTracker();
426 mUsageStatsManagerInternal.addAppIdleStateChangeListener(mStandbyTracker);
Makoto Onuki9be01402017-11-10 13:22:26 -0800427
428 try {
Makoto Onuki2206af32017-11-21 16:25:35 -0800429 mIActivityManager.registerUidObserver(new UidObserver(),
Makoto Onukiadb50d82018-01-29 16:20:30 -0800430 ActivityManager.UID_OBSERVER_GONE
431 | ActivityManager.UID_OBSERVER_IDLE
432 | ActivityManager.UID_OBSERVER_ACTIVE
433 | ActivityManager.UID_OBSERVER_PROCSTATE,
Makoto Onuki9be01402017-11-10 13:22:26 -0800434 ActivityManager.PROCESS_STATE_UNKNOWN, null);
Makoto Onuki2206af32017-11-21 16:25:35 -0800435 mAppOpsService.startWatchingMode(TARGET_OP, null,
Makoto Onuki9be01402017-11-10 13:22:26 -0800436 new AppOpsWatcher());
437 } catch (RemoteException e) {
438 // shouldn't happen.
439 }
440
Makoto Onuki2206af32017-11-21 16:25:35 -0800441 IntentFilter filter = new IntentFilter();
442 filter.addAction(Intent.ACTION_USER_REMOVED);
Nancy Zheng525aaa12018-01-12 11:45:37 -0800443 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800444 mContext.registerReceiver(new MyReceiver(), filter);
Makoto Onuki9be01402017-11-10 13:22:26 -0800445
446 refreshForcedAppStandbyUidPackagesLocked();
Makoto Onuki2206af32017-11-21 16:25:35 -0800447
448 mPowerManagerInternal.registerLowPowerModeObserver(
449 ServiceType.FORCE_ALL_APPS_STANDBY,
Nancy Zheng525aaa12018-01-12 11:45:37 -0800450 (state) -> {
451 synchronized (mLock) {
452 mBatterySaverEnabled = state.batterySaverEnabled;
453 updateForceAllAppStandbyState();
454 }
455 });
Makoto Onuki2206af32017-11-21 16:25:35 -0800456
Nancy Zheng525aaa12018-01-12 11:45:37 -0800457 mBatterySaverEnabled = mPowerManagerInternal.getLowPowerState(
458 ServiceType.FORCE_ALL_APPS_STANDBY).batterySaverEnabled;
459
460 updateForceAllAppStandbyState();
Makoto Onuki9be01402017-11-10 13:22:26 -0800461 }
462 }
463
Makoto Onuki2206af32017-11-21 16:25:35 -0800464 @VisibleForTesting
465 AppOpsManager injectAppOpsManager() {
466 return mContext.getSystemService(AppOpsManager.class);
467 }
468
469 @VisibleForTesting
470 IAppOpsService injectIAppOpsService() {
471 return IAppOpsService.Stub.asInterface(
472 ServiceManager.getService(Context.APP_OPS_SERVICE));
473 }
474
475 @VisibleForTesting
476 IActivityManager injectIActivityManager() {
477 return ActivityManager.getService();
478 }
479
480 @VisibleForTesting
Makoto Onukie4918212018-02-06 11:30:15 -0800481 ActivityManagerInternal injectActivityManagerInternal() {
482 return LocalServices.getService(ActivityManagerInternal.class);
483 }
484
485 @VisibleForTesting
Makoto Onuki2206af32017-11-21 16:25:35 -0800486 PowerManagerInternal injectPowerManagerInternal() {
487 return LocalServices.getService(PowerManagerInternal.class);
488 }
489
Nancy Zheng525aaa12018-01-12 11:45:37 -0800490 @VisibleForTesting
Makoto Onukieb898f12018-01-23 15:26:27 -0800491 UsageStatsManagerInternal injectUsageStatsManagerInternal() {
492 return LocalServices.getService(UsageStatsManagerInternal.class);
493 }
494
495 @VisibleForTesting
Nancy Zheng525aaa12018-01-12 11:45:37 -0800496 boolean isSmallBatteryDevice() {
497 return ActivityManager.isSmallBatteryDevice();
498 }
499
Makoto Onukieb898f12018-01-23 15:26:27 -0800500 @VisibleForTesting
501 int injectGetGlobalSettingInt(String key, int def) {
502 return Settings.Global.getInt(mContext.getContentResolver(), key, def);
503 }
504
Makoto Onuki9be01402017-11-10 13:22:26 -0800505 /**
Makoto Onuki2206af32017-11-21 16:25:35 -0800506 * Update {@link #mRunAnyRestrictedPackages} with the current app ops state.
Makoto Onuki9be01402017-11-10 13:22:26 -0800507 */
Andreas Gampea36dc622018-02-05 17:19:22 -0800508 @GuardedBy("mLock")
Makoto Onuki9be01402017-11-10 13:22:26 -0800509 private void refreshForcedAppStandbyUidPackagesLocked() {
Makoto Onuki2206af32017-11-21 16:25:35 -0800510 mRunAnyRestrictedPackages.clear();
511 final List<PackageOps> ops = mAppOpsManager.getPackagesForOps(
512 new int[] {TARGET_OP});
Makoto Onuki9be01402017-11-10 13:22:26 -0800513
514 if (ops == null) {
515 return;
516 }
517 final int size = ops.size();
518 for (int i = 0; i < size; i++) {
519 final AppOpsManager.PackageOps pkg = ops.get(i);
520 final List<AppOpsManager.OpEntry> entries = ops.get(i).getOps();
521
522 for (int j = 0; j < entries.size(); j++) {
523 AppOpsManager.OpEntry ent = entries.get(j);
Makoto Onuki2206af32017-11-21 16:25:35 -0800524 if (ent.getOp() != TARGET_OP) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800525 continue;
526 }
527 if (ent.getMode() != AppOpsManager.MODE_ALLOWED) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800528 mRunAnyRestrictedPackages.add(Pair.create(
Makoto Onuki9be01402017-11-10 13:22:26 -0800529 pkg.getUid(), pkg.getPackageName()));
530 }
531 }
532 }
533 }
534
Nancy Zheng525aaa12018-01-12 11:45:37 -0800535 private void updateForceAllAppStandbyState() {
536 synchronized (mLock) {
537 if (mForceAllAppStandbyForSmallBattery && isSmallBatteryDevice()) {
538 toggleForceAllAppsStandbyLocked(!mIsPluggedIn);
539 } else {
540 toggleForceAllAppsStandbyLocked(mBatterySaverEnabled);
541 }
542 }
543 }
544
Makoto Onuki2206af32017-11-21 16:25:35 -0800545 /**
546 * Update {@link #mForceAllAppsStandby} and notifies the listeners.
547 */
Andreas Gampea36dc622018-02-05 17:19:22 -0800548 @GuardedBy("mLock")
Nancy Zheng525aaa12018-01-12 11:45:37 -0800549 private void toggleForceAllAppsStandbyLocked(boolean enable) {
550 if (enable == mForceAllAppsStandby) {
551 return;
Makoto Onuki12391f22018-01-18 21:44:28 +0000552 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800553 mForceAllAppsStandby = enable;
554
555 mHandler.notifyForceAllAppsStandbyChanged();
Makoto Onuki9be01402017-11-10 13:22:26 -0800556 }
557
Andreas Gampea36dc622018-02-05 17:19:22 -0800558 @GuardedBy("mLock")
Makoto Onuki9be01402017-11-10 13:22:26 -0800559 private int findForcedAppStandbyUidPackageIndexLocked(int uid, @NonNull String packageName) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800560 final int size = mRunAnyRestrictedPackages.size();
561 if (size > 8) {
562 return mRunAnyRestrictedPackages.indexOf(Pair.create(uid, packageName));
563 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800564 for (int i = 0; i < size; i++) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800565 final Pair<Integer, String> pair = mRunAnyRestrictedPackages.valueAt(i);
Makoto Onuki9be01402017-11-10 13:22:26 -0800566
567 if ((pair.first == uid) && packageName.equals(pair.second)) {
568 return i;
569 }
570 }
571 return -1;
572 }
573
574 /**
Makoto Onuki2206af32017-11-21 16:25:35 -0800575 * @return whether a uid package-name pair is in mRunAnyRestrictedPackages.
Makoto Onuki9be01402017-11-10 13:22:26 -0800576 */
Andreas Gampea36dc622018-02-05 17:19:22 -0800577 @GuardedBy("mLock")
Makoto Onuki2206af32017-11-21 16:25:35 -0800578 boolean isRunAnyRestrictedLocked(int uid, @NonNull String packageName) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800579 return findForcedAppStandbyUidPackageIndexLocked(uid, packageName) >= 0;
580 }
581
Makoto Onuki2206af32017-11-21 16:25:35 -0800582 /**
583 * Add to / remove from {@link #mRunAnyRestrictedPackages}.
584 */
Andreas Gampea36dc622018-02-05 17:19:22 -0800585 @GuardedBy("mLock")
Makoto Onuki2206af32017-11-21 16:25:35 -0800586 boolean updateForcedAppStandbyUidPackageLocked(int uid, @NonNull String packageName,
Makoto Onuki9be01402017-11-10 13:22:26 -0800587 boolean restricted) {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800588 final int index = findForcedAppStandbyUidPackageIndexLocked(uid, packageName);
Makoto Onuki9be01402017-11-10 13:22:26 -0800589 final boolean wasRestricted = index >= 0;
590 if (wasRestricted == restricted) {
591 return false;
592 }
593 if (restricted) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800594 mRunAnyRestrictedPackages.add(Pair.create(uid, packageName));
Makoto Onuki9be01402017-11-10 13:22:26 -0800595 } else {
Makoto Onuki2206af32017-11-21 16:25:35 -0800596 mRunAnyRestrictedPackages.removeAt(index);
Makoto Onuki9be01402017-11-10 13:22:26 -0800597 }
598 return true;
599 }
600
Makoto Onukiadb50d82018-01-29 16:20:30 -0800601 private static boolean addUidToArray(SparseBooleanArray array, int uid) {
602 if (UserHandle.isCore(uid)) {
603 return false;
Makoto Onuki9be01402017-11-10 13:22:26 -0800604 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800605 if (array.get(uid)) {
606 return false;
607 }
608 array.put(uid, true);
609 return true;
Makoto Onuki9be01402017-11-10 13:22:26 -0800610 }
611
Makoto Onukiadb50d82018-01-29 16:20:30 -0800612 private static boolean removeUidFromArray(SparseBooleanArray array, int uid, boolean remove) {
613 if (UserHandle.isCore(uid)) {
614 return false;
Makoto Onuki9be01402017-11-10 13:22:26 -0800615 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800616 if (!array.get(uid)) {
617 return false;
618 }
619 if (remove) {
620 array.delete(uid);
621 } else {
622 array.put(uid, false);
623 }
624 return true;
Makoto Onuki9be01402017-11-10 13:22:26 -0800625 }
626
Makoto Onuki2206af32017-11-21 16:25:35 -0800627 private final class UidObserver extends IUidObserver.Stub {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800628 @Override
629 public void onUidStateChanged(int uid, int procState, long procStateSeq) {
Makoto Onuki4d298b52018-02-05 10:54:58 -0800630 mHandler.onUidStateChanged(uid, procState);
Makoto Onuki9be01402017-11-10 13:22:26 -0800631 }
632
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800633 @Override
634 public void onUidActive(int uid) {
Makoto Onuki4d298b52018-02-05 10:54:58 -0800635 mHandler.onUidActive(uid);
636 }
637
638 @Override
639 public void onUidGone(int uid, boolean disabled) {
640 mHandler.onUidGone(uid, disabled);
Makoto Onuki9be01402017-11-10 13:22:26 -0800641 }
642
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800643 @Override
644 public void onUidIdle(int uid, boolean disabled) {
Makoto Onuki4d298b52018-02-05 10:54:58 -0800645 mHandler.onUidIdle(uid, disabled);
Makoto Onuki9be01402017-11-10 13:22:26 -0800646 }
647
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800648 @Override
649 public void onUidCachedChanged(int uid, boolean cached) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800650 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800651 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800652
653 private final class AppOpsWatcher extends IAppOpsCallback.Stub {
654 @Override
655 public void opChanged(int op, int uid, String packageName) throws RemoteException {
Makoto Onuki2206af32017-11-21 16:25:35 -0800656 boolean restricted = false;
657 try {
658 restricted = mAppOpsService.checkOperation(TARGET_OP,
659 uid, packageName) != AppOpsManager.MODE_ALLOWED;
660 } catch (RemoteException e) {
661 // Shouldn't happen
662 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800663 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800664 if (updateForcedAppStandbyUidPackageLocked(uid, packageName, restricted)) {
665 mHandler.notifyRunAnyAppOpsChanged(uid, packageName);
666 }
667 }
668 }
669 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800670
Makoto Onuki2206af32017-11-21 16:25:35 -0800671 private final class MyReceiver extends BroadcastReceiver {
672 @Override
673 public void onReceive(Context context, Intent intent) {
674 if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
675 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
676 if (userId > 0) {
677 mHandler.doUserRemoved(userId);
Makoto Onuki9be01402017-11-10 13:22:26 -0800678 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800679 } else if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
680 synchronized (mLock) {
681 mIsPluggedIn = (intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0);
682 }
683 updateForceAllAppStandbyState();
Makoto Onuki9be01402017-11-10 13:22:26 -0800684 }
685 }
686 }
687
Makoto Onukieb898f12018-01-23 15:26:27 -0800688 final class StandbyTracker extends AppIdleStateChangeListener {
689 @Override
690 public void onAppIdleStateChanged(String packageName, int userId, boolean idle,
Amith Yamasani119be9a2018-02-18 22:23:00 -0800691 int bucket, int reason) {
Makoto Onukieb898f12018-01-23 15:26:27 -0800692 if (DEBUG) {
693 Slog.d(TAG,"onAppIdleStateChanged: " + packageName + " u" + userId
694 + (idle ? " idle" : " active") + " " + bucket);
695 }
696 final boolean changed;
697 if (bucket == UsageStatsManager.STANDBY_BUCKET_EXEMPTED) {
698 changed = mExemptedPackages.add(userId, packageName);
699 } else {
700 changed = mExemptedPackages.remove(userId, packageName);
701 }
702 if (changed) {
703 mHandler.notifyExemptChanged();
704 }
705 }
706
707 @Override
708 public void onParoleStateChanged(boolean isParoleOn) {
709 }
710 }
711
Makoto Onuki9be01402017-11-10 13:22:26 -0800712 private Listener[] cloneListeners() {
713 synchronized (mLock) {
714 return mListeners.toArray(new Listener[mListeners.size()]);
715 }
716 }
717
Makoto Onuki2206af32017-11-21 16:25:35 -0800718 private class MyHandler extends Handler {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800719 private static final int MSG_UID_ACTIVE_STATE_CHANGED = 0;
720 private static final int MSG_UID_FG_STATE_CHANGED = 1;
721 private static final int MSG_RUN_ANY_CHANGED = 3;
722 private static final int MSG_ALL_UNWHITELISTED = 4;
723 private static final int MSG_ALL_WHITELIST_CHANGED = 5;
724 private static final int MSG_TEMP_WHITELIST_CHANGED = 6;
725 private static final int MSG_FORCE_ALL_CHANGED = 7;
726 private static final int MSG_USER_REMOVED = 8;
727 private static final int MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED = 9;
728 private static final int MSG_EXEMPT_CHANGED = 10;
Makoto Onuki9be01402017-11-10 13:22:26 -0800729
Makoto Onuki4d298b52018-02-05 10:54:58 -0800730 private static final int MSG_ON_UID_STATE_CHANGED = 11;
731 private static final int MSG_ON_UID_ACTIVE = 12;
732 private static final int MSG_ON_UID_GONE = 13;
733 private static final int MSG_ON_UID_IDLE = 14;
734
Makoto Onuki2206af32017-11-21 16:25:35 -0800735 public MyHandler(Looper looper) {
736 super(looper);
Makoto Onuki9be01402017-11-10 13:22:26 -0800737 }
Makoto Onuki2206af32017-11-21 16:25:35 -0800738
Makoto Onukiadb50d82018-01-29 16:20:30 -0800739 public void notifyUidActiveStateChanged(int uid) {
740 obtainMessage(MSG_UID_ACTIVE_STATE_CHANGED, uid, 0).sendToTarget();
741 }
742
Makoto Onuki2206af32017-11-21 16:25:35 -0800743 public void notifyUidForegroundStateChanged(int uid) {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800744 obtainMessage(MSG_UID_FG_STATE_CHANGED, uid, 0).sendToTarget();
Makoto Onuki2206af32017-11-21 16:25:35 -0800745 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800746
Makoto Onuki2206af32017-11-21 16:25:35 -0800747 public void notifyRunAnyAppOpsChanged(int uid, @NonNull String packageName) {
748 obtainMessage(MSG_RUN_ANY_CHANGED, uid, 0, packageName).sendToTarget();
749 }
750
751 public void notifyAllUnwhitelisted() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800752 removeMessages(MSG_ALL_UNWHITELISTED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800753 obtainMessage(MSG_ALL_UNWHITELISTED).sendToTarget();
754 }
755
756 public void notifyAllWhitelistChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800757 removeMessages(MSG_ALL_WHITELIST_CHANGED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800758 obtainMessage(MSG_ALL_WHITELIST_CHANGED).sendToTarget();
759 }
760
761 public void notifyTempWhitelistChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800762 removeMessages(MSG_TEMP_WHITELIST_CHANGED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800763 obtainMessage(MSG_TEMP_WHITELIST_CHANGED).sendToTarget();
764 }
765
766 public void notifyForceAllAppsStandbyChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800767 removeMessages(MSG_FORCE_ALL_CHANGED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800768 obtainMessage(MSG_FORCE_ALL_CHANGED).sendToTarget();
769 }
770
Nancy Zheng525aaa12018-01-12 11:45:37 -0800771 public void notifyForcedAppStandbyFeatureFlagChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800772 removeMessages(MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED);
Nancy Zheng525aaa12018-01-12 11:45:37 -0800773 obtainMessage(MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED).sendToTarget();
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800774 }
775
Makoto Onukieb898f12018-01-23 15:26:27 -0800776 public void notifyExemptChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800777 removeMessages(MSG_EXEMPT_CHANGED);
Makoto Onukieb898f12018-01-23 15:26:27 -0800778 obtainMessage(MSG_EXEMPT_CHANGED).sendToTarget();
779 }
780
Makoto Onuki2206af32017-11-21 16:25:35 -0800781 public void doUserRemoved(int userId) {
782 obtainMessage(MSG_USER_REMOVED, userId, 0).sendToTarget();
783 }
784
Makoto Onuki4d298b52018-02-05 10:54:58 -0800785 public void onUidStateChanged(int uid, int procState) {
786 obtainMessage(MSG_ON_UID_STATE_CHANGED, uid, procState).sendToTarget();
787 }
788
789 public void onUidActive(int uid) {
790 obtainMessage(MSG_ON_UID_ACTIVE, uid, 0).sendToTarget();
791 }
792
793 public void onUidGone(int uid, boolean disabled) {
794 obtainMessage(MSG_ON_UID_GONE, uid, disabled ? 1 : 0).sendToTarget();
795 }
796
797 public void onUidIdle(int uid, boolean disabled) {
798 obtainMessage(MSG_ON_UID_IDLE, uid, disabled ? 1 : 0).sendToTarget();
799 }
800
Makoto Onuki2206af32017-11-21 16:25:35 -0800801 @Override
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800802 public void handleMessage(Message msg) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800803 switch (msg.what) {
804 case MSG_USER_REMOVED:
805 handleUserRemoved(msg.arg1);
806 return;
807 }
808
809 // Only notify the listeners when started.
810 synchronized (mLock) {
811 if (!mStarted) {
812 return;
813 }
814 }
Makoto Onukie4918212018-02-06 11:30:15 -0800815 final AppStateTracker sender = AppStateTracker.this;
Makoto Onuki2206af32017-11-21 16:25:35 -0800816
Makoto Onukieb898f12018-01-23 15:26:27 -0800817 long start = mStatLogger.getTime();
Makoto Onuki2206af32017-11-21 16:25:35 -0800818 switch (msg.what) {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800819 case MSG_UID_ACTIVE_STATE_CHANGED:
820 for (Listener l : cloneListeners()) {
821 l.onUidActiveStateChanged(sender, msg.arg1);
822 }
823 mStatLogger.logDurationStat(Stats.UID_ACTIVE_STATE_CHANGED, start);
824 return;
825
826 case MSG_UID_FG_STATE_CHANGED:
Makoto Onuki2206af32017-11-21 16:25:35 -0800827 for (Listener l : cloneListeners()) {
828 l.onUidForegroundStateChanged(sender, msg.arg1);
829 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800830 mStatLogger.logDurationStat(Stats.UID_FG_STATE_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800831 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800832
Makoto Onuki2206af32017-11-21 16:25:35 -0800833 case MSG_RUN_ANY_CHANGED:
834 for (Listener l : cloneListeners()) {
835 l.onRunAnyAppOpsChanged(sender, msg.arg1, (String) msg.obj);
836 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800837 mStatLogger.logDurationStat(Stats.RUN_ANY_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800838 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800839
Makoto Onuki2206af32017-11-21 16:25:35 -0800840 case MSG_ALL_UNWHITELISTED:
841 for (Listener l : cloneListeners()) {
842 l.onPowerSaveUnwhitelisted(sender);
843 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800844 mStatLogger.logDurationStat(Stats.ALL_UNWHITELISTED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800845 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800846
Makoto Onuki2206af32017-11-21 16:25:35 -0800847 case MSG_ALL_WHITELIST_CHANGED:
848 for (Listener l : cloneListeners()) {
849 l.onPowerSaveWhitelistedChanged(sender);
850 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800851 mStatLogger.logDurationStat(Stats.ALL_WHITELIST_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800852 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800853
Makoto Onuki2206af32017-11-21 16:25:35 -0800854 case MSG_TEMP_WHITELIST_CHANGED:
855 for (Listener l : cloneListeners()) {
856 l.onTempPowerSaveWhitelistChanged(sender);
857 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800858 mStatLogger.logDurationStat(Stats.TEMP_WHITELIST_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800859 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800860
861 case MSG_EXEMPT_CHANGED:
862 for (Listener l : cloneListeners()) {
863 l.onExemptChanged(sender);
864 }
865 mStatLogger.logDurationStat(Stats.EXEMPT_CHANGED, start);
866 return;
867
Makoto Onuki2206af32017-11-21 16:25:35 -0800868 case MSG_FORCE_ALL_CHANGED:
869 for (Listener l : cloneListeners()) {
870 l.onForceAllAppsStandbyChanged(sender);
871 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800872 mStatLogger.logDurationStat(Stats.FORCE_ALL_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800873 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800874
Nancy Zheng525aaa12018-01-12 11:45:37 -0800875 case MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED:
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800876 // Feature flag for forced app standby changed.
877 final boolean unblockAlarms;
878 synchronized (mLock) {
879 unblockAlarms = !mForcedAppStandbyEnabled && !mForceAllAppsStandby;
880 }
Suprabh Shuklac25447d2018-01-19 16:43:35 -0800881 for (Listener l : cloneListeners()) {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800882 l.updateAllJobs();
883 if (unblockAlarms) {
884 l.unblockAllUnrestrictedAlarms();
885 }
886 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800887 mStatLogger.logDurationStat(
888 Stats.FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED, start);
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800889 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800890
Makoto Onuki2206af32017-11-21 16:25:35 -0800891 case MSG_USER_REMOVED:
892 handleUserRemoved(msg.arg1);
893 return;
Makoto Onuki4d298b52018-02-05 10:54:58 -0800894
895 case MSG_ON_UID_STATE_CHANGED:
896 handleUidStateChanged(msg.arg1, msg.arg2);
897 return;
898 case MSG_ON_UID_ACTIVE:
899 handleUidActive(msg.arg1);
900 return;
901 case MSG_ON_UID_GONE:
902 handleUidGone(msg.arg1, msg.arg1 != 0);
903 return;
904 case MSG_ON_UID_IDLE:
905 handleUidIdle(msg.arg1, msg.arg1 != 0);
906 return;
907 }
908 }
909
910 public void handleUidStateChanged(int uid, int procState) {
911 synchronized (mLock) {
912 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
913 if (removeUidFromArray(mForegroundUids, uid, false)) {
914 mHandler.notifyUidForegroundStateChanged(uid);
915 }
916 } else {
917 if (addUidToArray(mForegroundUids, uid)) {
918 mHandler.notifyUidForegroundStateChanged(uid);
919 }
920 }
921 }
922 }
923
924 public void handleUidActive(int uid) {
925 synchronized (mLock) {
926 if (addUidToArray(mActiveUids, uid)) {
927 mHandler.notifyUidActiveStateChanged(uid);
928 }
929 }
930 }
931
932 public void handleUidGone(int uid, boolean disabled) {
933 removeUid(uid, true);
934 }
935
936 public void handleUidIdle(int uid, boolean disabled) {
937 // Just to avoid excessive memcpy, don't remove from the array in this case.
938 removeUid(uid, false);
939 }
940
941 private void removeUid(int uid, boolean remove) {
942 synchronized (mLock) {
943 if (removeUidFromArray(mActiveUids, uid, remove)) {
944 mHandler.notifyUidActiveStateChanged(uid);
945 }
946 if (removeUidFromArray(mForegroundUids, uid, remove)) {
947 mHandler.notifyUidForegroundStateChanged(uid);
948 }
Makoto Onuki2206af32017-11-21 16:25:35 -0800949 }
950 }
951 }
952
953 void handleUserRemoved(int removedUserId) {
954 synchronized (mLock) {
955 for (int i = mRunAnyRestrictedPackages.size() - 1; i >= 0; i--) {
956 final Pair<Integer, String> pair = mRunAnyRestrictedPackages.valueAt(i);
957 final int uid = pair.first;
958 final int userId = UserHandle.getUserId(uid);
959
960 if (userId == removedUserId) {
961 mRunAnyRestrictedPackages.removeAt(i);
962 }
963 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800964 cleanUpArrayForUser(mActiveUids, removedUserId);
965 cleanUpArrayForUser(mForegroundUids, removedUserId);
Makoto Onukieb898f12018-01-23 15:26:27 -0800966 mExemptedPackages.remove(removedUserId);
Makoto Onuki2206af32017-11-21 16:25:35 -0800967 }
968 }
969
Makoto Onukiadb50d82018-01-29 16:20:30 -0800970 private void cleanUpArrayForUser(SparseBooleanArray array, int removedUserId) {
971 for (int i = array.size() - 1; i >= 0; i--) {
972 final int uid = array.keyAt(i);
973 final int userId = UserHandle.getUserId(uid);
974
975 if (userId == removedUserId) {
976 array.removeAt(i);
977 }
978 }
979 }
980
Makoto Onuki2206af32017-11-21 16:25:35 -0800981 /**
982 * Called by device idle controller to update the power save whitelists.
983 */
984 public void setPowerSaveWhitelistAppIds(
985 int[] powerSaveWhitelistAllAppIdArray, int[] tempWhitelistAppIdArray) {
986 synchronized (mLock) {
987 final int[] previousWhitelist = mPowerWhitelistedAllAppIds;
988 final int[] previousTempWhitelist = mTempWhitelistedAppIds;
989
990 mPowerWhitelistedAllAppIds = powerSaveWhitelistAllAppIdArray;
991 mTempWhitelistedAppIds = tempWhitelistAppIdArray;
992
993 if (isAnyAppIdUnwhitelisted(previousWhitelist, mPowerWhitelistedAllAppIds)) {
994 mHandler.notifyAllUnwhitelisted();
995 } else if (!Arrays.equals(previousWhitelist, mPowerWhitelistedAllAppIds)) {
996 mHandler.notifyAllWhitelistChanged();
997 }
998
999 if (!Arrays.equals(previousTempWhitelist, mTempWhitelistedAppIds)) {
1000 mHandler.notifyTempWhitelistChanged();
1001 }
1002
1003 }
1004 }
1005
1006 /**
1007 * @retunr true if a sorted app-id array {@code prevArray} has at least one element
1008 * that's not in a sorted app-id array {@code newArray}.
1009 */
1010 @VisibleForTesting
1011 static boolean isAnyAppIdUnwhitelisted(int[] prevArray, int[] newArray) {
1012 int i1 = 0;
1013 int i2 = 0;
1014 boolean prevFinished;
1015 boolean newFinished;
1016
1017 for (;;) {
1018 prevFinished = i1 >= prevArray.length;
1019 newFinished = i2 >= newArray.length;
1020 if (prevFinished || newFinished) {
1021 break;
1022 }
1023 int a1 = prevArray[i1];
1024 int a2 = newArray[i2];
1025
1026 if (a1 == a2) {
1027 i1++;
1028 i2++;
1029 continue;
1030 }
1031 if (a1 < a2) {
1032 // prevArray has an element that's not in a2.
1033 return true;
1034 }
1035 i2++;
1036 }
1037 if (prevFinished) {
1038 return false;
1039 }
1040 return newFinished;
Makoto Onuki9be01402017-11-10 13:22:26 -08001041 }
1042
1043 // Public interface.
1044
1045 /**
1046 * Register a new listener.
1047 */
1048 public void addListener(@NonNull Listener listener) {
1049 synchronized (mLock) {
1050 mListeners.add(listener);
1051 }
1052 }
1053
1054 /**
Makoto Onuki2206af32017-11-21 16:25:35 -08001055 * @return whether alarms should be restricted for a UID package-name.
Makoto Onuki9be01402017-11-10 13:22:26 -08001056 */
Suprabh Shuklac25447d2018-01-19 16:43:35 -08001057 public boolean areAlarmsRestricted(int uid, @NonNull String packageName,
1058 boolean allowWhileIdle) {
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001059 return isRestricted(uid, packageName, /*useTempWhitelistToo=*/ false,
Suprabh Shuklac25447d2018-01-19 16:43:35 -08001060 /* exemptOnBatterySaver =*/ allowWhileIdle);
Makoto Onuki2206af32017-11-21 16:25:35 -08001061 }
1062
1063 /**
1064 * @return whether jobs should be restricted for a UID package-name.
1065 */
Makoto Onuki15407842018-01-19 14:23:11 -08001066 public boolean areJobsRestricted(int uid, @NonNull String packageName,
1067 boolean hasForegroundExemption) {
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001068 return isRestricted(uid, packageName, /*useTempWhitelistToo=*/ true,
Makoto Onuki15407842018-01-19 14:23:11 -08001069 hasForegroundExemption);
Makoto Onuki2206af32017-11-21 16:25:35 -08001070 }
1071
1072 /**
Christopher Tatec7933ac2018-03-12 17:57:09 -07001073 * @return whether foreground services should be suppressed in the background
1074 * due to forced app standby for the given app
1075 */
1076 public boolean areForegroundServicesRestricted(int uid, @NonNull String packageName) {
1077 synchronized (mLock) {
1078 return isRunAnyRestrictedLocked(uid, packageName);
1079 }
1080 }
1081
1082 /**
Makoto Onuki2206af32017-11-21 16:25:35 -08001083 * @return whether force-app-standby is effective for a UID package-name.
1084 */
1085 private boolean isRestricted(int uid, @NonNull String packageName,
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001086 boolean useTempWhitelistToo, boolean exemptOnBatterySaver) {
Makoto Onukiadb50d82018-01-29 16:20:30 -08001087 if (isUidActive(uid)) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001088 return false;
1089 }
1090 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001091 // Whitelisted?
1092 final int appId = UserHandle.getAppId(uid);
1093 if (ArrayUtils.contains(mPowerWhitelistedAllAppIds, appId)) {
1094 return false;
1095 }
1096 if (useTempWhitelistToo &&
1097 ArrayUtils.contains(mTempWhitelistedAppIds, appId)) {
1098 return false;
1099 }
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001100 if (mForcedAppStandbyEnabled && isRunAnyRestrictedLocked(uid, packageName)) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001101 return true;
1102 }
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001103 if (exemptOnBatterySaver) {
1104 return false;
1105 }
Makoto Onukieb898f12018-01-23 15:26:27 -08001106 final int userId = UserHandle.getUserId(uid);
1107 if (mExemptedPackages.contains(userId, packageName)) {
1108 return false;
1109 }
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001110 return mForceAllAppsStandby;
Makoto Onuki9be01402017-11-10 13:22:26 -08001111 }
1112 }
1113
Makoto Onuki2206af32017-11-21 16:25:35 -08001114 /**
Makoto Onukie4918212018-02-06 11:30:15 -08001115 * @return whether a UID is in active or not *based on cached information.*
Makoto Onukiadb50d82018-01-29 16:20:30 -08001116 *
1117 * Note this information is based on the UID proc state callback, meaning it's updated
1118 * asynchronously and may subtly be stale. If the fresh data is needed, use
Makoto Onukie4918212018-02-06 11:30:15 -08001119 * {@link #isUidActiveSynced} instead.
Makoto Onukiadb50d82018-01-29 16:20:30 -08001120 */
1121 public boolean isUidActive(int uid) {
1122 if (UserHandle.isCore(uid)) {
1123 return true;
1124 }
1125 synchronized (mLock) {
1126 return mActiveUids.get(uid);
1127 }
1128 }
1129
1130 /**
Makoto Onukie4918212018-02-06 11:30:15 -08001131 * @return whether a UID is in active or not *right now.*
1132 *
1133 * This gives the fresh information, but may access the activity manager so is slower.
1134 */
1135 public boolean isUidActiveSynced(int uid) {
1136 if (isUidActive(uid)) { // Use the cached one first.
1137 return true;
1138 }
1139 final long start = mStatLogger.getTime();
1140
1141 final boolean ret = mActivityManagerInternal.isUidActive(uid);
1142 mStatLogger.logDurationStat(Stats.IS_UID_ACTIVE_RAW, start);
1143
1144 return ret;
1145 }
1146
1147 /**
Makoto Onuki2206af32017-11-21 16:25:35 -08001148 * @return whether a UID is in the foreground or not.
1149 *
Makoto Onuki15407842018-01-19 14:23:11 -08001150 * Note this information is based on the UID proc state callback, meaning it's updated
1151 * asynchronously and may subtly be stale. If the fresh data is needed, use
1152 * {@link ActivityManagerInternal#getUidProcessState} instead.
Makoto Onuki2206af32017-11-21 16:25:35 -08001153 */
Makoto Onukiadb50d82018-01-29 16:20:30 -08001154 public boolean isUidInForeground(int uid) {
Makoto Onuki9cc471c2018-01-23 12:33:56 -08001155 if (UserHandle.isCore(uid)) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001156 return true;
1157 }
1158 synchronized (mLock) {
1159 return mForegroundUids.get(uid);
1160 }
1161 }
1162
Makoto Onuki2206af32017-11-21 16:25:35 -08001163 /**
1164 * @return whether force all apps standby is enabled or not.
1165 *
Makoto Onuki2206af32017-11-21 16:25:35 -08001166 */
1167 boolean isForceAllAppsStandbyEnabled() {
Makoto Onuki9be01402017-11-10 13:22:26 -08001168 synchronized (mLock) {
1169 return mForceAllAppsStandby;
1170 }
1171 }
1172
Makoto Onuki2206af32017-11-21 16:25:35 -08001173 /**
1174 * @return whether a UID/package has {@code OP_RUN_ANY_IN_BACKGROUND} allowed or not.
1175 *
1176 * Note clients normally shouldn't need to access it. It's only for dumpsys.
1177 */
Makoto Onuki9be01402017-11-10 13:22:26 -08001178 public boolean isRunAnyInBackgroundAppOpsAllowed(int uid, @NonNull String packageName) {
1179 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001180 return !isRunAnyRestrictedLocked(uid, packageName);
Makoto Onuki9be01402017-11-10 13:22:26 -08001181 }
1182 }
1183
Makoto Onuki2206af32017-11-21 16:25:35 -08001184 /**
1185 * @return whether a UID is in the user / system defined power-save whitelist or not.
1186 *
1187 * Note clients normally shouldn't need to access it. It's only for dumpsys.
1188 */
1189 public boolean isUidPowerSaveWhitelisted(int uid) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001190 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001191 return ArrayUtils.contains(mPowerWhitelistedAllAppIds, UserHandle.getAppId(uid));
Makoto Onuki9be01402017-11-10 13:22:26 -08001192 }
1193 }
1194
Makoto Onuki2206af32017-11-21 16:25:35 -08001195 /**
1196 * @return whether a UID is in the temp power-save whitelist or not.
1197 *
1198 * Note clients normally shouldn't need to access it. It's only for dumpsys.
1199 */
1200 public boolean isUidTempPowerSaveWhitelisted(int uid) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001201 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001202 return ArrayUtils.contains(mTempWhitelistedAppIds, UserHandle.getAppId(uid));
1203 }
1204 }
1205
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001206 @Deprecated
1207 public void dump(PrintWriter pw, String prefix) {
1208 dump(new IndentingPrintWriter(pw, " ").setIndent(prefix));
1209 }
1210
1211 public void dump(IndentingPrintWriter pw) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001212 synchronized (mLock) {
Suprabh Shukla4deb8522018-01-08 16:27:10 -08001213 pw.println("Forced App Standby Feature enabled: " + mForcedAppStandbyEnabled);
1214
Makoto Onuki2206af32017-11-21 16:25:35 -08001215 pw.print("Force all apps standby: ");
1216 pw.println(isForceAllAppsStandbyEnabled());
1217
Nancy Zheng525aaa12018-01-12 11:45:37 -08001218 pw.print("Small Battery Device: ");
1219 pw.println(isSmallBatteryDevice());
1220
Nancy Zheng525aaa12018-01-12 11:45:37 -08001221 pw.print("Force all apps standby for small battery device: ");
1222 pw.println(mForceAllAppStandbyForSmallBattery);
1223
Nancy Zheng525aaa12018-01-12 11:45:37 -08001224 pw.print("Plugged In: ");
1225 pw.println(mIsPluggedIn);
1226
Makoto Onukiadb50d82018-01-29 16:20:30 -08001227 pw.print("Active uids: ");
1228 dumpUids(pw, mActiveUids);
Makoto Onuki2206af32017-11-21 16:25:35 -08001229
Makoto Onukiadb50d82018-01-29 16:20:30 -08001230 pw.print("Foreground uids: ");
1231 dumpUids(pw, mForegroundUids);
Makoto Onuki2206af32017-11-21 16:25:35 -08001232
Makoto Onuki2206af32017-11-21 16:25:35 -08001233 pw.print("Whitelist appids: ");
1234 pw.println(Arrays.toString(mPowerWhitelistedAllAppIds));
1235
Makoto Onuki2206af32017-11-21 16:25:35 -08001236 pw.print("Temp whitelist appids: ");
1237 pw.println(Arrays.toString(mTempWhitelistedAppIds));
1238
Makoto Onukieb898f12018-01-23 15:26:27 -08001239 pw.println("Exempted packages:");
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001240 pw.increaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001241 for (int i = 0; i < mExemptedPackages.size(); i++) {
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001242 pw.print("User ");
Makoto Onukieb898f12018-01-23 15:26:27 -08001243 pw.print(mExemptedPackages.keyAt(i));
1244 pw.println();
1245
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001246 pw.increaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001247 for (int j = 0; j < mExemptedPackages.sizeAt(i); j++) {
Makoto Onukieb898f12018-01-23 15:26:27 -08001248 pw.print(mExemptedPackages.valueAt(i, j));
1249 pw.println();
1250 }
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001251 pw.decreaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001252 }
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001253 pw.decreaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001254 pw.println();
1255
Makoto Onuki2206af32017-11-21 16:25:35 -08001256 pw.println("Restricted packages:");
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001257 pw.increaseIndent();
Makoto Onuki2206af32017-11-21 16:25:35 -08001258 for (Pair<Integer, String> uidAndPackage : mRunAnyRestrictedPackages) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001259 pw.print(UserHandle.formatUid(uidAndPackage.first));
1260 pw.print(" ");
1261 pw.print(uidAndPackage.second);
1262 pw.println();
1263 }
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001264 pw.decreaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001265
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001266 mStatLogger.dump(pw);
Makoto Onuki2206af32017-11-21 16:25:35 -08001267 }
1268 }
1269
Makoto Onukiadb50d82018-01-29 16:20:30 -08001270 private void dumpUids(PrintWriter pw, SparseBooleanArray array) {
1271 pw.print("[");
1272
1273 String sep = "";
1274 for (int i = 0; i < array.size(); i++) {
1275 if (array.valueAt(i)) {
1276 pw.print(sep);
1277 pw.print(UserHandle.formatUid(array.keyAt(i)));
1278 sep = " ";
1279 }
1280 }
1281 pw.println("]");
1282 }
1283
Makoto Onuki2206af32017-11-21 16:25:35 -08001284 public void dumpProto(ProtoOutputStream proto, long fieldId) {
1285 synchronized (mLock) {
1286 final long token = proto.start(fieldId);
1287
1288 proto.write(ForceAppStandbyTrackerProto.FORCE_ALL_APPS_STANDBY, mForceAllAppsStandby);
Nancy Zheng525aaa12018-01-12 11:45:37 -08001289 proto.write(ForceAppStandbyTrackerProto.IS_SMALL_BATTERY_DEVICE,
1290 isSmallBatteryDevice());
1291 proto.write(ForceAppStandbyTrackerProto.FORCE_ALL_APPS_STANDBY_FOR_SMALL_BATTERY,
1292 mForceAllAppStandbyForSmallBattery);
Makoto Onukieb898f12018-01-23 15:26:27 -08001293 proto.write(ForceAppStandbyTrackerProto.IS_PLUGGED_IN, mIsPluggedIn);
Makoto Onuki2206af32017-11-21 16:25:35 -08001294
Makoto Onukiadb50d82018-01-29 16:20:30 -08001295 for (int i = 0; i < mActiveUids.size(); i++) {
1296 if (mActiveUids.valueAt(i)) {
1297 proto.write(ForceAppStandbyTrackerProto.ACTIVE_UIDS,
1298 mActiveUids.keyAt(i));
1299 }
1300 }
1301
Makoto Onuki2206af32017-11-21 16:25:35 -08001302 for (int i = 0; i < mForegroundUids.size(); i++) {
1303 if (mForegroundUids.valueAt(i)) {
1304 proto.write(ForceAppStandbyTrackerProto.FOREGROUND_UIDS,
1305 mForegroundUids.keyAt(i));
1306 }
1307 }
1308
1309 for (int appId : mPowerWhitelistedAllAppIds) {
1310 proto.write(ForceAppStandbyTrackerProto.POWER_SAVE_WHITELIST_APP_IDS, appId);
1311 }
1312
1313 for (int appId : mTempWhitelistedAppIds) {
1314 proto.write(ForceAppStandbyTrackerProto.TEMP_POWER_SAVE_WHITELIST_APP_IDS, appId);
1315 }
1316
Makoto Onukieb898f12018-01-23 15:26:27 -08001317 for (int i = 0; i < mExemptedPackages.size(); i++) {
1318 for (int j = 0; j < mExemptedPackages.sizeAt(i); j++) {
1319 final long token2 = proto.start(
1320 ForceAppStandbyTrackerProto.EXEMPTED_PACKAGES);
1321
1322 proto.write(ExemptedPackage.USER_ID, mExemptedPackages.keyAt(i));
1323 proto.write(ExemptedPackage.PACKAGE_NAME, mExemptedPackages.valueAt(i, j));
1324
1325 proto.end(token2);
1326 }
1327 }
1328
Makoto Onuki2206af32017-11-21 16:25:35 -08001329 for (Pair<Integer, String> uidAndPackage : mRunAnyRestrictedPackages) {
1330 final long token2 = proto.start(
1331 ForceAppStandbyTrackerProto.RUN_ANY_IN_BACKGROUND_RESTRICTED_PACKAGES);
1332 proto.write(RunAnyInBackgroundRestrictedPackages.UID, uidAndPackage.first);
1333 proto.write(RunAnyInBackgroundRestrictedPackages.PACKAGE_NAME,
1334 uidAndPackage.second);
1335 proto.end(token2);
1336 }
Makoto Onukieb898f12018-01-23 15:26:27 -08001337
1338 mStatLogger.dumpProto(proto, ForceAppStandbyTrackerProto.STATS);
1339
Makoto Onuki2206af32017-11-21 16:25:35 -08001340 proto.end(token);
Makoto Onuki9be01402017-11-10 13:22:26 -08001341 }
1342 }
1343}