blob: 2affb74b485cf9c4799521015df5ca95e3c10313 [file] [log] [blame]
Makoto Onuki9be01402017-11-10 13:22:26 -08001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.server;
17
18import android.annotation.NonNull;
Makoto Onuki9be01402017-11-10 13:22:26 -080019import android.app.ActivityManager;
Makoto Onuki15407842018-01-19 14:23:11 -080020import android.app.ActivityManagerInternal;
Makoto Onuki9be01402017-11-10 13:22:26 -080021import android.app.AppOpsManager;
22import android.app.AppOpsManager.PackageOps;
Makoto Onuki2206af32017-11-21 16:25:35 -080023import android.app.IActivityManager;
Makoto Onuki9be01402017-11-10 13:22:26 -080024import android.app.IUidObserver;
Makoto Onukieb898f12018-01-23 15:26:27 -080025import android.app.usage.UsageStatsManager;
26import android.app.usage.UsageStatsManagerInternal;
27import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener;
Makoto Onuki2206af32017-11-21 16:25:35 -080028import android.content.BroadcastReceiver;
Makoto Onuki9be01402017-11-10 13:22:26 -080029import android.content.Context;
Makoto Onuki2206af32017-11-21 16:25:35 -080030import android.content.Intent;
31import android.content.IntentFilter;
Suprabh Shukla4deb8522018-01-08 16:27:10 -080032import android.database.ContentObserver;
Nancy Zheng525aaa12018-01-12 11:45:37 -080033import android.net.Uri;
34import android.os.BatteryManager;
Makoto Onuki9be01402017-11-10 13:22:26 -080035import android.os.Handler;
Makoto Onuki2206af32017-11-21 16:25:35 -080036import android.os.Looper;
37import android.os.Message;
Makoto Onuki9be01402017-11-10 13:22:26 -080038import android.os.PowerManager.ServiceType;
39import android.os.PowerManagerInternal;
40import android.os.RemoteException;
41import android.os.ServiceManager;
42import android.os.UserHandle;
Suprabh Shukla4deb8522018-01-08 16:27:10 -080043import android.provider.Settings;
Makoto Onuki9be01402017-11-10 13:22:26 -080044import android.util.ArraySet;
45import android.util.Pair;
Suprabh Shukla4deb8522018-01-08 16:27:10 -080046import android.util.Slog;
Makoto Onuki9be01402017-11-10 13:22:26 -080047import android.util.SparseBooleanArray;
Makoto Onukieb898f12018-01-23 15:26:27 -080048import android.util.SparseSetArray;
Makoto Onuki2206af32017-11-21 16:25:35 -080049import android.util.proto.ProtoOutputStream;
Makoto Onuki9be01402017-11-10 13:22:26 -080050
51import com.android.internal.annotations.GuardedBy;
Makoto Onuki2206af32017-11-21 16:25:35 -080052import com.android.internal.annotations.VisibleForTesting;
Makoto Onuki9be01402017-11-10 13:22:26 -080053import com.android.internal.app.IAppOpsCallback;
54import com.android.internal.app.IAppOpsService;
Makoto Onuki2206af32017-11-21 16:25:35 -080055import com.android.internal.util.ArrayUtils;
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -070056import com.android.internal.util.IndentingPrintWriter;
Makoto Onuki9be01402017-11-10 13:22:26 -080057import com.android.internal.util.Preconditions;
Makoto Onukieb898f12018-01-23 15:26:27 -080058import com.android.server.ForceAppStandbyTrackerProto.ExemptedPackage;
Makoto Onuki2206af32017-11-21 16:25:35 -080059import com.android.server.ForceAppStandbyTrackerProto.RunAnyInBackgroundRestrictedPackages;
Makoto Onuki9be01402017-11-10 13:22:26 -080060
Makoto Onuki2206af32017-11-21 16:25:35 -080061import java.io.PrintWriter;
62import java.util.Arrays;
Makoto Onuki9be01402017-11-10 13:22:26 -080063import java.util.List;
64
65/**
Makoto Onuki2206af32017-11-21 16:25:35 -080066 * Class to keep track of the information related to "force app standby", which includes:
67 * - OP_RUN_ANY_IN_BACKGROUND for each package
Makoto Onukiadb50d82018-01-29 16:20:30 -080068 * - UID foreground/active state
Makoto Onuki2206af32017-11-21 16:25:35 -080069 * - User+system power save whitelist
70 * - Temporary power save whitelist
71 * - Global "force all apps standby" mode enforced by battery saver.
Makoto Onuki9be01402017-11-10 13:22:26 -080072 *
Makoto Onukiadb50d82018-01-29 16:20:30 -080073 * TODO: Make it a LocalService.
Makoto Onuki2206af32017-11-21 16:25:35 -080074 *
75 * Test:
Makoto Onukie4918212018-02-06 11:30:15 -080076 atest $ANDROID_BUILD_TOP/frameworks/base/services/tests/servicestests/src/com/android/server/AppStateTrackerTest.java
Makoto Onuki9be01402017-11-10 13:22:26 -080077 */
Makoto Onukie4918212018-02-06 11:30:15 -080078public class AppStateTracker {
Makoto Onuki9be01402017-11-10 13:22:26 -080079 private static final String TAG = "ForceAppStandbyTracker";
Makoto Onukieb898f12018-01-23 15:26:27 -080080 private static final boolean DEBUG = true;
Makoto Onuki9be01402017-11-10 13:22:26 -080081
Makoto Onukie4918212018-02-06 11:30:15 -080082 @GuardedBy("AppStateTracker.class")
83 private static AppStateTracker sInstance;
Makoto Onuki9be01402017-11-10 13:22:26 -080084
85 private final Object mLock = new Object();
86 private final Context mContext;
87
Makoto Onuki2206af32017-11-21 16:25:35 -080088 @VisibleForTesting
89 static final int TARGET_OP = AppOpsManager.OP_RUN_ANY_IN_BACKGROUND;
90
91 IActivityManager mIActivityManager;
Makoto Onukie4918212018-02-06 11:30:15 -080092 ActivityManagerInternal mActivityManagerInternal;
Makoto Onuki9be01402017-11-10 13:22:26 -080093 AppOpsManager mAppOpsManager;
94 IAppOpsService mAppOpsService;
95 PowerManagerInternal mPowerManagerInternal;
Makoto Onukieb898f12018-01-23 15:26:27 -080096 StandbyTracker mStandbyTracker;
97 UsageStatsManagerInternal mUsageStatsManagerInternal;
Makoto Onuki9be01402017-11-10 13:22:26 -080098
Makoto Onuki2206af32017-11-21 16:25:35 -080099 private final MyHandler mHandler;
Makoto Onuki9be01402017-11-10 13:22:26 -0800100
Nancy Zheng525aaa12018-01-12 11:45:37 -0800101 @VisibleForTesting
102 FeatureFlagsObserver mFlagsObserver;
103
Makoto Onuki9be01402017-11-10 13:22:26 -0800104 /**
105 * Pair of (uid (not user-id), packageName) with OP_RUN_ANY_IN_BACKGROUND *not* allowed.
106 */
107 @GuardedBy("mLock")
Makoto Onuki2206af32017-11-21 16:25:35 -0800108 final ArraySet<Pair<Integer, String>> mRunAnyRestrictedPackages = new ArraySet<>();
Makoto Onuki9be01402017-11-10 13:22:26 -0800109
Makoto Onukiadb50d82018-01-29 16:20:30 -0800110 /** UIDs that are active. */
111 @GuardedBy("mLock")
112 final SparseBooleanArray mActiveUids = new SparseBooleanArray();
113
114 /** UIDs that are in the foreground. */
Makoto Onuki9be01402017-11-10 13:22:26 -0800115 @GuardedBy("mLock")
116 final SparseBooleanArray mForegroundUids = new SparseBooleanArray();
117
Makoto Onuki71755c92018-01-16 14:15:44 -0800118 /**
119 * System except-idle + user whitelist in the device idle controller.
120 */
Makoto Onuki9be01402017-11-10 13:22:26 -0800121 @GuardedBy("mLock")
Makoto Onuki2206af32017-11-21 16:25:35 -0800122 private int[] mPowerWhitelistedAllAppIds = new int[0];
123
124 @GuardedBy("mLock")
125 private int[] mTempWhitelistedAppIds = mPowerWhitelistedAllAppIds;
126
Makoto Onukieb898f12018-01-23 15:26:27 -0800127 /**
128 * Per-user packages that are in the EXEMPT bucket.
129 */
130 @GuardedBy("mLock")
131 private final SparseSetArray<String> mExemptedPackages = new SparseSetArray<>();
132
Makoto Onuki2206af32017-11-21 16:25:35 -0800133 @GuardedBy("mLock")
Makoto Onuki9be01402017-11-10 13:22:26 -0800134 final ArraySet<Listener> mListeners = new ArraySet<>();
135
136 @GuardedBy("mLock")
137 boolean mStarted;
138
Nancy Zheng525aaa12018-01-12 11:45:37 -0800139 /**
140 * Only used for small battery use-case.
141 */
Makoto Onuki9be01402017-11-10 13:22:26 -0800142 @GuardedBy("mLock")
Nancy Zheng525aaa12018-01-12 11:45:37 -0800143 boolean mIsPluggedIn;
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800144
145 @GuardedBy("mLock")
Nancy Zheng525aaa12018-01-12 11:45:37 -0800146 boolean mBatterySaverEnabled;
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800147
Nancy Zheng525aaa12018-01-12 11:45:37 -0800148 /**
149 * True if the forced app standby is currently enabled
150 */
151 @GuardedBy("mLock")
152 boolean mForceAllAppsStandby;
153
154 /**
155 * True if the forced app standby for small battery devices feature is enabled in settings
156 */
157 @GuardedBy("mLock")
158 boolean mForceAllAppStandbyForSmallBattery;
159
160 /**
161 * True if the forced app standby feature is enabled in settings
162 */
163 @GuardedBy("mLock")
164 boolean mForcedAppStandbyEnabled;
165
Makoto Onukieb898f12018-01-23 15:26:27 -0800166 interface Stats {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800167 int UID_FG_STATE_CHANGED = 0;
168 int UID_ACTIVE_STATE_CHANGED = 1;
169 int RUN_ANY_CHANGED = 2;
170 int ALL_UNWHITELISTED = 3;
171 int ALL_WHITELIST_CHANGED = 4;
172 int TEMP_WHITELIST_CHANGED = 5;
173 int EXEMPT_CHANGED = 6;
174 int FORCE_ALL_CHANGED = 7;
175 int FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED = 8;
Makoto Onukie4918212018-02-06 11:30:15 -0800176
177 int IS_UID_ACTIVE_CACHED = 9;
178 int IS_UID_ACTIVE_RAW = 10;
Makoto Onukieb898f12018-01-23 15:26:27 -0800179 }
180
181 private final StatLogger mStatLogger = new StatLogger(new String[] {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800182 "UID_FG_STATE_CHANGED",
183 "UID_ACTIVE_STATE_CHANGED",
Makoto Onukieb898f12018-01-23 15:26:27 -0800184 "RUN_ANY_CHANGED",
185 "ALL_UNWHITELISTED",
186 "ALL_WHITELIST_CHANGED",
187 "TEMP_WHITELIST_CHANGED",
188 "EXEMPT_CHANGED",
189 "FORCE_ALL_CHANGED",
190 "FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED",
Makoto Onukie4918212018-02-06 11:30:15 -0800191
192 "IS_UID_ACTIVE_CACHED",
193 "IS_UID_ACTIVE_RAW",
Makoto Onukieb898f12018-01-23 15:26:27 -0800194 });
195
Nancy Zheng525aaa12018-01-12 11:45:37 -0800196 @VisibleForTesting
197 class FeatureFlagsObserver extends ContentObserver {
198 FeatureFlagsObserver() {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800199 super(null);
200 }
201
202 void register() {
203 mContext.getContentResolver().registerContentObserver(
204 Settings.Global.getUriFor(Settings.Global.FORCED_APP_STANDBY_ENABLED),
205 false, this);
Nancy Zheng525aaa12018-01-12 11:45:37 -0800206
207 mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor(
208 Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED), false, this);
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800209 }
210
211 boolean isForcedAppStandbyEnabled() {
Makoto Onukieb898f12018-01-23 15:26:27 -0800212 return injectGetGlobalSettingInt(Settings.Global.FORCED_APP_STANDBY_ENABLED, 1) == 1;
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800213 }
214
Nancy Zheng525aaa12018-01-12 11:45:37 -0800215 boolean isForcedAppStandbyForSmallBatteryEnabled() {
Makoto Onukieb898f12018-01-23 15:26:27 -0800216 return injectGetGlobalSettingInt(
Nancy Zheng525aaa12018-01-12 11:45:37 -0800217 Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED, 0) == 1;
218 }
219
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800220 @Override
Nancy Zheng525aaa12018-01-12 11:45:37 -0800221 public void onChange(boolean selfChange, Uri uri) {
222 if (Settings.Global.getUriFor(Settings.Global.FORCED_APP_STANDBY_ENABLED).equals(uri)) {
223 final boolean enabled = isForcedAppStandbyEnabled();
224 synchronized (mLock) {
225 if (mForcedAppStandbyEnabled == enabled) {
226 return;
227 }
228 mForcedAppStandbyEnabled = enabled;
229 if (DEBUG) {
230 Slog.d(TAG,"Forced app standby feature flag changed: "
231 + mForcedAppStandbyEnabled);
232 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800233 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800234 mHandler.notifyForcedAppStandbyFeatureFlagChanged();
235 } else if (Settings.Global.getUriFor(
236 Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED).equals(uri)) {
237 final boolean enabled = isForcedAppStandbyForSmallBatteryEnabled();
238 synchronized (mLock) {
239 if (mForceAllAppStandbyForSmallBattery == enabled) {
240 return;
241 }
242 mForceAllAppStandbyForSmallBattery = enabled;
243 if (DEBUG) {
244 Slog.d(TAG, "Forced app standby for small battery feature flag changed: "
245 + mForceAllAppStandbyForSmallBattery);
246 }
247 updateForceAllAppStandbyState();
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800248 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800249 } else {
250 Slog.w(TAG, "Unexpected feature flag uri encountered: " + uri);
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800251 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800252 }
253 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800254
255 public static abstract class Listener {
Makoto Onuki2206af32017-11-21 16:25:35 -0800256 /**
257 * This is called when the OP_RUN_ANY_IN_BACKGROUND appops changed for a package.
258 */
Makoto Onukie4918212018-02-06 11:30:15 -0800259 private void onRunAnyAppOpsChanged(AppStateTracker sender,
Makoto Onuki2206af32017-11-21 16:25:35 -0800260 int uid, @NonNull String packageName) {
Christopher Tate20afddd2018-02-28 15:19:19 -0800261 updateJobsForUidPackage(uid, packageName, sender.isUidActive(uid));
Makoto Onuki2206af32017-11-21 16:25:35 -0800262
Suprabh Shuklac25447d2018-01-19 16:43:35 -0800263 if (!sender.areAlarmsRestricted(uid, packageName, /*allowWhileIdle=*/ false)) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800264 unblockAlarmsForUidPackage(uid, packageName);
Suprabh Shuklac25447d2018-01-19 16:43:35 -0800265 } else if (!sender.areAlarmsRestricted(uid, packageName, /*allowWhileIdle=*/ true)){
266 // we need to deliver the allow-while-idle alarms for this uid, package
267 unblockAllUnrestrictedAlarms();
Makoto Onuki2206af32017-11-21 16:25:35 -0800268 }
Christopher Tatec7933ac2018-03-12 17:57:09 -0700269
270 if (!sender.isRunAnyInBackgroundAppOpsAllowed(uid, packageName)) {
271 Slog.v(TAG, "Package " + packageName + "/" + uid
272 + " toggled into fg service restriction");
273 stopForegroundServicesForUidPackage(uid, packageName);
274 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800275 }
276
Makoto Onuki2206af32017-11-21 16:25:35 -0800277 /**
278 * This is called when the foreground state changed for a UID.
279 */
Makoto Onukie4918212018-02-06 11:30:15 -0800280 private void onUidForegroundStateChanged(AppStateTracker sender, int uid) {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800281 onUidForeground(uid, sender.isUidInForeground(uid));
282 }
283
284 /**
285 * This is called when the active/idle state changed for a UID.
286 */
Makoto Onukie4918212018-02-06 11:30:15 -0800287 private void onUidActiveStateChanged(AppStateTracker sender, int uid) {
Christopher Tate20afddd2018-02-28 15:19:19 -0800288 final boolean isActive = sender.isUidActive(uid);
Makoto Onuki2206af32017-11-21 16:25:35 -0800289
Christopher Tate20afddd2018-02-28 15:19:19 -0800290 updateJobsForUid(uid, isActive);
291
292 if (isActive) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800293 unblockAlarmsForUid(uid);
294 }
295 }
296
297 /**
298 * This is called when an app-id(s) is removed from the power save whitelist.
299 */
Makoto Onukie4918212018-02-06 11:30:15 -0800300 private void onPowerSaveUnwhitelisted(AppStateTracker sender) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800301 updateAllJobs();
302 unblockAllUnrestrictedAlarms();
303 }
304
305 /**
306 * This is called when the power save whitelist changes, excluding the
307 * {@link #onPowerSaveUnwhitelisted} case.
308 */
Makoto Onukie4918212018-02-06 11:30:15 -0800309 private void onPowerSaveWhitelistedChanged(AppStateTracker sender) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800310 updateAllJobs();
311 }
312
313 /**
314 * This is called when the temp whitelist changes.
315 */
Makoto Onukie4918212018-02-06 11:30:15 -0800316 private void onTempPowerSaveWhitelistChanged(AppStateTracker sender) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800317
318 // TODO This case happens rather frequently; consider optimizing and update jobs
319 // only for affected app-ids.
320
321 updateAllJobs();
Makoto Onukieb898f12018-01-23 15:26:27 -0800322
323 // Note when an app is just put in the temp whitelist, we do *not* drain pending alarms.
324 }
325
326 /**
327 * This is called when the EXEMPT bucket is updated.
328 */
Makoto Onukie4918212018-02-06 11:30:15 -0800329 private void onExemptChanged(AppStateTracker sender) {
Makoto Onukieb898f12018-01-23 15:26:27 -0800330 // This doesn't happen very often, so just re-evaluate all jobs / alarms.
331 updateAllJobs();
332 unblockAllUnrestrictedAlarms();
Makoto Onuki2206af32017-11-21 16:25:35 -0800333 }
334
335 /**
336 * This is called when the global "force all apps standby" flag changes.
337 */
Makoto Onukie4918212018-02-06 11:30:15 -0800338 private void onForceAllAppsStandbyChanged(AppStateTracker sender) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800339 updateAllJobs();
340
341 if (!sender.isForceAllAppsStandbyEnabled()) {
342 unblockAllUnrestrictedAlarms();
343 }
344 }
345
346 /**
347 * Called when the job restrictions for multiple UIDs might have changed, so the job
348 * scheduler should re-evaluate all restrictions for all jobs.
349 */
350 public void updateAllJobs() {
351 }
352
353 /**
354 * Called when the job restrictions for a UID might have changed, so the job
355 * scheduler should re-evaluate all restrictions for all jobs.
356 */
Christopher Tate20afddd2018-02-28 15:19:19 -0800357 public void updateJobsForUid(int uid, boolean isNowActive) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800358 }
359
360 /**
361 * Called when the job restrictions for a UID - package might have changed, so the job
362 * scheduler should re-evaluate all restrictions for all jobs.
363 */
Christopher Tate20afddd2018-02-28 15:19:19 -0800364 public void updateJobsForUidPackage(int uid, String packageName, boolean isNowActive) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800365 }
366
367 /**
Christopher Tatec7933ac2018-03-12 17:57:09 -0700368 * Called when an app goes into forced app standby and its foreground
369 * services need to be removed from that state.
370 */
371 public void stopForegroundServicesForUidPackage(int uid, String packageName) {
372 }
373
374 /**
Makoto Onuki2206af32017-11-21 16:25:35 -0800375 * Called when the job restrictions for multiple UIDs might have changed, so the alarm
376 * manager should re-evaluate all restrictions for all blocked jobs.
377 */
378 public void unblockAllUnrestrictedAlarms() {
379 }
380
381 /**
382 * Called when all jobs for a specific UID are unblocked.
383 */
384 public void unblockAlarmsForUid(int uid) {
385 }
386
387 /**
388 * Called when all alarms for a specific UID - package are unblocked.
389 */
390 public void unblockAlarmsForUidPackage(int uid, String packageName) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800391 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800392
393 /**
394 * Called when a UID comes into the foreground or the background.
395 *
396 * @see #isUidInForeground(int)
397 */
398 public void onUidForeground(int uid, boolean foreground) {
399 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800400 }
401
Makoto Onukie4918212018-02-06 11:30:15 -0800402 public AppStateTracker(Context context, Looper looper) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800403 mContext = context;
Makoto Onuki2206af32017-11-21 16:25:35 -0800404 mHandler = new MyHandler(looper);
405 }
406
Makoto Onuki9be01402017-11-10 13:22:26 -0800407 /**
408 * Call it when the system is ready.
409 */
Makoto Onukie4918212018-02-06 11:30:15 -0800410 public void onSystemServicesReady() {
Makoto Onuki9be01402017-11-10 13:22:26 -0800411 synchronized (mLock) {
412 if (mStarted) {
413 return;
414 }
415 mStarted = true;
416
Makoto Onuki2206af32017-11-21 16:25:35 -0800417 mIActivityManager = Preconditions.checkNotNull(injectIActivityManager());
Makoto Onukie4918212018-02-06 11:30:15 -0800418 mActivityManagerInternal = Preconditions.checkNotNull(injectActivityManagerInternal());
Makoto Onuki2206af32017-11-21 16:25:35 -0800419 mAppOpsManager = Preconditions.checkNotNull(injectAppOpsManager());
420 mAppOpsService = Preconditions.checkNotNull(injectIAppOpsService());
421 mPowerManagerInternal = Preconditions.checkNotNull(injectPowerManagerInternal());
Makoto Onukieb898f12018-01-23 15:26:27 -0800422 mUsageStatsManagerInternal = Preconditions.checkNotNull(
423 injectUsageStatsManagerInternal());
424
Nancy Zheng525aaa12018-01-12 11:45:37 -0800425 mFlagsObserver = new FeatureFlagsObserver();
426 mFlagsObserver.register();
427 mForcedAppStandbyEnabled = mFlagsObserver.isForcedAppStandbyEnabled();
428 mForceAllAppStandbyForSmallBattery =
429 mFlagsObserver.isForcedAppStandbyForSmallBatteryEnabled();
Makoto Onukieb898f12018-01-23 15:26:27 -0800430 mStandbyTracker = new StandbyTracker();
431 mUsageStatsManagerInternal.addAppIdleStateChangeListener(mStandbyTracker);
Makoto Onuki9be01402017-11-10 13:22:26 -0800432
433 try {
Makoto Onuki2206af32017-11-21 16:25:35 -0800434 mIActivityManager.registerUidObserver(new UidObserver(),
Makoto Onukiadb50d82018-01-29 16:20:30 -0800435 ActivityManager.UID_OBSERVER_GONE
436 | ActivityManager.UID_OBSERVER_IDLE
437 | ActivityManager.UID_OBSERVER_ACTIVE
438 | ActivityManager.UID_OBSERVER_PROCSTATE,
Makoto Onuki9be01402017-11-10 13:22:26 -0800439 ActivityManager.PROCESS_STATE_UNKNOWN, null);
Makoto Onuki2206af32017-11-21 16:25:35 -0800440 mAppOpsService.startWatchingMode(TARGET_OP, null,
Makoto Onuki9be01402017-11-10 13:22:26 -0800441 new AppOpsWatcher());
442 } catch (RemoteException e) {
443 // shouldn't happen.
444 }
445
Makoto Onuki2206af32017-11-21 16:25:35 -0800446 IntentFilter filter = new IntentFilter();
447 filter.addAction(Intent.ACTION_USER_REMOVED);
Nancy Zheng525aaa12018-01-12 11:45:37 -0800448 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800449 mContext.registerReceiver(new MyReceiver(), filter);
Makoto Onuki9be01402017-11-10 13:22:26 -0800450
451 refreshForcedAppStandbyUidPackagesLocked();
Makoto Onuki2206af32017-11-21 16:25:35 -0800452
453 mPowerManagerInternal.registerLowPowerModeObserver(
454 ServiceType.FORCE_ALL_APPS_STANDBY,
Nancy Zheng525aaa12018-01-12 11:45:37 -0800455 (state) -> {
456 synchronized (mLock) {
457 mBatterySaverEnabled = state.batterySaverEnabled;
458 updateForceAllAppStandbyState();
459 }
460 });
Makoto Onuki2206af32017-11-21 16:25:35 -0800461
Nancy Zheng525aaa12018-01-12 11:45:37 -0800462 mBatterySaverEnabled = mPowerManagerInternal.getLowPowerState(
463 ServiceType.FORCE_ALL_APPS_STANDBY).batterySaverEnabled;
464
465 updateForceAllAppStandbyState();
Makoto Onuki9be01402017-11-10 13:22:26 -0800466 }
467 }
468
Makoto Onuki2206af32017-11-21 16:25:35 -0800469 @VisibleForTesting
470 AppOpsManager injectAppOpsManager() {
471 return mContext.getSystemService(AppOpsManager.class);
472 }
473
474 @VisibleForTesting
475 IAppOpsService injectIAppOpsService() {
476 return IAppOpsService.Stub.asInterface(
477 ServiceManager.getService(Context.APP_OPS_SERVICE));
478 }
479
480 @VisibleForTesting
481 IActivityManager injectIActivityManager() {
482 return ActivityManager.getService();
483 }
484
485 @VisibleForTesting
Makoto Onukie4918212018-02-06 11:30:15 -0800486 ActivityManagerInternal injectActivityManagerInternal() {
487 return LocalServices.getService(ActivityManagerInternal.class);
488 }
489
490 @VisibleForTesting
Makoto Onuki2206af32017-11-21 16:25:35 -0800491 PowerManagerInternal injectPowerManagerInternal() {
492 return LocalServices.getService(PowerManagerInternal.class);
493 }
494
Nancy Zheng525aaa12018-01-12 11:45:37 -0800495 @VisibleForTesting
Makoto Onukieb898f12018-01-23 15:26:27 -0800496 UsageStatsManagerInternal injectUsageStatsManagerInternal() {
497 return LocalServices.getService(UsageStatsManagerInternal.class);
498 }
499
500 @VisibleForTesting
Nancy Zheng525aaa12018-01-12 11:45:37 -0800501 boolean isSmallBatteryDevice() {
502 return ActivityManager.isSmallBatteryDevice();
503 }
504
Makoto Onukieb898f12018-01-23 15:26:27 -0800505 @VisibleForTesting
506 int injectGetGlobalSettingInt(String key, int def) {
507 return Settings.Global.getInt(mContext.getContentResolver(), key, def);
508 }
509
Makoto Onuki9be01402017-11-10 13:22:26 -0800510 /**
Makoto Onuki2206af32017-11-21 16:25:35 -0800511 * Update {@link #mRunAnyRestrictedPackages} with the current app ops state.
Makoto Onuki9be01402017-11-10 13:22:26 -0800512 */
Andreas Gampea36dc622018-02-05 17:19:22 -0800513 @GuardedBy("mLock")
Makoto Onuki9be01402017-11-10 13:22:26 -0800514 private void refreshForcedAppStandbyUidPackagesLocked() {
Makoto Onuki2206af32017-11-21 16:25:35 -0800515 mRunAnyRestrictedPackages.clear();
516 final List<PackageOps> ops = mAppOpsManager.getPackagesForOps(
517 new int[] {TARGET_OP});
Makoto Onuki9be01402017-11-10 13:22:26 -0800518
519 if (ops == null) {
520 return;
521 }
522 final int size = ops.size();
523 for (int i = 0; i < size; i++) {
524 final AppOpsManager.PackageOps pkg = ops.get(i);
525 final List<AppOpsManager.OpEntry> entries = ops.get(i).getOps();
526
527 for (int j = 0; j < entries.size(); j++) {
528 AppOpsManager.OpEntry ent = entries.get(j);
Makoto Onuki2206af32017-11-21 16:25:35 -0800529 if (ent.getOp() != TARGET_OP) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800530 continue;
531 }
532 if (ent.getMode() != AppOpsManager.MODE_ALLOWED) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800533 mRunAnyRestrictedPackages.add(Pair.create(
Makoto Onuki9be01402017-11-10 13:22:26 -0800534 pkg.getUid(), pkg.getPackageName()));
535 }
536 }
537 }
538 }
539
Nancy Zheng525aaa12018-01-12 11:45:37 -0800540 private void updateForceAllAppStandbyState() {
541 synchronized (mLock) {
542 if (mForceAllAppStandbyForSmallBattery && isSmallBatteryDevice()) {
543 toggleForceAllAppsStandbyLocked(!mIsPluggedIn);
544 } else {
545 toggleForceAllAppsStandbyLocked(mBatterySaverEnabled);
546 }
547 }
548 }
549
Makoto Onuki2206af32017-11-21 16:25:35 -0800550 /**
551 * Update {@link #mForceAllAppsStandby} and notifies the listeners.
552 */
Andreas Gampea36dc622018-02-05 17:19:22 -0800553 @GuardedBy("mLock")
Nancy Zheng525aaa12018-01-12 11:45:37 -0800554 private void toggleForceAllAppsStandbyLocked(boolean enable) {
555 if (enable == mForceAllAppsStandby) {
556 return;
Makoto Onuki12391f22018-01-18 21:44:28 +0000557 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800558 mForceAllAppsStandby = enable;
559
560 mHandler.notifyForceAllAppsStandbyChanged();
Makoto Onuki9be01402017-11-10 13:22:26 -0800561 }
562
Andreas Gampea36dc622018-02-05 17:19:22 -0800563 @GuardedBy("mLock")
Makoto Onuki9be01402017-11-10 13:22:26 -0800564 private int findForcedAppStandbyUidPackageIndexLocked(int uid, @NonNull String packageName) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800565 final int size = mRunAnyRestrictedPackages.size();
566 if (size > 8) {
567 return mRunAnyRestrictedPackages.indexOf(Pair.create(uid, packageName));
568 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800569 for (int i = 0; i < size; i++) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800570 final Pair<Integer, String> pair = mRunAnyRestrictedPackages.valueAt(i);
Makoto Onuki9be01402017-11-10 13:22:26 -0800571
572 if ((pair.first == uid) && packageName.equals(pair.second)) {
573 return i;
574 }
575 }
576 return -1;
577 }
578
579 /**
Makoto Onuki2206af32017-11-21 16:25:35 -0800580 * @return whether a uid package-name pair is in mRunAnyRestrictedPackages.
Makoto Onuki9be01402017-11-10 13:22:26 -0800581 */
Andreas Gampea36dc622018-02-05 17:19:22 -0800582 @GuardedBy("mLock")
Makoto Onuki2206af32017-11-21 16:25:35 -0800583 boolean isRunAnyRestrictedLocked(int uid, @NonNull String packageName) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800584 return findForcedAppStandbyUidPackageIndexLocked(uid, packageName) >= 0;
585 }
586
Makoto Onuki2206af32017-11-21 16:25:35 -0800587 /**
588 * Add to / remove from {@link #mRunAnyRestrictedPackages}.
589 */
Andreas Gampea36dc622018-02-05 17:19:22 -0800590 @GuardedBy("mLock")
Makoto Onuki2206af32017-11-21 16:25:35 -0800591 boolean updateForcedAppStandbyUidPackageLocked(int uid, @NonNull String packageName,
Makoto Onuki9be01402017-11-10 13:22:26 -0800592 boolean restricted) {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800593 final int index = findForcedAppStandbyUidPackageIndexLocked(uid, packageName);
Makoto Onuki9be01402017-11-10 13:22:26 -0800594 final boolean wasRestricted = index >= 0;
595 if (wasRestricted == restricted) {
596 return false;
597 }
598 if (restricted) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800599 mRunAnyRestrictedPackages.add(Pair.create(uid, packageName));
Makoto Onuki9be01402017-11-10 13:22:26 -0800600 } else {
Makoto Onuki2206af32017-11-21 16:25:35 -0800601 mRunAnyRestrictedPackages.removeAt(index);
Makoto Onuki9be01402017-11-10 13:22:26 -0800602 }
603 return true;
604 }
605
Makoto Onukiadb50d82018-01-29 16:20:30 -0800606 private static boolean addUidToArray(SparseBooleanArray array, int uid) {
607 if (UserHandle.isCore(uid)) {
608 return false;
Makoto Onuki9be01402017-11-10 13:22:26 -0800609 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800610 if (array.get(uid)) {
611 return false;
612 }
613 array.put(uid, true);
614 return true;
Makoto Onuki9be01402017-11-10 13:22:26 -0800615 }
616
Makoto Onukiadb50d82018-01-29 16:20:30 -0800617 private static boolean removeUidFromArray(SparseBooleanArray array, int uid, boolean remove) {
618 if (UserHandle.isCore(uid)) {
619 return false;
Makoto Onuki9be01402017-11-10 13:22:26 -0800620 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800621 if (!array.get(uid)) {
622 return false;
623 }
624 if (remove) {
625 array.delete(uid);
626 } else {
627 array.put(uid, false);
628 }
629 return true;
Makoto Onuki9be01402017-11-10 13:22:26 -0800630 }
631
Makoto Onuki2206af32017-11-21 16:25:35 -0800632 private final class UidObserver extends IUidObserver.Stub {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800633 @Override
634 public void onUidStateChanged(int uid, int procState, long procStateSeq) {
Makoto Onuki4d298b52018-02-05 10:54:58 -0800635 mHandler.onUidStateChanged(uid, procState);
Makoto Onuki9be01402017-11-10 13:22:26 -0800636 }
637
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800638 @Override
639 public void onUidActive(int uid) {
Makoto Onuki4d298b52018-02-05 10:54:58 -0800640 mHandler.onUidActive(uid);
641 }
642
643 @Override
644 public void onUidGone(int uid, boolean disabled) {
645 mHandler.onUidGone(uid, disabled);
Makoto Onuki9be01402017-11-10 13:22:26 -0800646 }
647
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800648 @Override
649 public void onUidIdle(int uid, boolean disabled) {
Makoto Onuki4d298b52018-02-05 10:54:58 -0800650 mHandler.onUidIdle(uid, disabled);
Makoto Onuki9be01402017-11-10 13:22:26 -0800651 }
652
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800653 @Override
654 public void onUidCachedChanged(int uid, boolean cached) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800655 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800656 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800657
658 private final class AppOpsWatcher extends IAppOpsCallback.Stub {
659 @Override
660 public void opChanged(int op, int uid, String packageName) throws RemoteException {
Makoto Onuki2206af32017-11-21 16:25:35 -0800661 boolean restricted = false;
662 try {
663 restricted = mAppOpsService.checkOperation(TARGET_OP,
664 uid, packageName) != AppOpsManager.MODE_ALLOWED;
665 } catch (RemoteException e) {
666 // Shouldn't happen
667 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800668 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800669 if (updateForcedAppStandbyUidPackageLocked(uid, packageName, restricted)) {
670 mHandler.notifyRunAnyAppOpsChanged(uid, packageName);
671 }
672 }
673 }
674 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800675
Makoto Onuki2206af32017-11-21 16:25:35 -0800676 private final class MyReceiver extends BroadcastReceiver {
677 @Override
678 public void onReceive(Context context, Intent intent) {
679 if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
680 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
681 if (userId > 0) {
682 mHandler.doUserRemoved(userId);
Makoto Onuki9be01402017-11-10 13:22:26 -0800683 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800684 } else if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
685 synchronized (mLock) {
686 mIsPluggedIn = (intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0);
687 }
688 updateForceAllAppStandbyState();
Makoto Onuki9be01402017-11-10 13:22:26 -0800689 }
690 }
691 }
692
Makoto Onukieb898f12018-01-23 15:26:27 -0800693 final class StandbyTracker extends AppIdleStateChangeListener {
694 @Override
695 public void onAppIdleStateChanged(String packageName, int userId, boolean idle,
Amith Yamasani119be9a2018-02-18 22:23:00 -0800696 int bucket, int reason) {
Makoto Onukieb898f12018-01-23 15:26:27 -0800697 if (DEBUG) {
698 Slog.d(TAG,"onAppIdleStateChanged: " + packageName + " u" + userId
699 + (idle ? " idle" : " active") + " " + bucket);
700 }
701 final boolean changed;
702 if (bucket == UsageStatsManager.STANDBY_BUCKET_EXEMPTED) {
703 changed = mExemptedPackages.add(userId, packageName);
704 } else {
705 changed = mExemptedPackages.remove(userId, packageName);
706 }
707 if (changed) {
708 mHandler.notifyExemptChanged();
709 }
710 }
711
712 @Override
713 public void onParoleStateChanged(boolean isParoleOn) {
714 }
715 }
716
Makoto Onuki9be01402017-11-10 13:22:26 -0800717 private Listener[] cloneListeners() {
718 synchronized (mLock) {
719 return mListeners.toArray(new Listener[mListeners.size()]);
720 }
721 }
722
Makoto Onuki2206af32017-11-21 16:25:35 -0800723 private class MyHandler extends Handler {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800724 private static final int MSG_UID_ACTIVE_STATE_CHANGED = 0;
725 private static final int MSG_UID_FG_STATE_CHANGED = 1;
726 private static final int MSG_RUN_ANY_CHANGED = 3;
727 private static final int MSG_ALL_UNWHITELISTED = 4;
728 private static final int MSG_ALL_WHITELIST_CHANGED = 5;
729 private static final int MSG_TEMP_WHITELIST_CHANGED = 6;
730 private static final int MSG_FORCE_ALL_CHANGED = 7;
731 private static final int MSG_USER_REMOVED = 8;
732 private static final int MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED = 9;
733 private static final int MSG_EXEMPT_CHANGED = 10;
Makoto Onuki9be01402017-11-10 13:22:26 -0800734
Makoto Onuki4d298b52018-02-05 10:54:58 -0800735 private static final int MSG_ON_UID_STATE_CHANGED = 11;
736 private static final int MSG_ON_UID_ACTIVE = 12;
737 private static final int MSG_ON_UID_GONE = 13;
738 private static final int MSG_ON_UID_IDLE = 14;
739
Makoto Onuki2206af32017-11-21 16:25:35 -0800740 public MyHandler(Looper looper) {
741 super(looper);
Makoto Onuki9be01402017-11-10 13:22:26 -0800742 }
Makoto Onuki2206af32017-11-21 16:25:35 -0800743
Makoto Onukiadb50d82018-01-29 16:20:30 -0800744 public void notifyUidActiveStateChanged(int uid) {
745 obtainMessage(MSG_UID_ACTIVE_STATE_CHANGED, uid, 0).sendToTarget();
746 }
747
Makoto Onuki2206af32017-11-21 16:25:35 -0800748 public void notifyUidForegroundStateChanged(int uid) {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800749 obtainMessage(MSG_UID_FG_STATE_CHANGED, uid, 0).sendToTarget();
Makoto Onuki2206af32017-11-21 16:25:35 -0800750 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800751
Makoto Onuki2206af32017-11-21 16:25:35 -0800752 public void notifyRunAnyAppOpsChanged(int uid, @NonNull String packageName) {
753 obtainMessage(MSG_RUN_ANY_CHANGED, uid, 0, packageName).sendToTarget();
754 }
755
756 public void notifyAllUnwhitelisted() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800757 removeMessages(MSG_ALL_UNWHITELISTED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800758 obtainMessage(MSG_ALL_UNWHITELISTED).sendToTarget();
759 }
760
761 public void notifyAllWhitelistChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800762 removeMessages(MSG_ALL_WHITELIST_CHANGED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800763 obtainMessage(MSG_ALL_WHITELIST_CHANGED).sendToTarget();
764 }
765
766 public void notifyTempWhitelistChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800767 removeMessages(MSG_TEMP_WHITELIST_CHANGED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800768 obtainMessage(MSG_TEMP_WHITELIST_CHANGED).sendToTarget();
769 }
770
771 public void notifyForceAllAppsStandbyChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800772 removeMessages(MSG_FORCE_ALL_CHANGED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800773 obtainMessage(MSG_FORCE_ALL_CHANGED).sendToTarget();
774 }
775
Nancy Zheng525aaa12018-01-12 11:45:37 -0800776 public void notifyForcedAppStandbyFeatureFlagChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800777 removeMessages(MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED);
Nancy Zheng525aaa12018-01-12 11:45:37 -0800778 obtainMessage(MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED).sendToTarget();
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800779 }
780
Makoto Onukieb898f12018-01-23 15:26:27 -0800781 public void notifyExemptChanged() {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800782 removeMessages(MSG_EXEMPT_CHANGED);
Makoto Onukieb898f12018-01-23 15:26:27 -0800783 obtainMessage(MSG_EXEMPT_CHANGED).sendToTarget();
784 }
785
Makoto Onuki2206af32017-11-21 16:25:35 -0800786 public void doUserRemoved(int userId) {
787 obtainMessage(MSG_USER_REMOVED, userId, 0).sendToTarget();
788 }
789
Makoto Onuki4d298b52018-02-05 10:54:58 -0800790 public void onUidStateChanged(int uid, int procState) {
791 obtainMessage(MSG_ON_UID_STATE_CHANGED, uid, procState).sendToTarget();
792 }
793
794 public void onUidActive(int uid) {
795 obtainMessage(MSG_ON_UID_ACTIVE, uid, 0).sendToTarget();
796 }
797
798 public void onUidGone(int uid, boolean disabled) {
799 obtainMessage(MSG_ON_UID_GONE, uid, disabled ? 1 : 0).sendToTarget();
800 }
801
802 public void onUidIdle(int uid, boolean disabled) {
803 obtainMessage(MSG_ON_UID_IDLE, uid, disabled ? 1 : 0).sendToTarget();
804 }
805
Makoto Onuki2206af32017-11-21 16:25:35 -0800806 @Override
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800807 public void handleMessage(Message msg) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800808 switch (msg.what) {
809 case MSG_USER_REMOVED:
810 handleUserRemoved(msg.arg1);
811 return;
812 }
813
814 // Only notify the listeners when started.
815 synchronized (mLock) {
816 if (!mStarted) {
817 return;
818 }
819 }
Makoto Onukie4918212018-02-06 11:30:15 -0800820 final AppStateTracker sender = AppStateTracker.this;
Makoto Onuki2206af32017-11-21 16:25:35 -0800821
Makoto Onukieb898f12018-01-23 15:26:27 -0800822 long start = mStatLogger.getTime();
Makoto Onuki2206af32017-11-21 16:25:35 -0800823 switch (msg.what) {
Makoto Onukiadb50d82018-01-29 16:20:30 -0800824 case MSG_UID_ACTIVE_STATE_CHANGED:
825 for (Listener l : cloneListeners()) {
826 l.onUidActiveStateChanged(sender, msg.arg1);
827 }
828 mStatLogger.logDurationStat(Stats.UID_ACTIVE_STATE_CHANGED, start);
829 return;
830
831 case MSG_UID_FG_STATE_CHANGED:
Makoto Onuki2206af32017-11-21 16:25:35 -0800832 for (Listener l : cloneListeners()) {
833 l.onUidForegroundStateChanged(sender, msg.arg1);
834 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800835 mStatLogger.logDurationStat(Stats.UID_FG_STATE_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800836 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800837
Makoto Onuki2206af32017-11-21 16:25:35 -0800838 case MSG_RUN_ANY_CHANGED:
839 for (Listener l : cloneListeners()) {
840 l.onRunAnyAppOpsChanged(sender, msg.arg1, (String) msg.obj);
841 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800842 mStatLogger.logDurationStat(Stats.RUN_ANY_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800843 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800844
Makoto Onuki2206af32017-11-21 16:25:35 -0800845 case MSG_ALL_UNWHITELISTED:
846 for (Listener l : cloneListeners()) {
847 l.onPowerSaveUnwhitelisted(sender);
848 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800849 mStatLogger.logDurationStat(Stats.ALL_UNWHITELISTED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800850 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800851
Makoto Onuki2206af32017-11-21 16:25:35 -0800852 case MSG_ALL_WHITELIST_CHANGED:
853 for (Listener l : cloneListeners()) {
854 l.onPowerSaveWhitelistedChanged(sender);
855 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800856 mStatLogger.logDurationStat(Stats.ALL_WHITELIST_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800857 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800858
Makoto Onuki2206af32017-11-21 16:25:35 -0800859 case MSG_TEMP_WHITELIST_CHANGED:
860 for (Listener l : cloneListeners()) {
861 l.onTempPowerSaveWhitelistChanged(sender);
862 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800863 mStatLogger.logDurationStat(Stats.TEMP_WHITELIST_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800864 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800865
866 case MSG_EXEMPT_CHANGED:
867 for (Listener l : cloneListeners()) {
868 l.onExemptChanged(sender);
869 }
870 mStatLogger.logDurationStat(Stats.EXEMPT_CHANGED, start);
871 return;
872
Makoto Onuki2206af32017-11-21 16:25:35 -0800873 case MSG_FORCE_ALL_CHANGED:
874 for (Listener l : cloneListeners()) {
875 l.onForceAllAppsStandbyChanged(sender);
876 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800877 mStatLogger.logDurationStat(Stats.FORCE_ALL_CHANGED, start);
Makoto Onuki2206af32017-11-21 16:25:35 -0800878 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800879
Nancy Zheng525aaa12018-01-12 11:45:37 -0800880 case MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED:
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800881 // Feature flag for forced app standby changed.
882 final boolean unblockAlarms;
883 synchronized (mLock) {
884 unblockAlarms = !mForcedAppStandbyEnabled && !mForceAllAppsStandby;
885 }
Suprabh Shuklac25447d2018-01-19 16:43:35 -0800886 for (Listener l : cloneListeners()) {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800887 l.updateAllJobs();
888 if (unblockAlarms) {
889 l.unblockAllUnrestrictedAlarms();
890 }
891 }
Makoto Onukieb898f12018-01-23 15:26:27 -0800892 mStatLogger.logDurationStat(
893 Stats.FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED, start);
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800894 return;
Makoto Onukieb898f12018-01-23 15:26:27 -0800895
Makoto Onuki2206af32017-11-21 16:25:35 -0800896 case MSG_USER_REMOVED:
897 handleUserRemoved(msg.arg1);
898 return;
Makoto Onuki4d298b52018-02-05 10:54:58 -0800899
900 case MSG_ON_UID_STATE_CHANGED:
901 handleUidStateChanged(msg.arg1, msg.arg2);
902 return;
903 case MSG_ON_UID_ACTIVE:
904 handleUidActive(msg.arg1);
905 return;
906 case MSG_ON_UID_GONE:
907 handleUidGone(msg.arg1, msg.arg1 != 0);
908 return;
909 case MSG_ON_UID_IDLE:
910 handleUidIdle(msg.arg1, msg.arg1 != 0);
911 return;
912 }
913 }
914
915 public void handleUidStateChanged(int uid, int procState) {
916 synchronized (mLock) {
917 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
918 if (removeUidFromArray(mForegroundUids, uid, false)) {
919 mHandler.notifyUidForegroundStateChanged(uid);
920 }
921 } else {
922 if (addUidToArray(mForegroundUids, uid)) {
923 mHandler.notifyUidForegroundStateChanged(uid);
924 }
925 }
926 }
927 }
928
929 public void handleUidActive(int uid) {
930 synchronized (mLock) {
931 if (addUidToArray(mActiveUids, uid)) {
932 mHandler.notifyUidActiveStateChanged(uid);
933 }
934 }
935 }
936
937 public void handleUidGone(int uid, boolean disabled) {
938 removeUid(uid, true);
939 }
940
941 public void handleUidIdle(int uid, boolean disabled) {
942 // Just to avoid excessive memcpy, don't remove from the array in this case.
943 removeUid(uid, false);
944 }
945
946 private void removeUid(int uid, boolean remove) {
947 synchronized (mLock) {
948 if (removeUidFromArray(mActiveUids, uid, remove)) {
949 mHandler.notifyUidActiveStateChanged(uid);
950 }
951 if (removeUidFromArray(mForegroundUids, uid, remove)) {
952 mHandler.notifyUidForegroundStateChanged(uid);
953 }
Makoto Onuki2206af32017-11-21 16:25:35 -0800954 }
955 }
956 }
957
958 void handleUserRemoved(int removedUserId) {
959 synchronized (mLock) {
960 for (int i = mRunAnyRestrictedPackages.size() - 1; i >= 0; i--) {
961 final Pair<Integer, String> pair = mRunAnyRestrictedPackages.valueAt(i);
962 final int uid = pair.first;
963 final int userId = UserHandle.getUserId(uid);
964
965 if (userId == removedUserId) {
966 mRunAnyRestrictedPackages.removeAt(i);
967 }
968 }
Makoto Onukiadb50d82018-01-29 16:20:30 -0800969 cleanUpArrayForUser(mActiveUids, removedUserId);
970 cleanUpArrayForUser(mForegroundUids, removedUserId);
Makoto Onukieb898f12018-01-23 15:26:27 -0800971 mExemptedPackages.remove(removedUserId);
Makoto Onuki2206af32017-11-21 16:25:35 -0800972 }
973 }
974
Makoto Onukiadb50d82018-01-29 16:20:30 -0800975 private void cleanUpArrayForUser(SparseBooleanArray array, int removedUserId) {
976 for (int i = array.size() - 1; i >= 0; i--) {
977 final int uid = array.keyAt(i);
978 final int userId = UserHandle.getUserId(uid);
979
980 if (userId == removedUserId) {
981 array.removeAt(i);
982 }
983 }
984 }
985
Makoto Onuki2206af32017-11-21 16:25:35 -0800986 /**
987 * Called by device idle controller to update the power save whitelists.
988 */
989 public void setPowerSaveWhitelistAppIds(
990 int[] powerSaveWhitelistAllAppIdArray, int[] tempWhitelistAppIdArray) {
991 synchronized (mLock) {
992 final int[] previousWhitelist = mPowerWhitelistedAllAppIds;
993 final int[] previousTempWhitelist = mTempWhitelistedAppIds;
994
995 mPowerWhitelistedAllAppIds = powerSaveWhitelistAllAppIdArray;
996 mTempWhitelistedAppIds = tempWhitelistAppIdArray;
997
998 if (isAnyAppIdUnwhitelisted(previousWhitelist, mPowerWhitelistedAllAppIds)) {
999 mHandler.notifyAllUnwhitelisted();
1000 } else if (!Arrays.equals(previousWhitelist, mPowerWhitelistedAllAppIds)) {
1001 mHandler.notifyAllWhitelistChanged();
1002 }
1003
1004 if (!Arrays.equals(previousTempWhitelist, mTempWhitelistedAppIds)) {
1005 mHandler.notifyTempWhitelistChanged();
1006 }
1007
1008 }
1009 }
1010
1011 /**
1012 * @retunr true if a sorted app-id array {@code prevArray} has at least one element
1013 * that's not in a sorted app-id array {@code newArray}.
1014 */
1015 @VisibleForTesting
1016 static boolean isAnyAppIdUnwhitelisted(int[] prevArray, int[] newArray) {
1017 int i1 = 0;
1018 int i2 = 0;
1019 boolean prevFinished;
1020 boolean newFinished;
1021
1022 for (;;) {
1023 prevFinished = i1 >= prevArray.length;
1024 newFinished = i2 >= newArray.length;
1025 if (prevFinished || newFinished) {
1026 break;
1027 }
1028 int a1 = prevArray[i1];
1029 int a2 = newArray[i2];
1030
1031 if (a1 == a2) {
1032 i1++;
1033 i2++;
1034 continue;
1035 }
1036 if (a1 < a2) {
1037 // prevArray has an element that's not in a2.
1038 return true;
1039 }
1040 i2++;
1041 }
1042 if (prevFinished) {
1043 return false;
1044 }
1045 return newFinished;
Makoto Onuki9be01402017-11-10 13:22:26 -08001046 }
1047
1048 // Public interface.
1049
1050 /**
1051 * Register a new listener.
1052 */
1053 public void addListener(@NonNull Listener listener) {
1054 synchronized (mLock) {
1055 mListeners.add(listener);
1056 }
1057 }
1058
1059 /**
Makoto Onuki2206af32017-11-21 16:25:35 -08001060 * @return whether alarms should be restricted for a UID package-name.
Makoto Onuki9be01402017-11-10 13:22:26 -08001061 */
Suprabh Shuklac25447d2018-01-19 16:43:35 -08001062 public boolean areAlarmsRestricted(int uid, @NonNull String packageName,
1063 boolean allowWhileIdle) {
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001064 return isRestricted(uid, packageName, /*useTempWhitelistToo=*/ false,
Suprabh Shuklac25447d2018-01-19 16:43:35 -08001065 /* exemptOnBatterySaver =*/ allowWhileIdle);
Makoto Onuki2206af32017-11-21 16:25:35 -08001066 }
1067
1068 /**
1069 * @return whether jobs should be restricted for a UID package-name.
1070 */
Makoto Onuki15407842018-01-19 14:23:11 -08001071 public boolean areJobsRestricted(int uid, @NonNull String packageName,
1072 boolean hasForegroundExemption) {
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001073 return isRestricted(uid, packageName, /*useTempWhitelistToo=*/ true,
Makoto Onuki15407842018-01-19 14:23:11 -08001074 hasForegroundExemption);
Makoto Onuki2206af32017-11-21 16:25:35 -08001075 }
1076
1077 /**
Christopher Tatec7933ac2018-03-12 17:57:09 -07001078 * @return whether foreground services should be suppressed in the background
1079 * due to forced app standby for the given app
1080 */
1081 public boolean areForegroundServicesRestricted(int uid, @NonNull String packageName) {
1082 synchronized (mLock) {
1083 return isRunAnyRestrictedLocked(uid, packageName);
1084 }
1085 }
1086
1087 /**
Makoto Onuki2206af32017-11-21 16:25:35 -08001088 * @return whether force-app-standby is effective for a UID package-name.
1089 */
1090 private boolean isRestricted(int uid, @NonNull String packageName,
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001091 boolean useTempWhitelistToo, boolean exemptOnBatterySaver) {
Makoto Onukiadb50d82018-01-29 16:20:30 -08001092 if (isUidActive(uid)) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001093 return false;
1094 }
1095 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001096 // Whitelisted?
1097 final int appId = UserHandle.getAppId(uid);
1098 if (ArrayUtils.contains(mPowerWhitelistedAllAppIds, appId)) {
1099 return false;
1100 }
1101 if (useTempWhitelistToo &&
1102 ArrayUtils.contains(mTempWhitelistedAppIds, appId)) {
1103 return false;
1104 }
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001105 if (mForcedAppStandbyEnabled && isRunAnyRestrictedLocked(uid, packageName)) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001106 return true;
1107 }
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001108 if (exemptOnBatterySaver) {
1109 return false;
1110 }
Makoto Onukieb898f12018-01-23 15:26:27 -08001111 final int userId = UserHandle.getUserId(uid);
1112 if (mExemptedPackages.contains(userId, packageName)) {
1113 return false;
1114 }
Makoto Onukieb8cfd12018-01-19 15:43:16 -08001115 return mForceAllAppsStandby;
Makoto Onuki9be01402017-11-10 13:22:26 -08001116 }
1117 }
1118
Makoto Onuki2206af32017-11-21 16:25:35 -08001119 /**
Makoto Onukie4918212018-02-06 11:30:15 -08001120 * @return whether a UID is in active or not *based on cached information.*
Makoto Onukiadb50d82018-01-29 16:20:30 -08001121 *
1122 * Note this information is based on the UID proc state callback, meaning it's updated
1123 * asynchronously and may subtly be stale. If the fresh data is needed, use
Makoto Onukie4918212018-02-06 11:30:15 -08001124 * {@link #isUidActiveSynced} instead.
Makoto Onukiadb50d82018-01-29 16:20:30 -08001125 */
1126 public boolean isUidActive(int uid) {
1127 if (UserHandle.isCore(uid)) {
1128 return true;
1129 }
1130 synchronized (mLock) {
1131 return mActiveUids.get(uid);
1132 }
1133 }
1134
1135 /**
Makoto Onukie4918212018-02-06 11:30:15 -08001136 * @return whether a UID is in active or not *right now.*
1137 *
1138 * This gives the fresh information, but may access the activity manager so is slower.
1139 */
1140 public boolean isUidActiveSynced(int uid) {
1141 if (isUidActive(uid)) { // Use the cached one first.
1142 return true;
1143 }
1144 final long start = mStatLogger.getTime();
1145
1146 final boolean ret = mActivityManagerInternal.isUidActive(uid);
1147 mStatLogger.logDurationStat(Stats.IS_UID_ACTIVE_RAW, start);
1148
1149 return ret;
1150 }
1151
1152 /**
Makoto Onuki2206af32017-11-21 16:25:35 -08001153 * @return whether a UID is in the foreground or not.
1154 *
Makoto Onuki15407842018-01-19 14:23:11 -08001155 * Note this information is based on the UID proc state callback, meaning it's updated
1156 * asynchronously and may subtly be stale. If the fresh data is needed, use
1157 * {@link ActivityManagerInternal#getUidProcessState} instead.
Makoto Onuki2206af32017-11-21 16:25:35 -08001158 */
Makoto Onukiadb50d82018-01-29 16:20:30 -08001159 public boolean isUidInForeground(int uid) {
Makoto Onuki9cc471c2018-01-23 12:33:56 -08001160 if (UserHandle.isCore(uid)) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001161 return true;
1162 }
1163 synchronized (mLock) {
1164 return mForegroundUids.get(uid);
1165 }
1166 }
1167
Makoto Onuki2206af32017-11-21 16:25:35 -08001168 /**
1169 * @return whether force all apps standby is enabled or not.
1170 *
Makoto Onuki2206af32017-11-21 16:25:35 -08001171 */
1172 boolean isForceAllAppsStandbyEnabled() {
Makoto Onuki9be01402017-11-10 13:22:26 -08001173 synchronized (mLock) {
1174 return mForceAllAppsStandby;
1175 }
1176 }
1177
Makoto Onuki2206af32017-11-21 16:25:35 -08001178 /**
1179 * @return whether a UID/package has {@code OP_RUN_ANY_IN_BACKGROUND} allowed or not.
1180 *
1181 * Note clients normally shouldn't need to access it. It's only for dumpsys.
1182 */
Makoto Onuki9be01402017-11-10 13:22:26 -08001183 public boolean isRunAnyInBackgroundAppOpsAllowed(int uid, @NonNull String packageName) {
1184 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001185 return !isRunAnyRestrictedLocked(uid, packageName);
Makoto Onuki9be01402017-11-10 13:22:26 -08001186 }
1187 }
1188
Makoto Onuki2206af32017-11-21 16:25:35 -08001189 /**
1190 * @return whether a UID is in the user / system defined power-save whitelist or not.
1191 *
1192 * Note clients normally shouldn't need to access it. It's only for dumpsys.
1193 */
1194 public boolean isUidPowerSaveWhitelisted(int uid) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001195 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001196 return ArrayUtils.contains(mPowerWhitelistedAllAppIds, UserHandle.getAppId(uid));
Makoto Onuki9be01402017-11-10 13:22:26 -08001197 }
1198 }
1199
Makoto Onuki2206af32017-11-21 16:25:35 -08001200 /**
1201 * @return whether a UID is in the temp power-save whitelist or not.
1202 *
1203 * Note clients normally shouldn't need to access it. It's only for dumpsys.
1204 */
1205 public boolean isUidTempPowerSaveWhitelisted(int uid) {
Makoto Onuki9be01402017-11-10 13:22:26 -08001206 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001207 return ArrayUtils.contains(mTempWhitelistedAppIds, UserHandle.getAppId(uid));
1208 }
1209 }
1210
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001211 @Deprecated
1212 public void dump(PrintWriter pw, String prefix) {
1213 dump(new IndentingPrintWriter(pw, " ").setIndent(prefix));
1214 }
1215
1216 public void dump(IndentingPrintWriter pw) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001217 synchronized (mLock) {
Suprabh Shukla4deb8522018-01-08 16:27:10 -08001218 pw.println("Forced App Standby Feature enabled: " + mForcedAppStandbyEnabled);
1219
Makoto Onuki2206af32017-11-21 16:25:35 -08001220 pw.print("Force all apps standby: ");
1221 pw.println(isForceAllAppsStandbyEnabled());
1222
Nancy Zheng525aaa12018-01-12 11:45:37 -08001223 pw.print("Small Battery Device: ");
1224 pw.println(isSmallBatteryDevice());
1225
Nancy Zheng525aaa12018-01-12 11:45:37 -08001226 pw.print("Force all apps standby for small battery device: ");
1227 pw.println(mForceAllAppStandbyForSmallBattery);
1228
Nancy Zheng525aaa12018-01-12 11:45:37 -08001229 pw.print("Plugged In: ");
1230 pw.println(mIsPluggedIn);
1231
Makoto Onukiadb50d82018-01-29 16:20:30 -08001232 pw.print("Active uids: ");
1233 dumpUids(pw, mActiveUids);
Makoto Onuki2206af32017-11-21 16:25:35 -08001234
Makoto Onukiadb50d82018-01-29 16:20:30 -08001235 pw.print("Foreground uids: ");
1236 dumpUids(pw, mForegroundUids);
Makoto Onuki2206af32017-11-21 16:25:35 -08001237
Makoto Onuki2206af32017-11-21 16:25:35 -08001238 pw.print("Whitelist appids: ");
1239 pw.println(Arrays.toString(mPowerWhitelistedAllAppIds));
1240
Makoto Onuki2206af32017-11-21 16:25:35 -08001241 pw.print("Temp whitelist appids: ");
1242 pw.println(Arrays.toString(mTempWhitelistedAppIds));
1243
Makoto Onukieb898f12018-01-23 15:26:27 -08001244 pw.println("Exempted packages:");
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001245 pw.increaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001246 for (int i = 0; i < mExemptedPackages.size(); i++) {
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001247 pw.print("User ");
Makoto Onukieb898f12018-01-23 15:26:27 -08001248 pw.print(mExemptedPackages.keyAt(i));
1249 pw.println();
1250
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001251 pw.increaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001252 for (int j = 0; j < mExemptedPackages.sizeAt(i); j++) {
Makoto Onukieb898f12018-01-23 15:26:27 -08001253 pw.print(mExemptedPackages.valueAt(i, j));
1254 pw.println();
1255 }
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001256 pw.decreaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001257 }
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001258 pw.decreaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001259 pw.println();
1260
Makoto Onuki2206af32017-11-21 16:25:35 -08001261 pw.println("Restricted packages:");
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001262 pw.increaseIndent();
Makoto Onuki2206af32017-11-21 16:25:35 -08001263 for (Pair<Integer, String> uidAndPackage : mRunAnyRestrictedPackages) {
Makoto Onuki2206af32017-11-21 16:25:35 -08001264 pw.print(UserHandle.formatUid(uidAndPackage.first));
1265 pw.print(" ");
1266 pw.print(uidAndPackage.second);
1267 pw.println();
1268 }
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001269 pw.decreaseIndent();
Makoto Onukieb898f12018-01-23 15:26:27 -08001270
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -07001271 mStatLogger.dump(pw);
Makoto Onuki2206af32017-11-21 16:25:35 -08001272 }
1273 }
1274
Makoto Onukiadb50d82018-01-29 16:20:30 -08001275 private void dumpUids(PrintWriter pw, SparseBooleanArray array) {
1276 pw.print("[");
1277
1278 String sep = "";
1279 for (int i = 0; i < array.size(); i++) {
1280 if (array.valueAt(i)) {
1281 pw.print(sep);
1282 pw.print(UserHandle.formatUid(array.keyAt(i)));
1283 sep = " ";
1284 }
1285 }
1286 pw.println("]");
1287 }
1288
Makoto Onuki2206af32017-11-21 16:25:35 -08001289 public void dumpProto(ProtoOutputStream proto, long fieldId) {
1290 synchronized (mLock) {
1291 final long token = proto.start(fieldId);
1292
1293 proto.write(ForceAppStandbyTrackerProto.FORCE_ALL_APPS_STANDBY, mForceAllAppsStandby);
Nancy Zheng525aaa12018-01-12 11:45:37 -08001294 proto.write(ForceAppStandbyTrackerProto.IS_SMALL_BATTERY_DEVICE,
1295 isSmallBatteryDevice());
1296 proto.write(ForceAppStandbyTrackerProto.FORCE_ALL_APPS_STANDBY_FOR_SMALL_BATTERY,
1297 mForceAllAppStandbyForSmallBattery);
Makoto Onukieb898f12018-01-23 15:26:27 -08001298 proto.write(ForceAppStandbyTrackerProto.IS_PLUGGED_IN, mIsPluggedIn);
Makoto Onuki2206af32017-11-21 16:25:35 -08001299
Makoto Onukiadb50d82018-01-29 16:20:30 -08001300 for (int i = 0; i < mActiveUids.size(); i++) {
1301 if (mActiveUids.valueAt(i)) {
1302 proto.write(ForceAppStandbyTrackerProto.ACTIVE_UIDS,
1303 mActiveUids.keyAt(i));
1304 }
1305 }
1306
Makoto Onuki2206af32017-11-21 16:25:35 -08001307 for (int i = 0; i < mForegroundUids.size(); i++) {
1308 if (mForegroundUids.valueAt(i)) {
1309 proto.write(ForceAppStandbyTrackerProto.FOREGROUND_UIDS,
1310 mForegroundUids.keyAt(i));
1311 }
1312 }
1313
1314 for (int appId : mPowerWhitelistedAllAppIds) {
1315 proto.write(ForceAppStandbyTrackerProto.POWER_SAVE_WHITELIST_APP_IDS, appId);
1316 }
1317
1318 for (int appId : mTempWhitelistedAppIds) {
1319 proto.write(ForceAppStandbyTrackerProto.TEMP_POWER_SAVE_WHITELIST_APP_IDS, appId);
1320 }
1321
Makoto Onukieb898f12018-01-23 15:26:27 -08001322 for (int i = 0; i < mExemptedPackages.size(); i++) {
1323 for (int j = 0; j < mExemptedPackages.sizeAt(i); j++) {
1324 final long token2 = proto.start(
1325 ForceAppStandbyTrackerProto.EXEMPTED_PACKAGES);
1326
1327 proto.write(ExemptedPackage.USER_ID, mExemptedPackages.keyAt(i));
1328 proto.write(ExemptedPackage.PACKAGE_NAME, mExemptedPackages.valueAt(i, j));
1329
1330 proto.end(token2);
1331 }
1332 }
1333
Makoto Onuki2206af32017-11-21 16:25:35 -08001334 for (Pair<Integer, String> uidAndPackage : mRunAnyRestrictedPackages) {
1335 final long token2 = proto.start(
1336 ForceAppStandbyTrackerProto.RUN_ANY_IN_BACKGROUND_RESTRICTED_PACKAGES);
1337 proto.write(RunAnyInBackgroundRestrictedPackages.UID, uidAndPackage.first);
1338 proto.write(RunAnyInBackgroundRestrictedPackages.PACKAGE_NAME,
1339 uidAndPackage.second);
1340 proto.end(token2);
1341 }
Makoto Onukieb898f12018-01-23 15:26:27 -08001342
1343 mStatLogger.dumpProto(proto, ForceAppStandbyTrackerProto.STATS);
1344
Makoto Onuki2206af32017-11-21 16:25:35 -08001345 proto.end(token);
Makoto Onuki9be01402017-11-10 13:22:26 -08001346 }
1347 }
1348}