blob: 23c57797c1f561a0d72ab135fb8e7c7a88ee3e95 [file] [log] [blame]
Makoto Onuki9be01402017-11-10 13:22:26 -08001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.server;
17
18import android.annotation.NonNull;
Makoto Onuki9be01402017-11-10 13:22:26 -080019import android.app.ActivityManager;
Makoto Onuki15407842018-01-19 14:23:11 -080020import android.app.ActivityManagerInternal;
Makoto Onuki9be01402017-11-10 13:22:26 -080021import android.app.AppOpsManager;
22import android.app.AppOpsManager.PackageOps;
Makoto Onuki2206af32017-11-21 16:25:35 -080023import android.app.IActivityManager;
Makoto Onuki9be01402017-11-10 13:22:26 -080024import android.app.IUidObserver;
Makoto Onukieb898f12018-01-23 15:26:27 -080025import android.app.usage.UsageStatsManager;
26import android.app.usage.UsageStatsManagerInternal;
27import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener;
Makoto Onuki2206af32017-11-21 16:25:35 -080028import android.content.BroadcastReceiver;
Makoto Onuki9be01402017-11-10 13:22:26 -080029import android.content.Context;
Makoto Onuki2206af32017-11-21 16:25:35 -080030import android.content.Intent;
31import android.content.IntentFilter;
Suprabh Shukla4deb8522018-01-08 16:27:10 -080032import android.database.ContentObserver;
Nancy Zheng525aaa12018-01-12 11:45:37 -080033import android.net.Uri;
34import android.os.BatteryManager;
Makoto Onuki9be01402017-11-10 13:22:26 -080035import android.os.Handler;
Makoto Onuki2206af32017-11-21 16:25:35 -080036import android.os.Looper;
37import android.os.Message;
Makoto Onuki9be01402017-11-10 13:22:26 -080038import android.os.PowerManager.ServiceType;
39import android.os.PowerManagerInternal;
40import android.os.RemoteException;
41import android.os.ServiceManager;
42import android.os.UserHandle;
Suprabh Shukla4deb8522018-01-08 16:27:10 -080043import android.provider.Settings;
Makoto Onuki9be01402017-11-10 13:22:26 -080044import android.util.ArraySet;
45import android.util.Pair;
Suprabh Shukla4deb8522018-01-08 16:27:10 -080046import android.util.Slog;
Makoto Onuki9be01402017-11-10 13:22:26 -080047import android.util.SparseBooleanArray;
Makoto Onukieb898f12018-01-23 15:26:27 -080048import android.util.SparseSetArray;
Makoto Onuki2206af32017-11-21 16:25:35 -080049import android.util.proto.ProtoOutputStream;
Makoto Onuki9be01402017-11-10 13:22:26 -080050
51import com.android.internal.annotations.GuardedBy;
Makoto Onuki2206af32017-11-21 16:25:35 -080052import com.android.internal.annotations.VisibleForTesting;
Makoto Onuki9be01402017-11-10 13:22:26 -080053import com.android.internal.app.IAppOpsCallback;
54import com.android.internal.app.IAppOpsService;
Makoto Onuki2206af32017-11-21 16:25:35 -080055import com.android.internal.util.ArrayUtils;
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -070056import com.android.internal.util.IndentingPrintWriter;
Makoto Onuki9be01402017-11-10 13:22:26 -080057import com.android.internal.util.Preconditions;
Makoto Onuki49392d32018-04-11 13:51:02 -070058import com.android.internal.util.StatLogger;
Makoto Onukieb898f12018-01-23 15:26:27 -080059import com.android.server.ForceAppStandbyTrackerProto.ExemptedPackage;
Makoto Onuki2206af32017-11-21 16:25:35 -080060import com.android.server.ForceAppStandbyTrackerProto.RunAnyInBackgroundRestrictedPackages;
Makoto Onuki9be01402017-11-10 13:22:26 -080061
Makoto Onuki2206af32017-11-21 16:25:35 -080062import java.io.PrintWriter;
63import java.util.Arrays;
Makoto Onuki9be01402017-11-10 13:22:26 -080064import java.util.List;
65
66/**
Makoto Onuki2206af32017-11-21 16:25:35 -080067 * Class to keep track of the information related to "force app standby", which includes:
68 * - OP_RUN_ANY_IN_BACKGROUND for each package
Makoto Onukiadb50d82018-01-29 16:20:30 -080069 * - UID foreground/active state
Makoto Onuki2206af32017-11-21 16:25:35 -080070 * - User+system power save whitelist
71 * - Temporary power save whitelist
72 * - Global "force all apps standby" mode enforced by battery saver.
Makoto Onuki9be01402017-11-10 13:22:26 -080073 *
Makoto Onuki2206af32017-11-21 16:25:35 -080074 * Test:
Makoto Onukie4918212018-02-06 11:30:15 -080075 atest $ANDROID_BUILD_TOP/frameworks/base/services/tests/servicestests/src/com/android/server/AppStateTrackerTest.java
Makoto Onuki9be01402017-11-10 13:22:26 -080076 */
Makoto Onukie4918212018-02-06 11:30:15 -080077public class AppStateTracker {
Makoto Onukic871c872018-03-19 09:39:56 -070078 private static final String TAG = "AppStateTracker";
79 private static final boolean DEBUG = false;
Makoto Onuki9be01402017-11-10 13:22:26 -080080
81 private final Object mLock = new Object();
82 private final Context mContext;
83
Makoto Onuki2206af32017-11-21 16:25:35 -080084 @VisibleForTesting
85 static final int TARGET_OP = AppOpsManager.OP_RUN_ANY_IN_BACKGROUND;
86
87 IActivityManager mIActivityManager;
Makoto Onukie4918212018-02-06 11:30:15 -080088 ActivityManagerInternal mActivityManagerInternal;
Makoto Onuki9be01402017-11-10 13:22:26 -080089 AppOpsManager mAppOpsManager;
90 IAppOpsService mAppOpsService;
91 PowerManagerInternal mPowerManagerInternal;
Makoto Onukieb898f12018-01-23 15:26:27 -080092 StandbyTracker mStandbyTracker;
93 UsageStatsManagerInternal mUsageStatsManagerInternal;
Makoto Onuki9be01402017-11-10 13:22:26 -080094
Makoto Onuki2206af32017-11-21 16:25:35 -080095 private final MyHandler mHandler;
Makoto Onuki9be01402017-11-10 13:22:26 -080096
Nancy Zheng525aaa12018-01-12 11:45:37 -080097 @VisibleForTesting
98 FeatureFlagsObserver mFlagsObserver;
99
Makoto Onuki9be01402017-11-10 13:22:26 -0800100 /**
101 * Pair of (uid (not user-id), packageName) with OP_RUN_ANY_IN_BACKGROUND *not* allowed.
102 */
103 @GuardedBy("mLock")
Makoto Onuki2206af32017-11-21 16:25:35 -0800104 final ArraySet<Pair<Integer, String>> mRunAnyRestrictedPackages = new ArraySet<>();
Makoto Onuki9be01402017-11-10 13:22:26 -0800105
Makoto Onukiadb50d82018-01-29 16:20:30 -0800106 /** UIDs that are active. */
107 @GuardedBy("mLock")
108 final SparseBooleanArray mActiveUids = new SparseBooleanArray();
109
110 /** UIDs that are in the foreground. */
Makoto Onuki9be01402017-11-10 13:22:26 -0800111 @GuardedBy("mLock")
112 final SparseBooleanArray mForegroundUids = new SparseBooleanArray();
113
Makoto Onuki71755c92018-01-16 14:15:44 -0800114 /**
115 * System except-idle + user whitelist in the device idle controller.
116 */
Makoto Onuki9be01402017-11-10 13:22:26 -0800117 @GuardedBy("mLock")
Makoto Onuki2206af32017-11-21 16:25:35 -0800118 private int[] mPowerWhitelistedAllAppIds = new int[0];
119
120 @GuardedBy("mLock")
121 private int[] mTempWhitelistedAppIds = mPowerWhitelistedAllAppIds;
122
Makoto Onukieb898f12018-01-23 15:26:27 -0800123 /**
124 * Per-user packages that are in the EXEMPT bucket.
125 */
126 @GuardedBy("mLock")
127 private final SparseSetArray<String> mExemptedPackages = new SparseSetArray<>();
128
Makoto Onuki2206af32017-11-21 16:25:35 -0800129 @GuardedBy("mLock")
Makoto Onuki9be01402017-11-10 13:22:26 -0800130 final ArraySet<Listener> mListeners = new ArraySet<>();
131
132 @GuardedBy("mLock")
133 boolean mStarted;
134
Nancy Zheng525aaa12018-01-12 11:45:37 -0800135 /**
136 * Only used for small battery use-case.
137 */
Makoto Onuki9be01402017-11-10 13:22:26 -0800138 @GuardedBy("mLock")
Nancy Zheng525aaa12018-01-12 11:45:37 -0800139 boolean mIsPluggedIn;
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800140
141 @GuardedBy("mLock")
Nancy Zheng525aaa12018-01-12 11:45:37 -0800142 boolean mBatterySaverEnabled;
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800143
Nancy Zheng525aaa12018-01-12 11:45:37 -0800144 /**
145 * True if the forced app standby is currently enabled
146 */
147 @GuardedBy("mLock")
148 boolean mForceAllAppsStandby;
149
150 /**
151 * True if the forced app standby for small battery devices feature is enabled in settings
152 */
153 @GuardedBy("mLock")
154 boolean mForceAllAppStandbyForSmallBattery;
155
156 /**
157 * True if the forced app standby feature is enabled in settings
158 */
159 @GuardedBy("mLock")
160 boolean mForcedAppStandbyEnabled;
161
Makoto Onukieb898f12018-01-23 15:26:27 -0800162 interface Stats {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800163 int UID_FG_STATE_CHANGED = 0;
164 int UID_ACTIVE_STATE_CHANGED = 1;
165 int RUN_ANY_CHANGED = 2;
166 int ALL_UNWHITELISTED = 3;
167 int ALL_WHITELIST_CHANGED = 4;
168 int TEMP_WHITELIST_CHANGED = 5;
169 int EXEMPT_CHANGED = 6;
170 int FORCE_ALL_CHANGED = 7;
171 int FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED = 8;
Makoto Onukie4918212018-02-06 11:30:15 -0800172
173 int IS_UID_ACTIVE_CACHED = 9;
174 int IS_UID_ACTIVE_RAW = 10;
Makoto Onukieb898f12018-01-23 15:26:27 -0800175 }
176
177 private final StatLogger mStatLogger = new StatLogger(new String[] {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800178 "UID_FG_STATE_CHANGED",
179 "UID_ACTIVE_STATE_CHANGED",
Makoto Onukieb898f12018-01-23 15:26:27 -0800180 "RUN_ANY_CHANGED",
181 "ALL_UNWHITELISTED",
182 "ALL_WHITELIST_CHANGED",
183 "TEMP_WHITELIST_CHANGED",
184 "EXEMPT_CHANGED",
185 "FORCE_ALL_CHANGED",
186 "FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED",
Makoto Onukie4918212018-02-06 11:30:15 -0800187
188 "IS_UID_ACTIVE_CACHED",
189 "IS_UID_ACTIVE_RAW",
Makoto Onukieb898f12018-01-23 15:26:27 -0800190 });
191
Nancy Zheng525aaa12018-01-12 11:45:37 -0800192 @VisibleForTesting
193 class FeatureFlagsObserver extends ContentObserver {
194 FeatureFlagsObserver() {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800195 super(null);
196 }
197
198 void register() {
199 mContext.getContentResolver().registerContentObserver(
200 Settings.Global.getUriFor(Settings.Global.FORCED_APP_STANDBY_ENABLED),
201 false, this);
Nancy Zheng525aaa12018-01-12 11:45:37 -0800202
203 mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor(
204 Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED), false, this);
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800205 }
206
207 boolean isForcedAppStandbyEnabled() {
Makoto Onukieb898f12018-01-23 15:26:27 -0800208 return injectGetGlobalSettingInt(Settings.Global.FORCED_APP_STANDBY_ENABLED, 1) == 1;
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800209 }
210
Nancy Zheng525aaa12018-01-12 11:45:37 -0800211 boolean isForcedAppStandbyForSmallBatteryEnabled() {
Makoto Onukieb898f12018-01-23 15:26:27 -0800212 return injectGetGlobalSettingInt(
Nancy Zheng525aaa12018-01-12 11:45:37 -0800213 Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED, 0) == 1;
214 }
215
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800216 @Override
Nancy Zheng525aaa12018-01-12 11:45:37 -0800217 public void onChange(boolean selfChange, Uri uri) {
218 if (Settings.Global.getUriFor(Settings.Global.FORCED_APP_STANDBY_ENABLED).equals(uri)) {
219 final boolean enabled = isForcedAppStandbyEnabled();
220 synchronized (mLock) {
221 if (mForcedAppStandbyEnabled == enabled) {
222 return;
223 }
224 mForcedAppStandbyEnabled = enabled;
225 if (DEBUG) {
226 Slog.d(TAG,"Forced app standby feature flag changed: "
227 + mForcedAppStandbyEnabled);
228 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800229 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800230 mHandler.notifyForcedAppStandbyFeatureFlagChanged();
231 } else if (Settings.Global.getUriFor(
232 Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED).equals(uri)) {
233 final boolean enabled = isForcedAppStandbyForSmallBatteryEnabled();
234 synchronized (mLock) {
235 if (mForceAllAppStandbyForSmallBattery == enabled) {
236 return;
237 }
238 mForceAllAppStandbyForSmallBattery = enabled;
239 if (DEBUG) {
240 Slog.d(TAG, "Forced app standby for small battery feature flag changed: "
241 + mForceAllAppStandbyForSmallBattery);
242 }
243 updateForceAllAppStandbyState();
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800244 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800245 } else {
246 Slog.w(TAG, "Unexpected feature flag uri encountered: " + uri);
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800247 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800248 }
249 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800250
251 public static abstract class Listener {
Makoto Onuki2206af32017-11-21 16:25:35 -0800252 /**
253 * This is called when the OP_RUN_ANY_IN_BACKGROUND appops changed for a package.
254 */
Makoto Onukie4918212018-02-06 11:30:15 -0800255 private void onRunAnyAppOpsChanged(AppStateTracker sender,
Makoto Onuki2206af32017-11-21 16:25:35 -0800256 int uid, @NonNull String packageName) {
Christopher Tate20afddd2018-02-28 15:19:19 -0800257 updateJobsForUidPackage(uid, packageName, sender.isUidActive(uid));
Makoto Onuki2206af32017-11-21 16:25:35 -0800258
Suprabh Shuklac25447d2018-01-19 16:43:35 -0800259 if (!sender.areAlarmsRestricted(uid, packageName, /*allowWhileIdle=*/ false)) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800260 unblockAlarmsForUidPackage(uid, packageName);
Suprabh Shuklac25447d2018-01-19 16:43:35 -0800261 } else if (!sender.areAlarmsRestricted(uid, packageName, /*allowWhileIdle=*/ true)){
262 // we need to deliver the allow-while-idle alarms for this uid, package
263 unblockAllUnrestrictedAlarms();
Makoto Onuki2206af32017-11-21 16:25:35 -0800264 }
Christopher Tatec7933ac2018-03-12 17:57:09 -0700265
266 if (!sender.isRunAnyInBackgroundAppOpsAllowed(uid, packageName)) {
267 Slog.v(TAG, "Package " + packageName + "/" + uid
268 + " toggled into fg service restriction");
269 stopForegroundServicesForUidPackage(uid, packageName);
270 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800271 }
272
Makoto Onuki2206af32017-11-21 16:25:35 -0800273 /**
274 * This is called when the foreground state changed for a UID.
275 */
Makoto Onukie4918212018-02-06 11:30:15 -0800276 private void onUidForegroundStateChanged(AppStateTracker sender, int uid) {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800277 onUidForeground(uid, sender.isUidInForeground(uid));
278 }
279
280 /**
281 * This is called when the active/idle state changed for a UID.
282 */
Makoto Onukie4918212018-02-06 11:30:15 -0800283 private void onUidActiveStateChanged(AppStateTracker sender, int uid) {
Christopher Tate20afddd2018-02-28 15:19:19 -0800284 final boolean isActive = sender.isUidActive(uid);
Makoto Onuki2206af32017-11-21 16:25:35 -0800285
Christopher Tate20afddd2018-02-28 15:19:19 -0800286 updateJobsForUid(uid, isActive);
287
288 if (isActive) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800289 unblockAlarmsForUid(uid);
290 }
291 }
292
293 /**
294 * This is called when an app-id(s) is removed from the power save whitelist.
295 */
Makoto Onukie4918212018-02-06 11:30:15 -0800296 private void onPowerSaveUnwhitelisted(AppStateTracker sender) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800297 updateAllJobs();
298 unblockAllUnrestrictedAlarms();
299 }
300
301 /**
302 * This is called when the power save whitelist changes, excluding the
303 * {@link #onPowerSaveUnwhitelisted} case.
304 */
Makoto Onukie4918212018-02-06 11:30:15 -0800305 private void onPowerSaveWhitelistedChanged(AppStateTracker sender) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800306 updateAllJobs();
307 }
308
309 /**
310 * This is called when the temp whitelist changes.
311 */
Makoto Onukie4918212018-02-06 11:30:15 -0800312 private void onTempPowerSaveWhitelistChanged(AppStateTracker sender) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800313
314 // TODO This case happens rather frequently; consider optimizing and update jobs
315 // only for affected app-ids.
316
317 updateAllJobs();
Makoto Onukieb898f12018-01-23 15:26:27 -0800318
319 // Note when an app is just put in the temp whitelist, we do *not* drain pending alarms.
320 }
321
322 /**
323 * This is called when the EXEMPT bucket is updated.
324 */
Makoto Onukie4918212018-02-06 11:30:15 -0800325 private void onExemptChanged(AppStateTracker sender) {
Makoto Onukieb898f12018-01-23 15:26:27 -0800326 // This doesn't happen very often, so just re-evaluate all jobs / alarms.
327 updateAllJobs();
328 unblockAllUnrestrictedAlarms();
Makoto Onuki2206af32017-11-21 16:25:35 -0800329 }
330
331 /**
332 * This is called when the global "force all apps standby" flag changes.
333 */
Makoto Onukie4918212018-02-06 11:30:15 -0800334 private void onForceAllAppsStandbyChanged(AppStateTracker sender) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800335 updateAllJobs();
336
337 if (!sender.isForceAllAppsStandbyEnabled()) {
338 unblockAllUnrestrictedAlarms();
339 }
340 }
341
342 /**
343 * Called when the job restrictions for multiple UIDs might have changed, so the job
344 * scheduler should re-evaluate all restrictions for all jobs.
345 */
346 public void updateAllJobs() {
347 }
348
349 /**
350 * Called when the job restrictions for a UID 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 updateJobsForUid(int uid, boolean isNowActive) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800354 }
355
356 /**
357 * Called when the job restrictions for a UID - package might have changed, so the job
358 * scheduler should re-evaluate all restrictions for all jobs.
359 */
Christopher Tate20afddd2018-02-28 15:19:19 -0800360 public void updateJobsForUidPackage(int uid, String packageName, boolean isNowActive) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800361 }
362
363 /**
Christopher Tatec7933ac2018-03-12 17:57:09 -0700364 * Called when an app goes into forced app standby and its foreground
365 * services need to be removed from that state.
366 */
367 public void stopForegroundServicesForUidPackage(int uid, String packageName) {
368 }
369
370 /**
Makoto Onuki2206af32017-11-21 16:25:35 -0800371 * Called when the job restrictions for multiple UIDs might have changed, so the alarm
372 * manager should re-evaluate all restrictions for all blocked jobs.
373 */
374 public void unblockAllUnrestrictedAlarms() {
375 }
376
377 /**
378 * Called when all jobs for a specific UID are unblocked.
379 */
380 public void unblockAlarmsForUid(int uid) {
381 }
382
383 /**
384 * Called when all alarms for a specific UID - package are unblocked.
385 */
386 public void unblockAlarmsForUidPackage(int uid, String packageName) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800387 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800388
389 /**
390 * Called when a UID comes into the foreground or the background.
391 *
392 * @see #isUidInForeground(int)
393 */
394 public void onUidForeground(int uid, boolean foreground) {
395 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800396 }
397
Makoto Onukie4918212018-02-06 11:30:15 -0800398 public AppStateTracker(Context context, Looper looper) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800399 mContext = context;
Makoto Onuki2206af32017-11-21 16:25:35 -0800400 mHandler = new MyHandler(looper);
401 }
402
Makoto Onuki9be01402017-11-10 13:22:26 -0800403 /**
404 * Call it when the system is ready.
405 */
Makoto Onukie4918212018-02-06 11:30:15 -0800406 public void onSystemServicesReady() {
Makoto Onuki9be01402017-11-10 13:22:26 -0800407 synchronized (mLock) {
408 if (mStarted) {
409 return;
410 }
411 mStarted = true;
412
Makoto Onuki2206af32017-11-21 16:25:35 -0800413 mIActivityManager = Preconditions.checkNotNull(injectIActivityManager());
Makoto Onukie4918212018-02-06 11:30:15 -0800414 mActivityManagerInternal = Preconditions.checkNotNull(injectActivityManagerInternal());
Makoto Onuki2206af32017-11-21 16:25:35 -0800415 mAppOpsManager = Preconditions.checkNotNull(injectAppOpsManager());
416 mAppOpsService = Preconditions.checkNotNull(injectIAppOpsService());
417 mPowerManagerInternal = Preconditions.checkNotNull(injectPowerManagerInternal());
Makoto Onukieb898f12018-01-23 15:26:27 -0800418 mUsageStatsManagerInternal = Preconditions.checkNotNull(
419 injectUsageStatsManagerInternal());
420
Nancy Zheng525aaa12018-01-12 11:45:37 -0800421 mFlagsObserver = new FeatureFlagsObserver();
422 mFlagsObserver.register();
423 mForcedAppStandbyEnabled = mFlagsObserver.isForcedAppStandbyEnabled();
424 mForceAllAppStandbyForSmallBattery =
425 mFlagsObserver.isForcedAppStandbyForSmallBatteryEnabled();
Makoto Onukieb898f12018-01-23 15:26:27 -0800426 mStandbyTracker = new StandbyTracker();
427 mUsageStatsManagerInternal.addAppIdleStateChangeListener(mStandbyTracker);
Makoto Onuki9be01402017-11-10 13:22:26 -0800428
429 try {
Makoto Onuki2206af32017-11-21 16:25:35 -0800430 mIActivityManager.registerUidObserver(new UidObserver(),
Makoto Onukiadb50d82018-01-29 16:20:30 -0800431 ActivityManager.UID_OBSERVER_GONE
432 | ActivityManager.UID_OBSERVER_IDLE
433 | ActivityManager.UID_OBSERVER_ACTIVE
434 | ActivityManager.UID_OBSERVER_PROCSTATE,
Makoto Onuki9be01402017-11-10 13:22:26 -0800435 ActivityManager.PROCESS_STATE_UNKNOWN, null);
Makoto Onuki2206af32017-11-21 16:25:35 -0800436 mAppOpsService.startWatchingMode(TARGET_OP, null,
Makoto Onuki9be01402017-11-10 13:22:26 -0800437 new AppOpsWatcher());
438 } catch (RemoteException e) {
439 // shouldn't happen.
440 }
441
Makoto Onuki2206af32017-11-21 16:25:35 -0800442 IntentFilter filter = new IntentFilter();
443 filter.addAction(Intent.ACTION_USER_REMOVED);
Nancy Zheng525aaa12018-01-12 11:45:37 -0800444 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800445 mContext.registerReceiver(new MyReceiver(), filter);
Makoto Onuki9be01402017-11-10 13:22:26 -0800446
447 refreshForcedAppStandbyUidPackagesLocked();
Makoto Onuki2206af32017-11-21 16:25:35 -0800448
449 mPowerManagerInternal.registerLowPowerModeObserver(
450 ServiceType.FORCE_ALL_APPS_STANDBY,
Nancy Zheng525aaa12018-01-12 11:45:37 -0800451 (state) -> {
452 synchronized (mLock) {
453 mBatterySaverEnabled = state.batterySaverEnabled;
454 updateForceAllAppStandbyState();
455 }
456 });
Makoto Onuki2206af32017-11-21 16:25:35 -0800457
Nancy Zheng525aaa12018-01-12 11:45:37 -0800458 mBatterySaverEnabled = mPowerManagerInternal.getLowPowerState(
459 ServiceType.FORCE_ALL_APPS_STANDBY).batterySaverEnabled;
460
461 updateForceAllAppStandbyState();
Makoto Onuki9be01402017-11-10 13:22:26 -0800462 }
463 }
464
Makoto Onuki2206af32017-11-21 16:25:35 -0800465 @VisibleForTesting
466 AppOpsManager injectAppOpsManager() {
467 return mContext.getSystemService(AppOpsManager.class);
468 }
469
470 @VisibleForTesting
471 IAppOpsService injectIAppOpsService() {
472 return IAppOpsService.Stub.asInterface(
473 ServiceManager.getService(Context.APP_OPS_SERVICE));
474 }
475
476 @VisibleForTesting
477 IActivityManager injectIActivityManager() {
478 return ActivityManager.getService();
479 }
480
481 @VisibleForTesting
Makoto Onukie4918212018-02-06 11:30:15 -0800482 ActivityManagerInternal injectActivityManagerInternal() {
483 return LocalServices.getService(ActivityManagerInternal.class);
484 }
485
486 @VisibleForTesting
Makoto Onuki2206af32017-11-21 16:25:35 -0800487 PowerManagerInternal injectPowerManagerInternal() {
488 return LocalServices.getService(PowerManagerInternal.class);
489 }
490
Nancy Zheng525aaa12018-01-12 11:45:37 -0800491 @VisibleForTesting
Makoto Onukieb898f12018-01-23 15:26:27 -0800492 UsageStatsManagerInternal injectUsageStatsManagerInternal() {
493 return LocalServices.getService(UsageStatsManagerInternal.class);
494 }
495
496 @VisibleForTesting
Nancy Zheng525aaa12018-01-12 11:45:37 -0800497 boolean isSmallBatteryDevice() {
498 return ActivityManager.isSmallBatteryDevice();
499 }
500
Makoto Onukieb898f12018-01-23 15:26:27 -0800501 @VisibleForTesting
502 int injectGetGlobalSettingInt(String key, int def) {
503 return Settings.Global.getInt(mContext.getContentResolver(), key, def);
504 }
505
Makoto Onuki9be01402017-11-10 13:22:26 -0800506 /**
Makoto Onuki2206af32017-11-21 16:25:35 -0800507 * Update {@link #mRunAnyRestrictedPackages} with the current app ops state.
Makoto Onuki9be01402017-11-10 13:22:26 -0800508 */
Andreas Gampea36dc622018-02-05 17:19:22 -0800509 @GuardedBy("mLock")
Makoto Onuki9be01402017-11-10 13:22:26 -0800510 private void refreshForcedAppStandbyUidPackagesLocked() {
Makoto Onuki2206af32017-11-21 16:25:35 -0800511 mRunAnyRestrictedPackages.clear();
512 final List<PackageOps> ops = mAppOpsManager.getPackagesForOps(
513 new int[] {TARGET_OP});
Makoto Onuki9be01402017-11-10 13:22:26 -0800514
515 if (ops == null) {
516 return;
517 }
518 final int size = ops.size();
519 for (int i = 0; i < size; i++) {
520 final AppOpsManager.PackageOps pkg = ops.get(i);
521 final List<AppOpsManager.OpEntry> entries = ops.get(i).getOps();
522
523 for (int j = 0; j < entries.size(); j++) {
524 AppOpsManager.OpEntry ent = entries.get(j);
Makoto Onuki2206af32017-11-21 16:25:35 -0800525 if (ent.getOp() != TARGET_OP) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800526 continue;
527 }
528 if (ent.getMode() != AppOpsManager.MODE_ALLOWED) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800529 mRunAnyRestrictedPackages.add(Pair.create(
Makoto Onuki9be01402017-11-10 13:22:26 -0800530 pkg.getUid(), pkg.getPackageName()));
531 }
532 }
533 }
534 }
535
Nancy Zheng525aaa12018-01-12 11:45:37 -0800536 private void updateForceAllAppStandbyState() {
537 synchronized (mLock) {
538 if (mForceAllAppStandbyForSmallBattery && isSmallBatteryDevice()) {
539 toggleForceAllAppsStandbyLocked(!mIsPluggedIn);
540 } else {
541 toggleForceAllAppsStandbyLocked(mBatterySaverEnabled);
542 }
543 }
544 }
545
Makoto Onuki2206af32017-11-21 16:25:35 -0800546 /**
547 * Update {@link #mForceAllAppsStandby} and notifies the listeners.
548 */
Andreas Gampea36dc622018-02-05 17:19:22 -0800549 @GuardedBy("mLock")
Nancy Zheng525aaa12018-01-12 11:45:37 -0800550 private void toggleForceAllAppsStandbyLocked(boolean enable) {
551 if (enable == mForceAllAppsStandby) {
552 return;
Makoto Onuki12391f22018-01-18 21:44:28 +0000553 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800554 mForceAllAppsStandby = enable;
555
556 mHandler.notifyForceAllAppsStandbyChanged();
Makoto Onuki9be01402017-11-10 13:22:26 -0800557 }
558
Andreas Gampea36dc622018-02-05 17:19:22 -0800559 @GuardedBy("mLock")
Makoto Onuki9be01402017-11-10 13:22:26 -0800560 private int findForcedAppStandbyUidPackageIndexLocked(int uid, @NonNull String packageName) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800561 final int size = mRunAnyRestrictedPackages.size();
562 if (size > 8) {
563 return mRunAnyRestrictedPackages.indexOf(Pair.create(uid, packageName));
564 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800565 for (int i = 0; i < size; i++) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800566 final Pair<Integer, String> pair = mRunAnyRestrictedPackages.valueAt(i);
Makoto Onuki9be01402017-11-10 13:22:26 -0800567
568 if ((pair.first == uid) && packageName.equals(pair.second)) {
569 return i;
570 }
571 }
572 return -1;
573 }
574
575 /**
Makoto Onuki2206af32017-11-21 16:25:35 -0800576 * @return whether a uid package-name pair is in mRunAnyRestrictedPackages.
Makoto Onuki9be01402017-11-10 13:22:26 -0800577 */
Andreas Gampea36dc622018-02-05 17:19:22 -0800578 @GuardedBy("mLock")
Makoto Onuki2206af32017-11-21 16:25:35 -0800579 boolean isRunAnyRestrictedLocked(int uid, @NonNull String packageName) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800580 return findForcedAppStandbyUidPackageIndexLocked(uid, packageName) >= 0;
581 }
582
Makoto Onuki2206af32017-11-21 16:25:35 -0800583 /**
584 * Add to / remove from {@link #mRunAnyRestrictedPackages}.
585 */
Andreas Gampea36dc622018-02-05 17:19:22 -0800586 @GuardedBy("mLock")
Makoto Onuki2206af32017-11-21 16:25:35 -0800587 boolean updateForcedAppStandbyUidPackageLocked(int uid, @NonNull String packageName,
Makoto Onuki9be01402017-11-10 13:22:26 -0800588 boolean restricted) {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800589 final int index = findForcedAppStandbyUidPackageIndexLocked(uid, packageName);
Makoto Onuki9be01402017-11-10 13:22:26 -0800590 final boolean wasRestricted = index >= 0;
591 if (wasRestricted == restricted) {
592 return false;
593 }
594 if (restricted) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800595 mRunAnyRestrictedPackages.add(Pair.create(uid, packageName));
Makoto Onuki9be01402017-11-10 13:22:26 -0800596 } else {
Makoto Onuki2206af32017-11-21 16:25:35 -0800597 mRunAnyRestrictedPackages.removeAt(index);
Makoto Onuki9be01402017-11-10 13:22:26 -0800598 }
599 return true;
600 }
601
Makoto Onukiadb50d82018-01-29 16:20:30 -0800602 private static boolean addUidToArray(SparseBooleanArray array, int uid) {
603 if (UserHandle.isCore(uid)) {
604 return false;
Makoto Onuki9be01402017-11-10 13:22:26 -0800605 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800606 if (array.get(uid)) {
607 return false;
608 }
609 array.put(uid, true);
610 return true;
Makoto Onuki9be01402017-11-10 13:22:26 -0800611 }
612
Makoto Onukiadb50d82018-01-29 16:20:30 -0800613 private static boolean removeUidFromArray(SparseBooleanArray array, int uid, boolean remove) {
614 if (UserHandle.isCore(uid)) {
615 return false;
Makoto Onuki9be01402017-11-10 13:22:26 -0800616 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800617 if (!array.get(uid)) {
618 return false;
619 }
620 if (remove) {
621 array.delete(uid);
622 } else {
623 array.put(uid, false);
624 }
625 return true;
Makoto Onuki9be01402017-11-10 13:22:26 -0800626 }
627
Makoto Onuki2206af32017-11-21 16:25:35 -0800628 private final class UidObserver extends IUidObserver.Stub {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800629 @Override
630 public void onUidStateChanged(int uid, int procState, long procStateSeq) {
Makoto Onuki4d298b52018-02-05 10:54:58 -0800631 mHandler.onUidStateChanged(uid, procState);
Makoto Onuki9be01402017-11-10 13:22:26 -0800632 }
633
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800634 @Override
635 public void onUidActive(int uid) {
Makoto Onuki4d298b52018-02-05 10:54:58 -0800636 mHandler.onUidActive(uid);
637 }
638
639 @Override
640 public void onUidGone(int uid, boolean disabled) {
641 mHandler.onUidGone(uid, disabled);
Makoto Onuki9be01402017-11-10 13:22:26 -0800642 }
643
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800644 @Override
645 public void onUidIdle(int uid, boolean disabled) {
Makoto Onuki4d298b52018-02-05 10:54:58 -0800646 mHandler.onUidIdle(uid, disabled);
Makoto Onuki9be01402017-11-10 13:22:26 -0800647 }
648
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800649 @Override
650 public void onUidCachedChanged(int uid, boolean cached) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800651 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800652 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800653
654 private final class AppOpsWatcher extends IAppOpsCallback.Stub {
655 @Override
656 public void opChanged(int op, int uid, String packageName) throws RemoteException {
Makoto Onuki2206af32017-11-21 16:25:35 -0800657 boolean restricted = false;
658 try {
659 restricted = mAppOpsService.checkOperation(TARGET_OP,
660 uid, packageName) != AppOpsManager.MODE_ALLOWED;
661 } catch (RemoteException e) {
662 // Shouldn't happen
663 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800664 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800665 if (updateForcedAppStandbyUidPackageLocked(uid, packageName, restricted)) {
666 mHandler.notifyRunAnyAppOpsChanged(uid, packageName);
667 }
668 }
669 }
670 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800671
Makoto Onuki2206af32017-11-21 16:25:35 -0800672 private final class MyReceiver extends BroadcastReceiver {
673 @Override
674 public void onReceive(Context context, Intent intent) {
675 if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
676 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
677 if (userId > 0) {
678 mHandler.doUserRemoved(userId);
Makoto Onuki9be01402017-11-10 13:22:26 -0800679 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800680 } else if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
681 synchronized (mLock) {
682 mIsPluggedIn = (intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0);
683 }
684 updateForceAllAppStandbyState();
Makoto Onuki9be01402017-11-10 13:22:26 -0800685 }
686 }
687 }
688
Makoto Onukieb898f12018-01-23 15:26:27 -0800689 final class StandbyTracker extends AppIdleStateChangeListener {
690 @Override
691 public void onAppIdleStateChanged(String packageName, int userId, boolean idle,
Amith Yamasani119be9a2018-02-18 22:23:00 -0800692 int bucket, int reason) {
Makoto Onukieb898f12018-01-23 15:26:27 -0800693 if (DEBUG) {
694 Slog.d(TAG,"onAppIdleStateChanged: " + packageName + " u" + userId
695 + (idle ? " idle" : " active") + " " + bucket);
696 }
697 final boolean changed;
698 if (bucket == UsageStatsManager.STANDBY_BUCKET_EXEMPTED) {
699 changed = mExemptedPackages.add(userId, packageName);
700 } else {
701 changed = mExemptedPackages.remove(userId, packageName);
702 }
703 if (changed) {
704 mHandler.notifyExemptChanged();
705 }
706 }
707
708 @Override
709 public void onParoleStateChanged(boolean isParoleOn) {
710 }
711 }
712
Makoto Onuki9be01402017-11-10 13:22:26 -0800713 private Listener[] cloneListeners() {
714 synchronized (mLock) {
715 return mListeners.toArray(new Listener[mListeners.size()]);
716 }
717 }
718
Makoto Onuki2206af32017-11-21 16:25:35 -0800719 private class MyHandler extends Handler {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800720 private static final int MSG_UID_ACTIVE_STATE_CHANGED = 0;
721 private static final int MSG_UID_FG_STATE_CHANGED = 1;
722 private static final int MSG_RUN_ANY_CHANGED = 3;
723 private static final int MSG_ALL_UNWHITELISTED = 4;
724 private static final int MSG_ALL_WHITELIST_CHANGED = 5;
725 private static final int MSG_TEMP_WHITELIST_CHANGED = 6;
726 private static final int MSG_FORCE_ALL_CHANGED = 7;
727 private static final int MSG_USER_REMOVED = 8;
728 private static final int MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED = 9;
729 private static final int MSG_EXEMPT_CHANGED = 10;
Makoto Onuki9be01402017-11-10 13:22:26 -0800730
Makoto Onuki4d298b52018-02-05 10:54:58 -0800731 private static final int MSG_ON_UID_STATE_CHANGED = 11;
732 private static final int MSG_ON_UID_ACTIVE = 12;
733 private static final int MSG_ON_UID_GONE = 13;
734 private static final int MSG_ON_UID_IDLE = 14;
735
Makoto Onuki2206af32017-11-21 16:25:35 -0800736 public MyHandler(Looper looper) {
737 super(looper);
Makoto Onuki9be01402017-11-10 13:22:26 -0800738 }
Makoto Onuki2206af32017-11-21 16:25:35 -0800739
Makoto Onukiadb50d82018-01-29 16:20:30 -0800740 public void notifyUidActiveStateChanged(int uid) {
741 obtainMessage(MSG_UID_ACTIVE_STATE_CHANGED, uid, 0).sendToTarget();
742 }
743
Makoto Onuki2206af32017-11-21 16:25:35 -0800744 public void notifyUidForegroundStateChanged(int uid) {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800745 obtainMessage(MSG_UID_FG_STATE_CHANGED, uid, 0).sendToTarget();
Makoto Onuki2206af32017-11-21 16:25:35 -0800746 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800747
Makoto Onuki2206af32017-11-21 16:25:35 -0800748 public void notifyRunAnyAppOpsChanged(int uid, @NonNull String packageName) {
749 obtainMessage(MSG_RUN_ANY_CHANGED, uid, 0, packageName).sendToTarget();
750 }
751
752 public void notifyAllUnwhitelisted() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800753 removeMessages(MSG_ALL_UNWHITELISTED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800754 obtainMessage(MSG_ALL_UNWHITELISTED).sendToTarget();
755 }
756
757 public void notifyAllWhitelistChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800758 removeMessages(MSG_ALL_WHITELIST_CHANGED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800759 obtainMessage(MSG_ALL_WHITELIST_CHANGED).sendToTarget();
760 }
761
762 public void notifyTempWhitelistChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800763 removeMessages(MSG_TEMP_WHITELIST_CHANGED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800764 obtainMessage(MSG_TEMP_WHITELIST_CHANGED).sendToTarget();
765 }
766
767 public void notifyForceAllAppsStandbyChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800768 removeMessages(MSG_FORCE_ALL_CHANGED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800769 obtainMessage(MSG_FORCE_ALL_CHANGED).sendToTarget();
770 }
771
Nancy Zheng525aaa12018-01-12 11:45:37 -0800772 public void notifyForcedAppStandbyFeatureFlagChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800773 removeMessages(MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED);
Nancy Zheng525aaa12018-01-12 11:45:37 -0800774 obtainMessage(MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED).sendToTarget();
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800775 }
776
Makoto Onukieb898f12018-01-23 15:26:27 -0800777 public void notifyExemptChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800778 removeMessages(MSG_EXEMPT_CHANGED);
Makoto Onukieb898f12018-01-23 15:26:27 -0800779 obtainMessage(MSG_EXEMPT_CHANGED).sendToTarget();
780 }
781
Makoto Onuki2206af32017-11-21 16:25:35 -0800782 public void doUserRemoved(int userId) {
783 obtainMessage(MSG_USER_REMOVED, userId, 0).sendToTarget();
784 }
785
Makoto Onuki4d298b52018-02-05 10:54:58 -0800786 public void onUidStateChanged(int uid, int procState) {
787 obtainMessage(MSG_ON_UID_STATE_CHANGED, uid, procState).sendToTarget();
788 }
789
790 public void onUidActive(int uid) {
791 obtainMessage(MSG_ON_UID_ACTIVE, uid, 0).sendToTarget();
792 }
793
794 public void onUidGone(int uid, boolean disabled) {
795 obtainMessage(MSG_ON_UID_GONE, uid, disabled ? 1 : 0).sendToTarget();
796 }
797
798 public void onUidIdle(int uid, boolean disabled) {
799 obtainMessage(MSG_ON_UID_IDLE, uid, disabled ? 1 : 0).sendToTarget();
800 }
801
Makoto Onuki2206af32017-11-21 16:25:35 -0800802 @Override
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800803 public void handleMessage(Message msg) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800804 switch (msg.what) {
805 case MSG_USER_REMOVED:
806 handleUserRemoved(msg.arg1);
807 return;
808 }
809
810 // Only notify the listeners when started.
811 synchronized (mLock) {
812 if (!mStarted) {
813 return;
814 }
815 }
Makoto Onukie4918212018-02-06 11:30:15 -0800816 final AppStateTracker sender = AppStateTracker.this;
Makoto Onuki2206af32017-11-21 16:25:35 -0800817
Makoto Onukieb898f12018-01-23 15:26:27 -0800818 long start = mStatLogger.getTime();
Makoto Onuki2206af32017-11-21 16:25:35 -0800819 switch (msg.what) {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800820 case MSG_UID_ACTIVE_STATE_CHANGED:
821 for (Listener l : cloneListeners()) {
822 l.onUidActiveStateChanged(sender, msg.arg1);
823 }
824 mStatLogger.logDurationStat(Stats.UID_ACTIVE_STATE_CHANGED, start);
825 return;
826
827 case MSG_UID_FG_STATE_CHANGED:
Makoto Onuki2206af32017-11-21 16:25:35 -0800828 for (Listener l : cloneListeners()) {
829 l.onUidForegroundStateChanged(sender, msg.arg1);
830 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800831 mStatLogger.logDurationStat(Stats.UID_FG_STATE_CHANGED, 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_RUN_ANY_CHANGED:
835 for (Listener l : cloneListeners()) {
836 l.onRunAnyAppOpsChanged(sender, msg.arg1, (String) msg.obj);
837 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800838 mStatLogger.logDurationStat(Stats.RUN_ANY_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_ALL_UNWHITELISTED:
842 for (Listener l : cloneListeners()) {
843 l.onPowerSaveUnwhitelisted(sender);
844 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800845 mStatLogger.logDurationStat(Stats.ALL_UNWHITELISTED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800846 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800847
Makoto Onuki2206af32017-11-21 16:25:35 -0800848 case MSG_ALL_WHITELIST_CHANGED:
849 for (Listener l : cloneListeners()) {
850 l.onPowerSaveWhitelistedChanged(sender);
851 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800852 mStatLogger.logDurationStat(Stats.ALL_WHITELIST_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800853 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800854
Makoto Onuki2206af32017-11-21 16:25:35 -0800855 case MSG_TEMP_WHITELIST_CHANGED:
856 for (Listener l : cloneListeners()) {
857 l.onTempPowerSaveWhitelistChanged(sender);
858 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800859 mStatLogger.logDurationStat(Stats.TEMP_WHITELIST_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800860 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800861
862 case MSG_EXEMPT_CHANGED:
863 for (Listener l : cloneListeners()) {
864 l.onExemptChanged(sender);
865 }
866 mStatLogger.logDurationStat(Stats.EXEMPT_CHANGED, start);
867 return;
868
Makoto Onuki2206af32017-11-21 16:25:35 -0800869 case MSG_FORCE_ALL_CHANGED:
870 for (Listener l : cloneListeners()) {
871 l.onForceAllAppsStandbyChanged(sender);
872 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800873 mStatLogger.logDurationStat(Stats.FORCE_ALL_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800874 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800875
Nancy Zheng525aaa12018-01-12 11:45:37 -0800876 case MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED:
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800877 // Feature flag for forced app standby changed.
878 final boolean unblockAlarms;
879 synchronized (mLock) {
880 unblockAlarms = !mForcedAppStandbyEnabled && !mForceAllAppsStandby;
881 }
Suprabh Shuklac25447d2018-01-19 16:43:35 -0800882 for (Listener l : cloneListeners()) {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800883 l.updateAllJobs();
884 if (unblockAlarms) {
885 l.unblockAllUnrestrictedAlarms();
886 }
887 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800888 mStatLogger.logDurationStat(
889 Stats.FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED, start);
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800890 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800891
Makoto Onuki2206af32017-11-21 16:25:35 -0800892 case MSG_USER_REMOVED:
893 handleUserRemoved(msg.arg1);
894 return;
Makoto Onuki4d298b52018-02-05 10:54:58 -0800895
896 case MSG_ON_UID_STATE_CHANGED:
897 handleUidStateChanged(msg.arg1, msg.arg2);
898 return;
899 case MSG_ON_UID_ACTIVE:
900 handleUidActive(msg.arg1);
901 return;
902 case MSG_ON_UID_GONE:
903 handleUidGone(msg.arg1, msg.arg1 != 0);
904 return;
905 case MSG_ON_UID_IDLE:
906 handleUidIdle(msg.arg1, msg.arg1 != 0);
907 return;
908 }
909 }
910
911 public void handleUidStateChanged(int uid, int procState) {
912 synchronized (mLock) {
913 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
914 if (removeUidFromArray(mForegroundUids, uid, false)) {
915 mHandler.notifyUidForegroundStateChanged(uid);
916 }
917 } else {
918 if (addUidToArray(mForegroundUids, uid)) {
919 mHandler.notifyUidForegroundStateChanged(uid);
920 }
921 }
922 }
923 }
924
925 public void handleUidActive(int uid) {
926 synchronized (mLock) {
927 if (addUidToArray(mActiveUids, uid)) {
928 mHandler.notifyUidActiveStateChanged(uid);
929 }
930 }
931 }
932
933 public void handleUidGone(int uid, boolean disabled) {
934 removeUid(uid, true);
935 }
936
937 public void handleUidIdle(int uid, boolean disabled) {
938 // Just to avoid excessive memcpy, don't remove from the array in this case.
939 removeUid(uid, false);
940 }
941
942 private void removeUid(int uid, boolean remove) {
943 synchronized (mLock) {
944 if (removeUidFromArray(mActiveUids, uid, remove)) {
945 mHandler.notifyUidActiveStateChanged(uid);
946 }
947 if (removeUidFromArray(mForegroundUids, uid, remove)) {
948 mHandler.notifyUidForegroundStateChanged(uid);
949 }
Makoto Onuki2206af32017-11-21 16:25:35 -0800950 }
951 }
952 }
953
954 void handleUserRemoved(int removedUserId) {
955 synchronized (mLock) {
956 for (int i = mRunAnyRestrictedPackages.size() - 1; i >= 0; i--) {
957 final Pair<Integer, String> pair = mRunAnyRestrictedPackages.valueAt(i);
958 final int uid = pair.first;
959 final int userId = UserHandle.getUserId(uid);
960
961 if (userId == removedUserId) {
962 mRunAnyRestrictedPackages.removeAt(i);
963 }
964 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800965 cleanUpArrayForUser(mActiveUids, removedUserId);
966 cleanUpArrayForUser(mForegroundUids, removedUserId);
Makoto Onukieb898f12018-01-23 15:26:27 -0800967 mExemptedPackages.remove(removedUserId);
Makoto Onuki2206af32017-11-21 16:25:35 -0800968 }
969 }
970
Makoto Onukiadb50d82018-01-29 16:20:30 -0800971 private void cleanUpArrayForUser(SparseBooleanArray array, int removedUserId) {
972 for (int i = array.size() - 1; i >= 0; i--) {
973 final int uid = array.keyAt(i);
974 final int userId = UserHandle.getUserId(uid);
975
976 if (userId == removedUserId) {
977 array.removeAt(i);
978 }
979 }
980 }
981
Makoto Onuki2206af32017-11-21 16:25:35 -0800982 /**
983 * Called by device idle controller to update the power save whitelists.
984 */
985 public void setPowerSaveWhitelistAppIds(
986 int[] powerSaveWhitelistAllAppIdArray, int[] tempWhitelistAppIdArray) {
987 synchronized (mLock) {
988 final int[] previousWhitelist = mPowerWhitelistedAllAppIds;
989 final int[] previousTempWhitelist = mTempWhitelistedAppIds;
990
991 mPowerWhitelistedAllAppIds = powerSaveWhitelistAllAppIdArray;
992 mTempWhitelistedAppIds = tempWhitelistAppIdArray;
993
994 if (isAnyAppIdUnwhitelisted(previousWhitelist, mPowerWhitelistedAllAppIds)) {
995 mHandler.notifyAllUnwhitelisted();
996 } else if (!Arrays.equals(previousWhitelist, mPowerWhitelistedAllAppIds)) {
997 mHandler.notifyAllWhitelistChanged();
998 }
999
1000 if (!Arrays.equals(previousTempWhitelist, mTempWhitelistedAppIds)) {
1001 mHandler.notifyTempWhitelistChanged();
1002 }
1003
1004 }
1005 }
1006
1007 /**
1008 * @retunr true if a sorted app-id array {@code prevArray} has at least one element
1009 * that's not in a sorted app-id array {@code newArray}.
1010 */
1011 @VisibleForTesting
1012 static boolean isAnyAppIdUnwhitelisted(int[] prevArray, int[] newArray) {
1013 int i1 = 0;
1014 int i2 = 0;
1015 boolean prevFinished;
1016 boolean newFinished;
1017
1018 for (;;) {
1019 prevFinished = i1 >= prevArray.length;
1020 newFinished = i2 >= newArray.length;
1021 if (prevFinished || newFinished) {
1022 break;
1023 }
1024 int a1 = prevArray[i1];
1025 int a2 = newArray[i2];
1026
1027 if (a1 == a2) {
1028 i1++;
1029 i2++;
1030 continue;
1031 }
1032 if (a1 < a2) {
1033 // prevArray has an element that's not in a2.
1034 return true;
1035 }
1036 i2++;
1037 }
1038 if (prevFinished) {
1039 return false;
1040 }
1041 return newFinished;
Makoto Onuki9be01402017-11-10 13:22:26 -08001042 }
1043
1044 // Public interface.
1045
1046 /**
1047 * Register a new listener.
1048 */
1049 public void addListener(@NonNull Listener listener) {
1050 synchronized (mLock) {
1051 mListeners.add(listener);
1052 }
1053 }
1054
1055 /**
Makoto Onuki2206af32017-11-21 16:25:35 -08001056 * @return whether alarms should be restricted for a UID package-name.
Makoto Onuki9be01402017-11-10 13:22:26 -08001057 */
Suprabh Shuklac25447d2018-01-19 16:43:35 -08001058 public boolean areAlarmsRestricted(int uid, @NonNull String packageName,
1059 boolean allowWhileIdle) {
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001060 return isRestricted(uid, packageName, /*useTempWhitelistToo=*/ false,
Suprabh Shuklac25447d2018-01-19 16:43:35 -08001061 /* exemptOnBatterySaver =*/ allowWhileIdle);
Makoto Onuki2206af32017-11-21 16:25:35 -08001062 }
1063
1064 /**
1065 * @return whether jobs should be restricted for a UID package-name.
1066 */
Makoto Onuki15407842018-01-19 14:23:11 -08001067 public boolean areJobsRestricted(int uid, @NonNull String packageName,
1068 boolean hasForegroundExemption) {
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001069 return isRestricted(uid, packageName, /*useTempWhitelistToo=*/ true,
Makoto Onuki15407842018-01-19 14:23:11 -08001070 hasForegroundExemption);
Makoto Onuki2206af32017-11-21 16:25:35 -08001071 }
1072
1073 /**
Christopher Tatec7933ac2018-03-12 17:57:09 -07001074 * @return whether foreground services should be suppressed in the background
1075 * due to forced app standby for the given app
1076 */
1077 public boolean areForegroundServicesRestricted(int uid, @NonNull String packageName) {
1078 synchronized (mLock) {
1079 return isRunAnyRestrictedLocked(uid, packageName);
1080 }
1081 }
1082
1083 /**
Makoto Onuki2206af32017-11-21 16:25:35 -08001084 * @return whether force-app-standby is effective for a UID package-name.
1085 */
1086 private boolean isRestricted(int uid, @NonNull String packageName,
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001087 boolean useTempWhitelistToo, boolean exemptOnBatterySaver) {
Makoto Onukiadb50d82018-01-29 16:20:30 -08001088 if (isUidActive(uid)) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001089 return false;
1090 }
1091 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001092 // Whitelisted?
1093 final int appId = UserHandle.getAppId(uid);
1094 if (ArrayUtils.contains(mPowerWhitelistedAllAppIds, appId)) {
1095 return false;
1096 }
1097 if (useTempWhitelistToo &&
1098 ArrayUtils.contains(mTempWhitelistedAppIds, appId)) {
1099 return false;
1100 }
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001101 if (mForcedAppStandbyEnabled && isRunAnyRestrictedLocked(uid, packageName)) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001102 return true;
1103 }
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001104 if (exemptOnBatterySaver) {
1105 return false;
1106 }
Makoto Onukieb898f12018-01-23 15:26:27 -08001107 final int userId = UserHandle.getUserId(uid);
1108 if (mExemptedPackages.contains(userId, packageName)) {
1109 return false;
1110 }
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001111 return mForceAllAppsStandby;
Makoto Onuki9be01402017-11-10 13:22:26 -08001112 }
1113 }
1114
Makoto Onuki2206af32017-11-21 16:25:35 -08001115 /**
Makoto Onukie4918212018-02-06 11:30:15 -08001116 * @return whether a UID is in active or not *based on cached information.*
Makoto Onukiadb50d82018-01-29 16:20:30 -08001117 *
1118 * Note this information is based on the UID proc state callback, meaning it's updated
1119 * asynchronously and may subtly be stale. If the fresh data is needed, use
Makoto Onukie4918212018-02-06 11:30:15 -08001120 * {@link #isUidActiveSynced} instead.
Makoto Onukiadb50d82018-01-29 16:20:30 -08001121 */
1122 public boolean isUidActive(int uid) {
1123 if (UserHandle.isCore(uid)) {
1124 return true;
1125 }
1126 synchronized (mLock) {
1127 return mActiveUids.get(uid);
1128 }
1129 }
1130
1131 /**
Makoto Onukie4918212018-02-06 11:30:15 -08001132 * @return whether a UID is in active or not *right now.*
1133 *
1134 * This gives the fresh information, but may access the activity manager so is slower.
1135 */
1136 public boolean isUidActiveSynced(int uid) {
1137 if (isUidActive(uid)) { // Use the cached one first.
1138 return true;
1139 }
1140 final long start = mStatLogger.getTime();
1141
1142 final boolean ret = mActivityManagerInternal.isUidActive(uid);
1143 mStatLogger.logDurationStat(Stats.IS_UID_ACTIVE_RAW, start);
1144
1145 return ret;
1146 }
1147
1148 /**
Makoto Onuki2206af32017-11-21 16:25:35 -08001149 * @return whether a UID is in the foreground or not.
1150 *
Makoto Onuki15407842018-01-19 14:23:11 -08001151 * Note this information is based on the UID proc state callback, meaning it's updated
1152 * asynchronously and may subtly be stale. If the fresh data is needed, use
1153 * {@link ActivityManagerInternal#getUidProcessState} instead.
Makoto Onuki2206af32017-11-21 16:25:35 -08001154 */
Makoto Onukiadb50d82018-01-29 16:20:30 -08001155 public boolean isUidInForeground(int uid) {
Makoto Onuki9cc471c2018-01-23 12:33:56 -08001156 if (UserHandle.isCore(uid)) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001157 return true;
1158 }
1159 synchronized (mLock) {
1160 return mForegroundUids.get(uid);
1161 }
1162 }
1163
Makoto Onuki2206af32017-11-21 16:25:35 -08001164 /**
1165 * @return whether force all apps standby is enabled or not.
1166 *
Makoto Onuki2206af32017-11-21 16:25:35 -08001167 */
1168 boolean isForceAllAppsStandbyEnabled() {
Makoto Onuki9be01402017-11-10 13:22:26 -08001169 synchronized (mLock) {
1170 return mForceAllAppsStandby;
1171 }
1172 }
1173
Makoto Onuki2206af32017-11-21 16:25:35 -08001174 /**
1175 * @return whether a UID/package has {@code OP_RUN_ANY_IN_BACKGROUND} allowed or not.
1176 *
1177 * Note clients normally shouldn't need to access it. It's only for dumpsys.
1178 */
Makoto Onuki9be01402017-11-10 13:22:26 -08001179 public boolean isRunAnyInBackgroundAppOpsAllowed(int uid, @NonNull String packageName) {
1180 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001181 return !isRunAnyRestrictedLocked(uid, packageName);
Makoto Onuki9be01402017-11-10 13:22:26 -08001182 }
1183 }
1184
Makoto Onuki2206af32017-11-21 16:25:35 -08001185 /**
1186 * @return whether a UID is in the user / system defined power-save whitelist or not.
1187 *
1188 * Note clients normally shouldn't need to access it. It's only for dumpsys.
1189 */
1190 public boolean isUidPowerSaveWhitelisted(int uid) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001191 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001192 return ArrayUtils.contains(mPowerWhitelistedAllAppIds, UserHandle.getAppId(uid));
Makoto Onuki9be01402017-11-10 13:22:26 -08001193 }
1194 }
1195
Makoto Onuki2206af32017-11-21 16:25:35 -08001196 /**
1197 * @return whether a UID is in the temp power-save whitelist or not.
1198 *
1199 * Note clients normally shouldn't need to access it. It's only for dumpsys.
1200 */
1201 public boolean isUidTempPowerSaveWhitelisted(int uid) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001202 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001203 return ArrayUtils.contains(mTempWhitelistedAppIds, UserHandle.getAppId(uid));
1204 }
1205 }
1206
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001207 @Deprecated
1208 public void dump(PrintWriter pw, String prefix) {
1209 dump(new IndentingPrintWriter(pw, " ").setIndent(prefix));
1210 }
1211
1212 public void dump(IndentingPrintWriter pw) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001213 synchronized (mLock) {
Suprabh Shukla4deb8522018-01-08 16:27:10 -08001214 pw.println("Forced App Standby Feature enabled: " + mForcedAppStandbyEnabled);
1215
Makoto Onuki2206af32017-11-21 16:25:35 -08001216 pw.print("Force all apps standby: ");
1217 pw.println(isForceAllAppsStandbyEnabled());
1218
Nancy Zheng525aaa12018-01-12 11:45:37 -08001219 pw.print("Small Battery Device: ");
1220 pw.println(isSmallBatteryDevice());
1221
Nancy Zheng525aaa12018-01-12 11:45:37 -08001222 pw.print("Force all apps standby for small battery device: ");
1223 pw.println(mForceAllAppStandbyForSmallBattery);
1224
Nancy Zheng525aaa12018-01-12 11:45:37 -08001225 pw.print("Plugged In: ");
1226 pw.println(mIsPluggedIn);
1227
Makoto Onukiadb50d82018-01-29 16:20:30 -08001228 pw.print("Active uids: ");
1229 dumpUids(pw, mActiveUids);
Makoto Onuki2206af32017-11-21 16:25:35 -08001230
Makoto Onukiadb50d82018-01-29 16:20:30 -08001231 pw.print("Foreground uids: ");
1232 dumpUids(pw, mForegroundUids);
Makoto Onuki2206af32017-11-21 16:25:35 -08001233
Makoto Onuki2206af32017-11-21 16:25:35 -08001234 pw.print("Whitelist appids: ");
1235 pw.println(Arrays.toString(mPowerWhitelistedAllAppIds));
1236
Makoto Onuki2206af32017-11-21 16:25:35 -08001237 pw.print("Temp whitelist appids: ");
1238 pw.println(Arrays.toString(mTempWhitelistedAppIds));
1239
Makoto Onukieb898f12018-01-23 15:26:27 -08001240 pw.println("Exempted packages:");
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001241 pw.increaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001242 for (int i = 0; i < mExemptedPackages.size(); i++) {
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001243 pw.print("User ");
Makoto Onukieb898f12018-01-23 15:26:27 -08001244 pw.print(mExemptedPackages.keyAt(i));
1245 pw.println();
1246
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001247 pw.increaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001248 for (int j = 0; j < mExemptedPackages.sizeAt(i); j++) {
Makoto Onukieb898f12018-01-23 15:26:27 -08001249 pw.print(mExemptedPackages.valueAt(i, j));
1250 pw.println();
1251 }
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001252 pw.decreaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001253 }
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001254 pw.decreaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001255 pw.println();
1256
Makoto Onuki2206af32017-11-21 16:25:35 -08001257 pw.println("Restricted packages:");
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001258 pw.increaseIndent();
Makoto Onuki2206af32017-11-21 16:25:35 -08001259 for (Pair<Integer, String> uidAndPackage : mRunAnyRestrictedPackages) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001260 pw.print(UserHandle.formatUid(uidAndPackage.first));
1261 pw.print(" ");
1262 pw.print(uidAndPackage.second);
1263 pw.println();
1264 }
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001265 pw.decreaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001266
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001267 mStatLogger.dump(pw);
Makoto Onuki2206af32017-11-21 16:25:35 -08001268 }
1269 }
1270
Makoto Onukiadb50d82018-01-29 16:20:30 -08001271 private void dumpUids(PrintWriter pw, SparseBooleanArray array) {
1272 pw.print("[");
1273
1274 String sep = "";
1275 for (int i = 0; i < array.size(); i++) {
1276 if (array.valueAt(i)) {
1277 pw.print(sep);
1278 pw.print(UserHandle.formatUid(array.keyAt(i)));
1279 sep = " ";
1280 }
1281 }
1282 pw.println("]");
1283 }
1284
Makoto Onuki2206af32017-11-21 16:25:35 -08001285 public void dumpProto(ProtoOutputStream proto, long fieldId) {
1286 synchronized (mLock) {
1287 final long token = proto.start(fieldId);
1288
1289 proto.write(ForceAppStandbyTrackerProto.FORCE_ALL_APPS_STANDBY, mForceAllAppsStandby);
Nancy Zheng525aaa12018-01-12 11:45:37 -08001290 proto.write(ForceAppStandbyTrackerProto.IS_SMALL_BATTERY_DEVICE,
1291 isSmallBatteryDevice());
1292 proto.write(ForceAppStandbyTrackerProto.FORCE_ALL_APPS_STANDBY_FOR_SMALL_BATTERY,
1293 mForceAllAppStandbyForSmallBattery);
Makoto Onukieb898f12018-01-23 15:26:27 -08001294 proto.write(ForceAppStandbyTrackerProto.IS_PLUGGED_IN, mIsPluggedIn);
Makoto Onuki2206af32017-11-21 16:25:35 -08001295
Makoto Onukiadb50d82018-01-29 16:20:30 -08001296 for (int i = 0; i < mActiveUids.size(); i++) {
1297 if (mActiveUids.valueAt(i)) {
1298 proto.write(ForceAppStandbyTrackerProto.ACTIVE_UIDS,
1299 mActiveUids.keyAt(i));
1300 }
1301 }
1302
Makoto Onuki2206af32017-11-21 16:25:35 -08001303 for (int i = 0; i < mForegroundUids.size(); i++) {
1304 if (mForegroundUids.valueAt(i)) {
1305 proto.write(ForceAppStandbyTrackerProto.FOREGROUND_UIDS,
1306 mForegroundUids.keyAt(i));
1307 }
1308 }
1309
1310 for (int appId : mPowerWhitelistedAllAppIds) {
1311 proto.write(ForceAppStandbyTrackerProto.POWER_SAVE_WHITELIST_APP_IDS, appId);
1312 }
1313
1314 for (int appId : mTempWhitelistedAppIds) {
1315 proto.write(ForceAppStandbyTrackerProto.TEMP_POWER_SAVE_WHITELIST_APP_IDS, appId);
1316 }
1317
Makoto Onukieb898f12018-01-23 15:26:27 -08001318 for (int i = 0; i < mExemptedPackages.size(); i++) {
1319 for (int j = 0; j < mExemptedPackages.sizeAt(i); j++) {
1320 final long token2 = proto.start(
1321 ForceAppStandbyTrackerProto.EXEMPTED_PACKAGES);
1322
1323 proto.write(ExemptedPackage.USER_ID, mExemptedPackages.keyAt(i));
1324 proto.write(ExemptedPackage.PACKAGE_NAME, mExemptedPackages.valueAt(i, j));
1325
1326 proto.end(token2);
1327 }
1328 }
1329
Makoto Onuki2206af32017-11-21 16:25:35 -08001330 for (Pair<Integer, String> uidAndPackage : mRunAnyRestrictedPackages) {
1331 final long token2 = proto.start(
1332 ForceAppStandbyTrackerProto.RUN_ANY_IN_BACKGROUND_RESTRICTED_PACKAGES);
1333 proto.write(RunAnyInBackgroundRestrictedPackages.UID, uidAndPackage.first);
1334 proto.write(RunAnyInBackgroundRestrictedPackages.PACKAGE_NAME,
1335 uidAndPackage.second);
1336 proto.end(token2);
1337 }
Makoto Onukieb898f12018-01-23 15:26:27 -08001338
1339 mStatLogger.dumpProto(proto, ForceAppStandbyTrackerProto.STATS);
1340
Makoto Onuki2206af32017-11-21 16:25:35 -08001341 proto.end(token);
Makoto Onuki9be01402017-11-10 13:22:26 -08001342 }
1343 }
1344}