blob: 257845e365bed00d5071b38965565cc2e299f74b [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 Onuki2206af32017-11-21 16:25:35 -080025import android.content.BroadcastReceiver;
Makoto Onuki9be01402017-11-10 13:22:26 -080026import android.content.Context;
Makoto Onuki2206af32017-11-21 16:25:35 -080027import android.content.Intent;
28import android.content.IntentFilter;
Suprabh Shukla4deb8522018-01-08 16:27:10 -080029import android.database.ContentObserver;
Nancy Zheng525aaa12018-01-12 11:45:37 -080030import android.net.Uri;
31import android.os.BatteryManager;
Makoto Onuki9be01402017-11-10 13:22:26 -080032import android.os.Handler;
Makoto Onuki2206af32017-11-21 16:25:35 -080033import android.os.Looper;
34import android.os.Message;
Makoto Onuki9be01402017-11-10 13:22:26 -080035import android.os.PowerManager.ServiceType;
36import android.os.PowerManagerInternal;
37import android.os.RemoteException;
38import android.os.ServiceManager;
39import android.os.UserHandle;
Suprabh Shukla4deb8522018-01-08 16:27:10 -080040import android.provider.Settings;
Makoto Onuki9be01402017-11-10 13:22:26 -080041import android.util.ArraySet;
42import android.util.Pair;
Suprabh Shukla4deb8522018-01-08 16:27:10 -080043import android.util.Slog;
Makoto Onuki9be01402017-11-10 13:22:26 -080044import android.util.SparseBooleanArray;
Makoto Onuki2206af32017-11-21 16:25:35 -080045import android.util.proto.ProtoOutputStream;
Makoto Onuki9be01402017-11-10 13:22:26 -080046
47import com.android.internal.annotations.GuardedBy;
Makoto Onuki2206af32017-11-21 16:25:35 -080048import com.android.internal.annotations.VisibleForTesting;
Makoto Onuki9be01402017-11-10 13:22:26 -080049import com.android.internal.app.IAppOpsCallback;
50import com.android.internal.app.IAppOpsService;
Makoto Onuki2206af32017-11-21 16:25:35 -080051import com.android.internal.util.ArrayUtils;
Makoto Onuki9be01402017-11-10 13:22:26 -080052import com.android.internal.util.Preconditions;
Makoto Onuki2206af32017-11-21 16:25:35 -080053import com.android.server.ForceAppStandbyTrackerProto.RunAnyInBackgroundRestrictedPackages;
Makoto Onuki9be01402017-11-10 13:22:26 -080054
Makoto Onuki2206af32017-11-21 16:25:35 -080055import java.io.PrintWriter;
56import java.util.Arrays;
Makoto Onuki9be01402017-11-10 13:22:26 -080057import java.util.List;
58
59/**
Makoto Onuki2206af32017-11-21 16:25:35 -080060 * Class to keep track of the information related to "force app standby", which includes:
61 * - OP_RUN_ANY_IN_BACKGROUND for each package
62 * - UID foreground state
63 * - User+system power save whitelist
64 * - Temporary power save whitelist
65 * - Global "force all apps standby" mode enforced by battery saver.
Makoto Onuki9be01402017-11-10 13:22:26 -080066 *
Makoto Onuki2206af32017-11-21 16:25:35 -080067 * TODO: In general, we can reduce the number of callbacks by checking all signals before sending
Suprabh Shukla4deb8522018-01-08 16:27:10 -080068 * each callback. For example, even when an UID comes into the foreground, if it wasn't
69 * originally restricted, then there's no need to send an event.
70 * Doing this would be error-prone, so we punt it for now, but we should revisit it later.
Makoto Onuki2206af32017-11-21 16:25:35 -080071 *
72 * Test:
Suprabh Shukla4deb8522018-01-08 16:27:10 -080073 * atest $ANDROID_BUILD_TOP/frameworks/base/services/tests/servicestests/src/com/android/server/ForceAppStandbyTrackerTest.java
Makoto Onuki9be01402017-11-10 13:22:26 -080074 */
75public class ForceAppStandbyTracker {
76 private static final String TAG = "ForceAppStandbyTracker";
Suprabh Shukla4deb8522018-01-08 16:27:10 -080077 private static final boolean DEBUG = false;
Makoto Onuki9be01402017-11-10 13:22:26 -080078
79 @GuardedBy("ForceAppStandbyTracker.class")
80 private static ForceAppStandbyTracker sInstance;
81
82 private final Object mLock = new Object();
83 private final Context mContext;
84
Makoto Onuki2206af32017-11-21 16:25:35 -080085 @VisibleForTesting
86 static final int TARGET_OP = AppOpsManager.OP_RUN_ANY_IN_BACKGROUND;
87
88 IActivityManager mIActivityManager;
Makoto Onuki9be01402017-11-10 13:22:26 -080089 AppOpsManager mAppOpsManager;
90 IAppOpsService mAppOpsService;
91 PowerManagerInternal mPowerManagerInternal;
92
Makoto Onuki2206af32017-11-21 16:25:35 -080093 private final MyHandler mHandler;
Makoto Onuki9be01402017-11-10 13:22:26 -080094
Nancy Zheng525aaa12018-01-12 11:45:37 -080095 @VisibleForTesting
96 FeatureFlagsObserver mFlagsObserver;
97
Makoto Onuki9be01402017-11-10 13:22:26 -080098 /**
99 * Pair of (uid (not user-id), packageName) with OP_RUN_ANY_IN_BACKGROUND *not* allowed.
100 */
101 @GuardedBy("mLock")
Makoto Onuki2206af32017-11-21 16:25:35 -0800102 final ArraySet<Pair<Integer, String>> mRunAnyRestrictedPackages = new ArraySet<>();
Makoto Onuki9be01402017-11-10 13:22:26 -0800103
104 @GuardedBy("mLock")
105 final SparseBooleanArray mForegroundUids = new SparseBooleanArray();
106
Makoto Onuki71755c92018-01-16 14:15:44 -0800107 /**
108 * System except-idle + user whitelist in the device idle controller.
109 */
Makoto Onuki9be01402017-11-10 13:22:26 -0800110 @GuardedBy("mLock")
Makoto Onuki2206af32017-11-21 16:25:35 -0800111 private int[] mPowerWhitelistedAllAppIds = new int[0];
112
113 @GuardedBy("mLock")
114 private int[] mTempWhitelistedAppIds = mPowerWhitelistedAllAppIds;
115
116 @GuardedBy("mLock")
Makoto Onuki9be01402017-11-10 13:22:26 -0800117 final ArraySet<Listener> mListeners = new ArraySet<>();
118
119 @GuardedBy("mLock")
120 boolean mStarted;
121
Nancy Zheng525aaa12018-01-12 11:45:37 -0800122 /**
123 * Only used for small battery use-case.
124 */
Makoto Onuki9be01402017-11-10 13:22:26 -0800125 @GuardedBy("mLock")
Nancy Zheng525aaa12018-01-12 11:45:37 -0800126 boolean mIsPluggedIn;
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800127
128 @GuardedBy("mLock")
Nancy Zheng525aaa12018-01-12 11:45:37 -0800129 boolean mBatterySaverEnabled;
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800130
Nancy Zheng525aaa12018-01-12 11:45:37 -0800131 /**
132 * True if the forced app standby is currently enabled
133 */
134 @GuardedBy("mLock")
135 boolean mForceAllAppsStandby;
136
137 /**
138 * True if the forced app standby for small battery devices feature is enabled in settings
139 */
140 @GuardedBy("mLock")
141 boolean mForceAllAppStandbyForSmallBattery;
142
143 /**
144 * True if the forced app standby feature is enabled in settings
145 */
146 @GuardedBy("mLock")
147 boolean mForcedAppStandbyEnabled;
148
149 @VisibleForTesting
150 class FeatureFlagsObserver extends ContentObserver {
151 FeatureFlagsObserver() {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800152 super(null);
153 }
154
155 void register() {
156 mContext.getContentResolver().registerContentObserver(
157 Settings.Global.getUriFor(Settings.Global.FORCED_APP_STANDBY_ENABLED),
158 false, this);
Nancy Zheng525aaa12018-01-12 11:45:37 -0800159
160 mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor(
161 Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED), false, this);
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800162 }
163
164 boolean isForcedAppStandbyEnabled() {
165 return Settings.Global.getInt(mContext.getContentResolver(),
166 Settings.Global.FORCED_APP_STANDBY_ENABLED, 1) == 1;
167 }
168
Nancy Zheng525aaa12018-01-12 11:45:37 -0800169 boolean isForcedAppStandbyForSmallBatteryEnabled() {
170 return Settings.Global.getInt(mContext.getContentResolver(),
171 Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED, 0) == 1;
172 }
173
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800174 @Override
Nancy Zheng525aaa12018-01-12 11:45:37 -0800175 public void onChange(boolean selfChange, Uri uri) {
176 if (Settings.Global.getUriFor(Settings.Global.FORCED_APP_STANDBY_ENABLED).equals(uri)) {
177 final boolean enabled = isForcedAppStandbyEnabled();
178 synchronized (mLock) {
179 if (mForcedAppStandbyEnabled == enabled) {
180 return;
181 }
182 mForcedAppStandbyEnabled = enabled;
183 if (DEBUG) {
184 Slog.d(TAG,"Forced app standby feature flag changed: "
185 + mForcedAppStandbyEnabled);
186 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800187 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800188 mHandler.notifyForcedAppStandbyFeatureFlagChanged();
189 } else if (Settings.Global.getUriFor(
190 Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED).equals(uri)) {
191 final boolean enabled = isForcedAppStandbyForSmallBatteryEnabled();
192 synchronized (mLock) {
193 if (mForceAllAppStandbyForSmallBattery == enabled) {
194 return;
195 }
196 mForceAllAppStandbyForSmallBattery = enabled;
197 if (DEBUG) {
198 Slog.d(TAG, "Forced app standby for small battery feature flag changed: "
199 + mForceAllAppStandbyForSmallBattery);
200 }
201 updateForceAllAppStandbyState();
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800202 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800203 } else {
204 Slog.w(TAG, "Unexpected feature flag uri encountered: " + uri);
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800205 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800206 }
207 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800208
209 public static abstract class Listener {
Makoto Onuki2206af32017-11-21 16:25:35 -0800210 /**
211 * This is called when the OP_RUN_ANY_IN_BACKGROUND appops changed for a package.
212 */
213 private void onRunAnyAppOpsChanged(ForceAppStandbyTracker sender,
214 int uid, @NonNull String packageName) {
215 updateJobsForUidPackage(uid, packageName);
216
Suprabh Shuklac25447d2018-01-19 16:43:35 -0800217 if (!sender.areAlarmsRestricted(uid, packageName, /*allowWhileIdle=*/ false)) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800218 unblockAlarmsForUidPackage(uid, packageName);
Suprabh Shuklac25447d2018-01-19 16:43:35 -0800219 } else if (!sender.areAlarmsRestricted(uid, packageName, /*allowWhileIdle=*/ true)){
220 // we need to deliver the allow-while-idle alarms for this uid, package
221 unblockAllUnrestrictedAlarms();
Makoto Onuki2206af32017-11-21 16:25:35 -0800222 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800223 }
224
Makoto Onuki2206af32017-11-21 16:25:35 -0800225 /**
226 * This is called when the foreground state changed for a UID.
227 */
228 private void onUidForegroundStateChanged(ForceAppStandbyTracker sender, int uid) {
229 updateJobsForUid(uid);
230
231 if (sender.isInForeground(uid)) {
232 unblockAlarmsForUid(uid);
233 }
234 }
235
236 /**
237 * This is called when an app-id(s) is removed from the power save whitelist.
238 */
239 private void onPowerSaveUnwhitelisted(ForceAppStandbyTracker sender) {
240 updateAllJobs();
241 unblockAllUnrestrictedAlarms();
242 }
243
244 /**
245 * This is called when the power save whitelist changes, excluding the
246 * {@link #onPowerSaveUnwhitelisted} case.
247 */
248 private void onPowerSaveWhitelistedChanged(ForceAppStandbyTracker sender) {
249 updateAllJobs();
250 }
251
252 /**
253 * This is called when the temp whitelist changes.
254 */
255 private void onTempPowerSaveWhitelistChanged(ForceAppStandbyTracker sender) {
256
257 // TODO This case happens rather frequently; consider optimizing and update jobs
258 // only for affected app-ids.
259
260 updateAllJobs();
261 }
262
263 /**
264 * This is called when the global "force all apps standby" flag changes.
265 */
266 private void onForceAllAppsStandbyChanged(ForceAppStandbyTracker sender) {
267 updateAllJobs();
268
269 if (!sender.isForceAllAppsStandbyEnabled()) {
270 unblockAllUnrestrictedAlarms();
271 }
272 }
273
274 /**
275 * Called when the job restrictions for multiple UIDs might have changed, so the job
276 * scheduler should re-evaluate all restrictions for all jobs.
277 */
278 public void updateAllJobs() {
279 }
280
281 /**
282 * Called when the job restrictions for a UID might have changed, so the job
283 * scheduler should re-evaluate all restrictions for all jobs.
284 */
285 public void updateJobsForUid(int uid) {
286 }
287
288 /**
289 * Called when the job restrictions for a UID - package might have changed, so the job
290 * scheduler should re-evaluate all restrictions for all jobs.
291 */
292 public void updateJobsForUidPackage(int uid, String packageName) {
293 }
294
295 /**
296 * Called when the job restrictions for multiple UIDs might have changed, so the alarm
297 * manager should re-evaluate all restrictions for all blocked jobs.
298 */
299 public void unblockAllUnrestrictedAlarms() {
300 }
301
302 /**
303 * Called when all jobs for a specific UID are unblocked.
304 */
305 public void unblockAlarmsForUid(int uid) {
306 }
307
308 /**
309 * Called when all alarms for a specific UID - package are unblocked.
310 */
311 public void unblockAlarmsForUidPackage(int uid, String packageName) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800312 }
313 }
314
Makoto Onuki2206af32017-11-21 16:25:35 -0800315 @VisibleForTesting
316 ForceAppStandbyTracker(Context context, Looper looper) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800317 mContext = context;
Makoto Onuki2206af32017-11-21 16:25:35 -0800318 mHandler = new MyHandler(looper);
319 }
320
321 private ForceAppStandbyTracker(Context context) {
322 this(context, FgThread.get().getLooper());
Makoto Onuki9be01402017-11-10 13:22:26 -0800323 }
324
325 /**
326 * Get the singleton instance.
327 */
328 public static synchronized ForceAppStandbyTracker getInstance(Context context) {
329 if (sInstance == null) {
330 sInstance = new ForceAppStandbyTracker(context);
331 }
332 return sInstance;
333 }
334
335 /**
336 * Call it when the system is ready.
337 */
338 public void start() {
339 synchronized (mLock) {
340 if (mStarted) {
341 return;
342 }
343 mStarted = true;
344
Makoto Onuki2206af32017-11-21 16:25:35 -0800345 mIActivityManager = Preconditions.checkNotNull(injectIActivityManager());
346 mAppOpsManager = Preconditions.checkNotNull(injectAppOpsManager());
347 mAppOpsService = Preconditions.checkNotNull(injectIAppOpsService());
348 mPowerManagerInternal = Preconditions.checkNotNull(injectPowerManagerInternal());
Nancy Zheng525aaa12018-01-12 11:45:37 -0800349 mFlagsObserver = new FeatureFlagsObserver();
350 mFlagsObserver.register();
351 mForcedAppStandbyEnabled = mFlagsObserver.isForcedAppStandbyEnabled();
352 mForceAllAppStandbyForSmallBattery =
353 mFlagsObserver.isForcedAppStandbyForSmallBatteryEnabled();
Makoto Onuki9be01402017-11-10 13:22:26 -0800354
355 try {
Makoto Onuki2206af32017-11-21 16:25:35 -0800356 mIActivityManager.registerUidObserver(new UidObserver(),
Makoto Onuki9be01402017-11-10 13:22:26 -0800357 ActivityManager.UID_OBSERVER_GONE | ActivityManager.UID_OBSERVER_IDLE
358 | ActivityManager.UID_OBSERVER_ACTIVE,
359 ActivityManager.PROCESS_STATE_UNKNOWN, null);
Makoto Onuki2206af32017-11-21 16:25:35 -0800360 mAppOpsService.startWatchingMode(TARGET_OP, null,
Makoto Onuki9be01402017-11-10 13:22:26 -0800361 new AppOpsWatcher());
362 } catch (RemoteException e) {
363 // shouldn't happen.
364 }
365
Makoto Onuki2206af32017-11-21 16:25:35 -0800366 IntentFilter filter = new IntentFilter();
367 filter.addAction(Intent.ACTION_USER_REMOVED);
Nancy Zheng525aaa12018-01-12 11:45:37 -0800368 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
Makoto Onuki2206af32017-11-21 16:25:35 -0800369 mContext.registerReceiver(new MyReceiver(), filter);
Makoto Onuki9be01402017-11-10 13:22:26 -0800370
371 refreshForcedAppStandbyUidPackagesLocked();
Makoto Onuki2206af32017-11-21 16:25:35 -0800372
373 mPowerManagerInternal.registerLowPowerModeObserver(
374 ServiceType.FORCE_ALL_APPS_STANDBY,
Nancy Zheng525aaa12018-01-12 11:45:37 -0800375 (state) -> {
376 synchronized (mLock) {
377 mBatterySaverEnabled = state.batterySaverEnabled;
378 updateForceAllAppStandbyState();
379 }
380 });
Makoto Onuki2206af32017-11-21 16:25:35 -0800381
Nancy Zheng525aaa12018-01-12 11:45:37 -0800382 mBatterySaverEnabled = mPowerManagerInternal.getLowPowerState(
383 ServiceType.FORCE_ALL_APPS_STANDBY).batterySaverEnabled;
384
385 updateForceAllAppStandbyState();
Makoto Onuki9be01402017-11-10 13:22:26 -0800386 }
387 }
388
Makoto Onuki2206af32017-11-21 16:25:35 -0800389 @VisibleForTesting
390 AppOpsManager injectAppOpsManager() {
391 return mContext.getSystemService(AppOpsManager.class);
392 }
393
394 @VisibleForTesting
395 IAppOpsService injectIAppOpsService() {
396 return IAppOpsService.Stub.asInterface(
397 ServiceManager.getService(Context.APP_OPS_SERVICE));
398 }
399
400 @VisibleForTesting
401 IActivityManager injectIActivityManager() {
402 return ActivityManager.getService();
403 }
404
405 @VisibleForTesting
406 PowerManagerInternal injectPowerManagerInternal() {
407 return LocalServices.getService(PowerManagerInternal.class);
408 }
409
Nancy Zheng525aaa12018-01-12 11:45:37 -0800410 @VisibleForTesting
411 boolean isSmallBatteryDevice() {
412 return ActivityManager.isSmallBatteryDevice();
413 }
414
Makoto Onuki9be01402017-11-10 13:22:26 -0800415 /**
Makoto Onuki2206af32017-11-21 16:25:35 -0800416 * Update {@link #mRunAnyRestrictedPackages} with the current app ops state.
Makoto Onuki9be01402017-11-10 13:22:26 -0800417 */
418 private void refreshForcedAppStandbyUidPackagesLocked() {
Makoto Onuki2206af32017-11-21 16:25:35 -0800419 mRunAnyRestrictedPackages.clear();
420 final List<PackageOps> ops = mAppOpsManager.getPackagesForOps(
421 new int[] {TARGET_OP});
Makoto Onuki9be01402017-11-10 13:22:26 -0800422
423 if (ops == null) {
424 return;
425 }
426 final int size = ops.size();
427 for (int i = 0; i < size; i++) {
428 final AppOpsManager.PackageOps pkg = ops.get(i);
429 final List<AppOpsManager.OpEntry> entries = ops.get(i).getOps();
430
431 for (int j = 0; j < entries.size(); j++) {
432 AppOpsManager.OpEntry ent = entries.get(j);
Makoto Onuki2206af32017-11-21 16:25:35 -0800433 if (ent.getOp() != TARGET_OP) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800434 continue;
435 }
436 if (ent.getMode() != AppOpsManager.MODE_ALLOWED) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800437 mRunAnyRestrictedPackages.add(Pair.create(
Makoto Onuki9be01402017-11-10 13:22:26 -0800438 pkg.getUid(), pkg.getPackageName()));
439 }
440 }
441 }
442 }
443
Nancy Zheng525aaa12018-01-12 11:45:37 -0800444 private void updateForceAllAppStandbyState() {
445 synchronized (mLock) {
446 if (mForceAllAppStandbyForSmallBattery && isSmallBatteryDevice()) {
447 toggleForceAllAppsStandbyLocked(!mIsPluggedIn);
448 } else {
449 toggleForceAllAppsStandbyLocked(mBatterySaverEnabled);
450 }
451 }
452 }
453
Makoto Onuki2206af32017-11-21 16:25:35 -0800454 /**
455 * Update {@link #mForceAllAppsStandby} and notifies the listeners.
456 */
Nancy Zheng525aaa12018-01-12 11:45:37 -0800457 private void toggleForceAllAppsStandbyLocked(boolean enable) {
458 if (enable == mForceAllAppsStandby) {
459 return;
Makoto Onuki12391f22018-01-18 21:44:28 +0000460 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800461 mForceAllAppsStandby = enable;
462
463 mHandler.notifyForceAllAppsStandbyChanged();
Makoto Onuki9be01402017-11-10 13:22:26 -0800464 }
465
466 private int findForcedAppStandbyUidPackageIndexLocked(int uid, @NonNull String packageName) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800467 final int size = mRunAnyRestrictedPackages.size();
468 if (size > 8) {
469 return mRunAnyRestrictedPackages.indexOf(Pair.create(uid, packageName));
470 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800471 for (int i = 0; i < size; i++) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800472 final Pair<Integer, String> pair = mRunAnyRestrictedPackages.valueAt(i);
Makoto Onuki9be01402017-11-10 13:22:26 -0800473
474 if ((pair.first == uid) && packageName.equals(pair.second)) {
475 return i;
476 }
477 }
478 return -1;
479 }
480
481 /**
Makoto Onuki2206af32017-11-21 16:25:35 -0800482 * @return whether a uid package-name pair is in mRunAnyRestrictedPackages.
Makoto Onuki9be01402017-11-10 13:22:26 -0800483 */
Makoto Onuki2206af32017-11-21 16:25:35 -0800484 boolean isRunAnyRestrictedLocked(int uid, @NonNull String packageName) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800485 return findForcedAppStandbyUidPackageIndexLocked(uid, packageName) >= 0;
486 }
487
Makoto Onuki2206af32017-11-21 16:25:35 -0800488 /**
489 * Add to / remove from {@link #mRunAnyRestrictedPackages}.
490 */
491 boolean updateForcedAppStandbyUidPackageLocked(int uid, @NonNull String packageName,
Makoto Onuki9be01402017-11-10 13:22:26 -0800492 boolean restricted) {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800493 final int index = findForcedAppStandbyUidPackageIndexLocked(uid, packageName);
Makoto Onuki9be01402017-11-10 13:22:26 -0800494 final boolean wasRestricted = index >= 0;
495 if (wasRestricted == restricted) {
496 return false;
497 }
498 if (restricted) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800499 mRunAnyRestrictedPackages.add(Pair.create(uid, packageName));
Makoto Onuki9be01402017-11-10 13:22:26 -0800500 } else {
Makoto Onuki2206af32017-11-21 16:25:35 -0800501 mRunAnyRestrictedPackages.removeAt(index);
Makoto Onuki9be01402017-11-10 13:22:26 -0800502 }
503 return true;
504 }
505
Makoto Onuki2206af32017-11-21 16:25:35 -0800506 /**
507 * Puts a UID to {@link #mForegroundUids}.
508 */
Makoto Onuki9be01402017-11-10 13:22:26 -0800509 void uidToForeground(int uid) {
510 synchronized (mLock) {
Makoto Onuki9cc471c2018-01-23 12:33:56 -0800511 if (UserHandle.isCore(uid)) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800512 return;
513 }
514 // TODO This can be optimized by calling indexOfKey and sharing the index for get and
515 // put.
516 if (mForegroundUids.get(uid)) {
517 return;
518 }
519 mForegroundUids.put(uid, true);
Makoto Onuki2206af32017-11-21 16:25:35 -0800520 mHandler.notifyUidForegroundStateChanged(uid);
Makoto Onuki9be01402017-11-10 13:22:26 -0800521 }
522 }
523
Makoto Onuki2206af32017-11-21 16:25:35 -0800524 /**
525 * Sets false for a UID {@link #mForegroundUids}, or remove it when {@code remove} is true.
526 */
Makoto Onuki9be01402017-11-10 13:22:26 -0800527 void uidToBackground(int uid, boolean remove) {
528 synchronized (mLock) {
Makoto Onuki9cc471c2018-01-23 12:33:56 -0800529 if (UserHandle.isCore(uid)) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800530 return;
531 }
532 // TODO This can be optimized by calling indexOfKey and sharing the index for get and
533 // put.
534 if (!mForegroundUids.get(uid)) {
535 return;
536 }
537 if (remove) {
538 mForegroundUids.delete(uid);
539 } else {
540 mForegroundUids.put(uid, false);
541 }
Makoto Onuki2206af32017-11-21 16:25:35 -0800542 mHandler.notifyUidForegroundStateChanged(uid);
Makoto Onuki9be01402017-11-10 13:22:26 -0800543 }
544 }
545
Makoto Onuki2206af32017-11-21 16:25:35 -0800546 private final class UidObserver extends IUidObserver.Stub {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800547 @Override
548 public void onUidStateChanged(int uid, int procState, long procStateSeq) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800549 }
550
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800551 @Override
552 public void onUidGone(int uid, boolean disabled) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800553 uidToBackground(uid, /*remove=*/ true);
554 }
555
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800556 @Override
557 public void onUidActive(int uid) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800558 uidToForeground(uid);
559 }
560
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800561 @Override
562 public void onUidIdle(int uid, boolean disabled) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800563 // Just to avoid excessive memcpy, don't remove from the array in this case.
564 uidToBackground(uid, /*remove=*/ false);
565 }
566
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800567 @Override
568 public void onUidCachedChanged(int uid, boolean cached) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800569 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800570 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800571
572 private final class AppOpsWatcher extends IAppOpsCallback.Stub {
573 @Override
574 public void opChanged(int op, int uid, String packageName) throws RemoteException {
Makoto Onuki2206af32017-11-21 16:25:35 -0800575 boolean restricted = false;
576 try {
577 restricted = mAppOpsService.checkOperation(TARGET_OP,
578 uid, packageName) != AppOpsManager.MODE_ALLOWED;
579 } catch (RemoteException e) {
580 // Shouldn't happen
581 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800582 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800583 if (updateForcedAppStandbyUidPackageLocked(uid, packageName, restricted)) {
584 mHandler.notifyRunAnyAppOpsChanged(uid, packageName);
585 }
586 }
587 }
588 }
Makoto Onuki9be01402017-11-10 13:22:26 -0800589
Makoto Onuki2206af32017-11-21 16:25:35 -0800590 private final class MyReceiver extends BroadcastReceiver {
591 @Override
592 public void onReceive(Context context, Intent intent) {
593 if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
594 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
595 if (userId > 0) {
596 mHandler.doUserRemoved(userId);
Makoto Onuki9be01402017-11-10 13:22:26 -0800597 }
Nancy Zheng525aaa12018-01-12 11:45:37 -0800598 } else if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
599 synchronized (mLock) {
600 mIsPluggedIn = (intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0);
601 }
602 updateForceAllAppStandbyState();
Makoto Onuki9be01402017-11-10 13:22:26 -0800603 }
604 }
605 }
606
607 private Listener[] cloneListeners() {
608 synchronized (mLock) {
609 return mListeners.toArray(new Listener[mListeners.size()]);
610 }
611 }
612
Makoto Onuki2206af32017-11-21 16:25:35 -0800613 private class MyHandler extends Handler {
614 private static final int MSG_UID_STATE_CHANGED = 1;
615 private static final int MSG_RUN_ANY_CHANGED = 2;
616 private static final int MSG_ALL_UNWHITELISTED = 3;
617 private static final int MSG_ALL_WHITELIST_CHANGED = 4;
618 private static final int MSG_TEMP_WHITELIST_CHANGED = 5;
619 private static final int MSG_FORCE_ALL_CHANGED = 6;
Makoto Onuki2206af32017-11-21 16:25:35 -0800620 private static final int MSG_USER_REMOVED = 7;
Nancy Zheng525aaa12018-01-12 11:45:37 -0800621 private static final int MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED = 8;
Makoto Onuki9be01402017-11-10 13:22:26 -0800622
Makoto Onuki2206af32017-11-21 16:25:35 -0800623 public MyHandler(Looper looper) {
624 super(looper);
Makoto Onuki9be01402017-11-10 13:22:26 -0800625 }
Makoto Onuki2206af32017-11-21 16:25:35 -0800626
627 public void notifyUidForegroundStateChanged(int uid) {
628 obtainMessage(MSG_UID_STATE_CHANGED, uid, 0).sendToTarget();
629 }
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800630
Makoto Onuki2206af32017-11-21 16:25:35 -0800631 public void notifyRunAnyAppOpsChanged(int uid, @NonNull String packageName) {
632 obtainMessage(MSG_RUN_ANY_CHANGED, uid, 0, packageName).sendToTarget();
633 }
634
635 public void notifyAllUnwhitelisted() {
636 obtainMessage(MSG_ALL_UNWHITELISTED).sendToTarget();
637 }
638
639 public void notifyAllWhitelistChanged() {
640 obtainMessage(MSG_ALL_WHITELIST_CHANGED).sendToTarget();
641 }
642
643 public void notifyTempWhitelistChanged() {
644 obtainMessage(MSG_TEMP_WHITELIST_CHANGED).sendToTarget();
645 }
646
647 public void notifyForceAllAppsStandbyChanged() {
648 obtainMessage(MSG_FORCE_ALL_CHANGED).sendToTarget();
649 }
650
Nancy Zheng525aaa12018-01-12 11:45:37 -0800651 public void notifyForcedAppStandbyFeatureFlagChanged() {
652 obtainMessage(MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED).sendToTarget();
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800653 }
654
Makoto Onuki2206af32017-11-21 16:25:35 -0800655 public void doUserRemoved(int userId) {
656 obtainMessage(MSG_USER_REMOVED, userId, 0).sendToTarget();
657 }
658
659 @Override
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800660 public void handleMessage(Message msg) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800661 switch (msg.what) {
662 case MSG_USER_REMOVED:
663 handleUserRemoved(msg.arg1);
664 return;
665 }
666
667 // Only notify the listeners when started.
668 synchronized (mLock) {
669 if (!mStarted) {
670 return;
671 }
672 }
673 final ForceAppStandbyTracker sender = ForceAppStandbyTracker.this;
674
675 switch (msg.what) {
676 case MSG_UID_STATE_CHANGED:
677 for (Listener l : cloneListeners()) {
678 l.onUidForegroundStateChanged(sender, msg.arg1);
679 }
680 return;
681 case MSG_RUN_ANY_CHANGED:
682 for (Listener l : cloneListeners()) {
683 l.onRunAnyAppOpsChanged(sender, msg.arg1, (String) msg.obj);
684 }
685 return;
686 case MSG_ALL_UNWHITELISTED:
687 for (Listener l : cloneListeners()) {
688 l.onPowerSaveUnwhitelisted(sender);
689 }
690 return;
691 case MSG_ALL_WHITELIST_CHANGED:
692 for (Listener l : cloneListeners()) {
693 l.onPowerSaveWhitelistedChanged(sender);
694 }
695 return;
696 case MSG_TEMP_WHITELIST_CHANGED:
697 for (Listener l : cloneListeners()) {
698 l.onTempPowerSaveWhitelistChanged(sender);
699 }
700 return;
701 case MSG_FORCE_ALL_CHANGED:
702 for (Listener l : cloneListeners()) {
703 l.onForceAllAppsStandbyChanged(sender);
704 }
705 return;
Nancy Zheng525aaa12018-01-12 11:45:37 -0800706 case MSG_FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED:
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800707 // Feature flag for forced app standby changed.
708 final boolean unblockAlarms;
709 synchronized (mLock) {
710 unblockAlarms = !mForcedAppStandbyEnabled && !mForceAllAppsStandby;
711 }
Suprabh Shuklac25447d2018-01-19 16:43:35 -0800712 for (Listener l : cloneListeners()) {
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800713 l.updateAllJobs();
714 if (unblockAlarms) {
715 l.unblockAllUnrestrictedAlarms();
716 }
717 }
718 return;
Makoto Onuki2206af32017-11-21 16:25:35 -0800719 case MSG_USER_REMOVED:
720 handleUserRemoved(msg.arg1);
721 return;
722 }
723 }
724 }
725
726 void handleUserRemoved(int removedUserId) {
727 synchronized (mLock) {
728 for (int i = mRunAnyRestrictedPackages.size() - 1; i >= 0; i--) {
729 final Pair<Integer, String> pair = mRunAnyRestrictedPackages.valueAt(i);
730 final int uid = pair.first;
731 final int userId = UserHandle.getUserId(uid);
732
733 if (userId == removedUserId) {
734 mRunAnyRestrictedPackages.removeAt(i);
735 }
736 }
737 for (int i = mForegroundUids.size() - 1; i >= 0; i--) {
738 final int uid = mForegroundUids.keyAt(i);
739 final int userId = UserHandle.getUserId(uid);
740
741 if (userId == removedUserId) {
742 mForegroundUids.removeAt(i);
743 }
744 }
745 }
746 }
747
748 /**
749 * Called by device idle controller to update the power save whitelists.
750 */
751 public void setPowerSaveWhitelistAppIds(
752 int[] powerSaveWhitelistAllAppIdArray, int[] tempWhitelistAppIdArray) {
753 synchronized (mLock) {
754 final int[] previousWhitelist = mPowerWhitelistedAllAppIds;
755 final int[] previousTempWhitelist = mTempWhitelistedAppIds;
756
757 mPowerWhitelistedAllAppIds = powerSaveWhitelistAllAppIdArray;
758 mTempWhitelistedAppIds = tempWhitelistAppIdArray;
759
760 if (isAnyAppIdUnwhitelisted(previousWhitelist, mPowerWhitelistedAllAppIds)) {
761 mHandler.notifyAllUnwhitelisted();
762 } else if (!Arrays.equals(previousWhitelist, mPowerWhitelistedAllAppIds)) {
763 mHandler.notifyAllWhitelistChanged();
764 }
765
766 if (!Arrays.equals(previousTempWhitelist, mTempWhitelistedAppIds)) {
767 mHandler.notifyTempWhitelistChanged();
768 }
769
770 }
771 }
772
773 /**
774 * @retunr true if a sorted app-id array {@code prevArray} has at least one element
775 * that's not in a sorted app-id array {@code newArray}.
776 */
777 @VisibleForTesting
778 static boolean isAnyAppIdUnwhitelisted(int[] prevArray, int[] newArray) {
779 int i1 = 0;
780 int i2 = 0;
781 boolean prevFinished;
782 boolean newFinished;
783
784 for (;;) {
785 prevFinished = i1 >= prevArray.length;
786 newFinished = i2 >= newArray.length;
787 if (prevFinished || newFinished) {
788 break;
789 }
790 int a1 = prevArray[i1];
791 int a2 = newArray[i2];
792
793 if (a1 == a2) {
794 i1++;
795 i2++;
796 continue;
797 }
798 if (a1 < a2) {
799 // prevArray has an element that's not in a2.
800 return true;
801 }
802 i2++;
803 }
804 if (prevFinished) {
805 return false;
806 }
807 return newFinished;
Makoto Onuki9be01402017-11-10 13:22:26 -0800808 }
809
810 // Public interface.
811
812 /**
813 * Register a new listener.
814 */
815 public void addListener(@NonNull Listener listener) {
816 synchronized (mLock) {
817 mListeners.add(listener);
818 }
819 }
820
821 /**
Makoto Onuki2206af32017-11-21 16:25:35 -0800822 * @return whether alarms should be restricted for a UID package-name.
Makoto Onuki9be01402017-11-10 13:22:26 -0800823 */
Suprabh Shuklac25447d2018-01-19 16:43:35 -0800824 public boolean areAlarmsRestricted(int uid, @NonNull String packageName,
825 boolean allowWhileIdle) {
Makoto Onukieb8cfd12018-01-19 15:43:16 -0800826 return isRestricted(uid, packageName, /*useTempWhitelistToo=*/ false,
Suprabh Shuklac25447d2018-01-19 16:43:35 -0800827 /* exemptOnBatterySaver =*/ allowWhileIdle);
Makoto Onuki2206af32017-11-21 16:25:35 -0800828 }
829
830 /**
831 * @return whether jobs should be restricted for a UID package-name.
832 */
Makoto Onuki15407842018-01-19 14:23:11 -0800833 public boolean areJobsRestricted(int uid, @NonNull String packageName,
834 boolean hasForegroundExemption) {
Makoto Onukieb8cfd12018-01-19 15:43:16 -0800835 return isRestricted(uid, packageName, /*useTempWhitelistToo=*/ true,
Makoto Onuki15407842018-01-19 14:23:11 -0800836 hasForegroundExemption);
Makoto Onuki2206af32017-11-21 16:25:35 -0800837 }
838
839 /**
840 * @return whether force-app-standby is effective for a UID package-name.
841 */
842 private boolean isRestricted(int uid, @NonNull String packageName,
Makoto Onukieb8cfd12018-01-19 15:43:16 -0800843 boolean useTempWhitelistToo, boolean exemptOnBatterySaver) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800844 if (isInForeground(uid)) {
845 return false;
846 }
847 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800848 // Whitelisted?
849 final int appId = UserHandle.getAppId(uid);
850 if (ArrayUtils.contains(mPowerWhitelistedAllAppIds, appId)) {
851 return false;
852 }
853 if (useTempWhitelistToo &&
854 ArrayUtils.contains(mTempWhitelistedAppIds, appId)) {
855 return false;
856 }
Makoto Onukieb8cfd12018-01-19 15:43:16 -0800857 if (mForcedAppStandbyEnabled && isRunAnyRestrictedLocked(uid, packageName)) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800858 return true;
859 }
Makoto Onukieb8cfd12018-01-19 15:43:16 -0800860 if (exemptOnBatterySaver) {
861 return false;
862 }
863 return mForceAllAppsStandby;
Makoto Onuki9be01402017-11-10 13:22:26 -0800864 }
865 }
866
Makoto Onuki2206af32017-11-21 16:25:35 -0800867 /**
868 * @return whether a UID is in the foreground or not.
869 *
Makoto Onuki15407842018-01-19 14:23:11 -0800870 * Note this information is based on the UID proc state callback, meaning it's updated
871 * asynchronously and may subtly be stale. If the fresh data is needed, use
872 * {@link ActivityManagerInternal#getUidProcessState} instead.
Makoto Onuki2206af32017-11-21 16:25:35 -0800873 */
Makoto Onuki9be01402017-11-10 13:22:26 -0800874 public boolean isInForeground(int uid) {
Makoto Onuki9cc471c2018-01-23 12:33:56 -0800875 if (UserHandle.isCore(uid)) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800876 return true;
877 }
878 synchronized (mLock) {
879 return mForegroundUids.get(uid);
880 }
881 }
882
Makoto Onuki2206af32017-11-21 16:25:35 -0800883 /**
884 * @return whether force all apps standby is enabled or not.
885 *
Makoto Onuki2206af32017-11-21 16:25:35 -0800886 */
887 boolean isForceAllAppsStandbyEnabled() {
Makoto Onuki9be01402017-11-10 13:22:26 -0800888 synchronized (mLock) {
889 return mForceAllAppsStandby;
890 }
891 }
892
Makoto Onuki2206af32017-11-21 16:25:35 -0800893 /**
894 * @return whether a UID/package has {@code OP_RUN_ANY_IN_BACKGROUND} allowed or not.
895 *
896 * Note clients normally shouldn't need to access it. It's only for dumpsys.
897 */
Makoto Onuki9be01402017-11-10 13:22:26 -0800898 public boolean isRunAnyInBackgroundAppOpsAllowed(int uid, @NonNull String packageName) {
899 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800900 return !isRunAnyRestrictedLocked(uid, packageName);
Makoto Onuki9be01402017-11-10 13:22:26 -0800901 }
902 }
903
Makoto Onuki2206af32017-11-21 16:25:35 -0800904 /**
905 * @return whether a UID is in the user / system defined power-save whitelist or not.
906 *
907 * Note clients normally shouldn't need to access it. It's only for dumpsys.
908 */
909 public boolean isUidPowerSaveWhitelisted(int uid) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800910 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800911 return ArrayUtils.contains(mPowerWhitelistedAllAppIds, UserHandle.getAppId(uid));
Makoto Onuki9be01402017-11-10 13:22:26 -0800912 }
913 }
914
Makoto Onuki2206af32017-11-21 16:25:35 -0800915 /**
916 * @return whether a UID is in the temp power-save whitelist or not.
917 *
918 * Note clients normally shouldn't need to access it. It's only for dumpsys.
919 */
920 public boolean isUidTempPowerSaveWhitelisted(int uid) {
Makoto Onuki9be01402017-11-10 13:22:26 -0800921 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -0800922 return ArrayUtils.contains(mTempWhitelistedAppIds, UserHandle.getAppId(uid));
923 }
924 }
925
926 public void dump(PrintWriter pw, String indent) {
927 synchronized (mLock) {
928 pw.print(indent);
Suprabh Shukla4deb8522018-01-08 16:27:10 -0800929 pw.println("Forced App Standby Feature enabled: " + mForcedAppStandbyEnabled);
930
931 pw.print(indent);
Makoto Onuki2206af32017-11-21 16:25:35 -0800932 pw.print("Force all apps standby: ");
933 pw.println(isForceAllAppsStandbyEnabled());
934
935 pw.print(indent);
Nancy Zheng525aaa12018-01-12 11:45:37 -0800936 pw.print("Small Battery Device: ");
937 pw.println(isSmallBatteryDevice());
938
939 pw.print(indent);
940 pw.print("Force all apps standby for small battery device: ");
941 pw.println(mForceAllAppStandbyForSmallBattery);
942
943 pw.print(indent);
944 pw.print("Plugged In: ");
945 pw.println(mIsPluggedIn);
946
947 pw.print(indent);
Makoto Onuki2206af32017-11-21 16:25:35 -0800948 pw.print("Foreground uids: [");
949
950 String sep = "";
951 for (int i = 0; i < mForegroundUids.size(); i++) {
952 if (mForegroundUids.valueAt(i)) {
953 pw.print(sep);
954 pw.print(UserHandle.formatUid(mForegroundUids.keyAt(i)));
955 sep = " ";
956 }
957 }
958 pw.println("]");
959
960 pw.print(indent);
961 pw.print("Whitelist appids: ");
962 pw.println(Arrays.toString(mPowerWhitelistedAllAppIds));
963
964 pw.print(indent);
965 pw.print("Temp whitelist appids: ");
966 pw.println(Arrays.toString(mTempWhitelistedAppIds));
967
968 pw.print(indent);
969 pw.println("Restricted packages:");
970 for (Pair<Integer, String> uidAndPackage : mRunAnyRestrictedPackages) {
971 pw.print(indent);
972 pw.print(" ");
973 pw.print(UserHandle.formatUid(uidAndPackage.first));
974 pw.print(" ");
975 pw.print(uidAndPackage.second);
976 pw.println();
977 }
978 }
979 }
980
981 public void dumpProto(ProtoOutputStream proto, long fieldId) {
982 synchronized (mLock) {
983 final long token = proto.start(fieldId);
984
985 proto.write(ForceAppStandbyTrackerProto.FORCE_ALL_APPS_STANDBY, mForceAllAppsStandby);
Nancy Zheng525aaa12018-01-12 11:45:37 -0800986 proto.write(ForceAppStandbyTrackerProto.IS_SMALL_BATTERY_DEVICE,
987 isSmallBatteryDevice());
988 proto.write(ForceAppStandbyTrackerProto.FORCE_ALL_APPS_STANDBY_FOR_SMALL_BATTERY,
989 mForceAllAppStandbyForSmallBattery);
990 proto.write(ForceAppStandbyTrackerProto.IS_CHARGING, mIsPluggedIn);
Makoto Onuki2206af32017-11-21 16:25:35 -0800991
992 for (int i = 0; i < mForegroundUids.size(); i++) {
993 if (mForegroundUids.valueAt(i)) {
994 proto.write(ForceAppStandbyTrackerProto.FOREGROUND_UIDS,
995 mForegroundUids.keyAt(i));
996 }
997 }
998
999 for (int appId : mPowerWhitelistedAllAppIds) {
1000 proto.write(ForceAppStandbyTrackerProto.POWER_SAVE_WHITELIST_APP_IDS, appId);
1001 }
1002
1003 for (int appId : mTempWhitelistedAppIds) {
1004 proto.write(ForceAppStandbyTrackerProto.TEMP_POWER_SAVE_WHITELIST_APP_IDS, appId);
1005 }
1006
1007 for (Pair<Integer, String> uidAndPackage : mRunAnyRestrictedPackages) {
1008 final long token2 = proto.start(
1009 ForceAppStandbyTrackerProto.RUN_ANY_IN_BACKGROUND_RESTRICTED_PACKAGES);
1010 proto.write(RunAnyInBackgroundRestrictedPackages.UID, uidAndPackage.first);
1011 proto.write(RunAnyInBackgroundRestrictedPackages.PACKAGE_NAME,
1012 uidAndPackage.second);
1013 proto.end(token2);
1014 }
1015 proto.end(token);
Makoto Onuki9be01402017-11-10 13:22:26 -08001016 }
1017 }
1018}