Loading core/proto/android/server/alarmmanagerservice.proto +4 −4 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import "frameworks/base/core/proto/android/app/alarmmanager.proto"; import "frameworks/base/core/proto/android/app/pendingintent.proto"; import "frameworks/base/core/proto/android/internal/locallog.proto"; import "frameworks/base/core/proto/android/os/worksource.proto"; import "frameworks/base/core/proto/android/server/forceappstandbytracker.proto"; package com.android.server; Loading @@ -32,10 +33,9 @@ message AlarmManagerServiceProto { optional int64 last_time_change_realtime = 4; // Current settings optional ConstantsProto settings = 5; // UIDs currently in the foreground. repeated int32 foreground_uids = 6; // Packages forced into app standby. repeated string forced_app_standby_packages = 7; // Dump from ForceAppStandbyTracker. optional ForceAppStandbyTrackerProto force_app_standby_tracker = 6; optional bool is_interactive = 8; // Only valid if is_interactive is false. Loading core/proto/android/server/forceappstandbytracker.proto 0 → 100644 +44 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ syntax = "proto2"; package com.android.server; option java_multiple_files = true; // Dump from ForceAppStandbyTracker. message ForceAppStandbyTrackerProto { // Whether all apps are forced standby or not. optional bool force_all_apps_standby = 1; // UIDs currently in the foreground. repeated int32 foreground_uids = 2; // App ids that are in power-save whitelist. repeated int32 power_save_whitelist_app_ids = 3; // App ids that are in temporary power-save whitelist. repeated int32 temp_power_save_whitelist_app_ids = 4; message RunAnyInBackgroundRestrictedPackages { optional int32 uid = 1; optional string package_name = 2; } // Packages that are disallowed OP_RUN_ANY_IN_BACKGROUND. repeated RunAnyInBackgroundRestrictedPackages run_any_in_background_restricted_packages = 5; } services/core/java/com/android/server/AlarmManagerService.java +81 −109 Original line number Diff line number Diff line Loading @@ -46,7 +46,6 @@ import android.os.Message; import android.os.PowerManager; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; import android.os.SystemProperties; import android.os.Trace; Loading @@ -56,7 +55,6 @@ import android.provider.Settings; import android.text.TextUtils; import android.text.format.DateFormat; import android.util.ArrayMap; import android.util.ArraySet; import android.util.KeyValueListParser; import android.util.Log; import android.util.Slog; Loading @@ -82,6 +80,7 @@ import java.util.Locale; import java.util.Random; import java.util.TimeZone; import java.util.TreeSet; import java.util.function.Predicate; import static android.app.AlarmManager.RTC_WAKEUP; import static android.app.AlarmManager.RTC; Loading @@ -89,11 +88,17 @@ import static android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP; import static android.app.AlarmManager.ELAPSED_REALTIME; import com.android.internal.annotations.GuardedBy; import com.android.internal.app.IAppOpsCallback; import com.android.internal.app.IAppOpsService; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.DumpUtils; import com.android.internal.util.LocalLog; import com.android.server.ForceAppStandbyTracker.Listener; /** * Alarm manager implementaion. * * Unit test: atest $ANDROID_BUILD_TOP/frameworks/base/services/tests/servicestests/src/com/android/server/AlarmManagerServiceTest.java */ class AlarmManagerService extends SystemService { private static final int RTC_WAKEUP_MASK = 1 << RTC_WAKEUP; private static final int RTC_MASK = 1 << RTC; Loading Loading @@ -132,13 +137,10 @@ class AlarmManagerService extends SystemService { final LocalLog mLog = new LocalLog(TAG); AppOpsManager mAppOps; IAppOpsService mAppOpsService; DeviceIdleController.LocalService mLocalDeviceIdleController; final Object mLock = new Object(); ArraySet<String> mForcedAppStandbyPackages = new ArraySet<>(); SparseBooleanArray mForegroundUids = new SparseBooleanArray(); // List of alarms per uid deferred due to user applied background restrictions on the source app SparseArray<ArrayList<Alarm>> mPendingBackgroundAlarms = new SparseArray<>(); long mNativeData; Loading Loading @@ -184,12 +186,6 @@ class AlarmManagerService extends SystemService { */ int mSystemUiUid; /** * The current set of user whitelisted apps for device idle mode, meaning these are allowed * to freely schedule alarms. */ int[] mDeviceIdleUserWhitelist = new int[0]; /** * For each uid, this is the last time we dispatched an "allow while idle" alarm, * used to determine the earliest we can dispatch the next such alarm. Times are in the Loading Loading @@ -224,6 +220,8 @@ class AlarmManagerService extends SystemService { private final SparseArray<AlarmManager.AlarmClockInfo> mHandlerSparseAlarmClockArray = new SparseArray<>(); private final ForceAppStandbyTracker mForceAppStandbyTracker; /** * All times are in milliseconds. These constants are kept synchronized with the system * global Settings. Any access to this class or its fields should be done while Loading Loading @@ -758,6 +756,9 @@ class AlarmManagerService extends SystemService { public AlarmManagerService(Context context) { super(context); mConstants = new Constants(mHandler); mForceAppStandbyTracker = ForceAppStandbyTracker.getInstance(context); mForceAppStandbyTracker.addListener(mForceAppStandbyListener); } static long convertToElapsed(long when, int type) { Loading Loading @@ -895,17 +896,48 @@ class AlarmManagerService extends SystemService { deliverPendingBackgroundAlarmsLocked(alarmsToDeliver, SystemClock.elapsedRealtime()); } void sendPendingBackgroundAlarmsForAppIdLocked(int appId) { /** * Check all alarms in {@link #mPendingBackgroundAlarms} and send the ones that are not * restricted. * * This is only called when the global "force all apps-standby" flag changes or when the * power save whitelist changes, so it's okay to be slow. */ void sendAllUnrestrictedPendingBackgroundAlarmsLocked() { final ArrayList<Alarm> alarmsToDeliver = new ArrayList<>(); for (int i = mPendingBackgroundAlarms.size() - 1; i >= 0; i--) { final int uid = mPendingBackgroundAlarms.keyAt(i); final ArrayList<Alarm> alarmsForUid = mPendingBackgroundAlarms.valueAt(i); if (UserHandle.getAppId(uid) == appId) { alarmsToDeliver.addAll(alarmsForUid); mPendingBackgroundAlarms.removeAt(i); findAllUnrestrictedPendingBackgroundAlarmsLockedInner( mPendingBackgroundAlarms, alarmsToDeliver, this::isBackgroundRestricted); if (alarmsToDeliver.size() > 0) { deliverPendingBackgroundAlarmsLocked(alarmsToDeliver, SystemClock.elapsedRealtime()); } } @VisibleForTesting static void findAllUnrestrictedPendingBackgroundAlarmsLockedInner( SparseArray<ArrayList<Alarm>> pendingAlarms, ArrayList<Alarm> unrestrictedAlarms, Predicate<Alarm> isBackgroundRestricted) { for (int uidIndex = pendingAlarms.size() - 1; uidIndex >= 0; uidIndex--) { final int uid = pendingAlarms.keyAt(uidIndex); final ArrayList<Alarm> alarmsForUid = pendingAlarms.valueAt(uidIndex); for (int alarmIndex = alarmsForUid.size() - 1; alarmIndex >= 0; alarmIndex--) { final Alarm alarm = alarmsForUid.get(alarmIndex); if (isBackgroundRestricted.test(alarm)) { continue; } unrestrictedAlarms.add(alarm); alarmsForUid.remove(alarmIndex); } if (alarmsForUid.size() == 0) { pendingAlarms.removeAt(uidIndex); } } deliverPendingBackgroundAlarmsLocked(alarmsToDeliver, SystemClock.elapsedRealtime()); } private void deliverPendingBackgroundAlarmsLocked(ArrayList<Alarm> alarms, long nowELAPSED) { Loading Loading @@ -1235,10 +1267,8 @@ class AlarmManagerService extends SystemService { } catch (RemoteException e) { // ignored; both services live in system_server } mAppOpsService = IAppOpsService.Stub.asInterface( ServiceManager.getService(Context.APP_OPS_SERVICE)); publishBinderService(Context.ALARM_SERVICE, mService); publishLocalService(LocalService.class, new LocalService()); mForceAppStandbyTracker.start(); } @Override Loading @@ -1248,13 +1278,6 @@ class AlarmManagerService extends SystemService { mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE); mLocalDeviceIdleController = LocalServices.getService(DeviceIdleController.LocalService.class); try { mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, null, new AppOpsWatcher()); } catch (RemoteException rexc) { // Shouldn't happen as they are in the same process. Slog.e(TAG, "AppOps service not reachable", rexc); } } } Loading Loading @@ -1583,8 +1606,7 @@ class AlarmManagerService extends SystemService { // timing restrictions. } else if (workSource == null && (callingUid < Process.FIRST_APPLICATION_UID || callingUid == mSystemUiUid || Arrays.binarySearch(mDeviceIdleUserWhitelist, UserHandle.getAppId(callingUid)) >= 0)) { || mForceAppStandbyTracker.isUidPowerSaveWhitelisted(callingUid))) { flags |= AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED; flags &= ~AlarmManager.FLAG_ALLOW_WHILE_IDLE; } Loading Loading @@ -1661,24 +1683,14 @@ class AlarmManagerService extends SystemService { } }; public final class LocalService { public void setDeviceIdleUserWhitelist(int[] appids) { setDeviceIdleUserWhitelistImpl(appids); } } void dumpImpl(PrintWriter pw) { synchronized (mLock) { pw.println("Current Alarm Manager state:"); mConstants.dump(pw); pw.println(); pw.print(" Foreground uids: ["); for (int i = 0; i < mForegroundUids.size(); i++) { if (mForegroundUids.valueAt(i)) pw.print(mForegroundUids.keyAt(i) + " "); } pw.println("]"); pw.println(" Forced app standby packages: " + mForcedAppStandbyPackages); mForceAppStandbyTracker.dump(pw, " "); final long nowRTC = System.currentTimeMillis(); final long nowELAPSED = SystemClock.elapsedRealtime(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Loading Loading @@ -1718,7 +1730,6 @@ class AlarmManagerService extends SystemService { pw.print(" set at "); TimeUtils.formatDuration(mLastWakeupSet, nowELAPSED, pw); pw.println(); pw.print(" Num time change events: "); pw.println(mNumTimeChanged); pw.println(" mDeviceIdleUserWhitelist=" + Arrays.toString(mDeviceIdleUserWhitelist)); pw.println(); pw.println(" Next alarm clock information: "); Loading Loading @@ -1991,15 +2002,8 @@ class AlarmManagerService extends SystemService { mConstants.dumpProto(proto, AlarmManagerServiceProto.SETTINGS); final int foregroundUidsSize = mForegroundUids.size(); for (int i = 0; i < foregroundUidsSize; i++) { if (mForegroundUids.valueAt(i)) { proto.write(AlarmManagerServiceProto.FOREGROUND_UIDS, mForegroundUids.keyAt(i)); } } for (String pkg : mForcedAppStandbyPackages) { proto.write(AlarmManagerServiceProto.FORCED_APP_STANDBY_PACKAGES, pkg); } mForceAppStandbyTracker.dumpProto(proto, AlarmManagerServiceProto.FORCE_APP_STANDBY_TRACKER); proto.write(AlarmManagerServiceProto.IS_INTERACTIVE, mInteractive); if (!mInteractive) { Loading @@ -2023,9 +2027,6 @@ class AlarmManagerService extends SystemService { proto.write(AlarmManagerServiceProto.TIME_SINCE_LAST_WAKEUP_SET_MS, nowElapsed - mLastWakeupSet); proto.write(AlarmManagerServiceProto.TIME_CHANGE_EVENT_COUNT, mNumTimeChanged); for (int i : mDeviceIdleUserWhitelist) { proto.write(AlarmManagerServiceProto.DEVICE_IDLE_USER_WHITELIST_APP_IDS, i); } final TreeSet<Integer> users = new TreeSet<>(); final int nextAlarmClockForUserSize = mNextAlarmClockForUser.size(); Loading Loading @@ -2267,28 +2268,6 @@ class AlarmManagerService extends SystemService { } } void setDeviceIdleUserWhitelistImpl(int[] appids) { synchronized (mLock) { // appids are sorted, just send pending alarms for any new appids added to the whitelist int i = 0, j = 0; while (i < appids.length) { while (j < mDeviceIdleUserWhitelist.length && mDeviceIdleUserWhitelist[j] < appids[i]) { j++; } if (j < mDeviceIdleUserWhitelist.length && appids[i] != mDeviceIdleUserWhitelist[j]) { if (DEBUG_BG_LIMIT) { Slog.d(TAG, "Sending blocked alarms for whitelisted appid " + appids[j]); } sendPendingBackgroundAlarmsForAppIdLocked(appids[j]); } i++; } mDeviceIdleUserWhitelist = appids; } } AlarmManager.AlarmClockInfo getNextAlarmClockImpl(int userId) { synchronized (mLock) { return mNextAlarmClockForUser.get(userId); Loading Loading @@ -2711,9 +2690,7 @@ class AlarmManagerService extends SystemService { final String sourcePackage = (alarm.operation != null) ? alarm.operation.getCreatorPackage() : alarm.packageName; final int sourceUid = alarm.creatorUid; return mForcedAppStandbyPackages.contains(sourcePackage) && !mForegroundUids.get(sourceUid) && Arrays.binarySearch(mDeviceIdleUserWhitelist, UserHandle.getAppId(sourceUid)) < 0; return mForceAppStandbyTracker.areAlarmsRestricted(sourceUid, sourcePackage); } private native long init(); Loading Loading @@ -2860,7 +2837,8 @@ class AlarmManagerService extends SystemService { } } private static class Alarm { @VisibleForTesting static class Alarm { public final int type; public final long origWhen; public final boolean wakeup; Loading Loading @@ -3483,17 +3461,10 @@ class AlarmManagerService extends SystemService { if (disabled) { removeForStoppedLocked(uid); } mForegroundUids.delete(uid); } } @Override public void onUidActive(int uid) { synchronized (mLock) { if (!mForegroundUids.get(uid)) { mForegroundUids.put(uid, true); sendPendingBackgroundAlarmsLocked(uid, null); } } } @Override public void onUidIdle(int uid, boolean disabled) { Loading @@ -3501,7 +3472,6 @@ class AlarmManagerService extends SystemService { if (disabled) { removeForStoppedLocked(uid); } mForegroundUids.delete(uid); } } Loading @@ -3509,27 +3479,29 @@ class AlarmManagerService extends SystemService { } }; private final class AppOpsWatcher extends IAppOpsCallback.Stub { private final Listener mForceAppStandbyListener = new Listener() { @Override public void opChanged(int op, int uid, String packageName) throws RemoteException { public void unblockAllUnrestrictedAlarms() { synchronized (mLock) { final int mode = mAppOpsService.checkOperation(op, uid, packageName); if (DEBUG_BG_LIMIT) { Slog.d(TAG, "Appop changed for " + uid + ", " + packageName + " to " + mode); sendAllUnrestrictedPendingBackgroundAlarmsLocked(); } final boolean changed; if (mode != AppOpsManager.MODE_ALLOWED) { changed = mForcedAppStandbyPackages.add(packageName); } else { changed = mForcedAppStandbyPackages.remove(packageName); } if (changed && mode == AppOpsManager.MODE_ALLOWED) { sendPendingBackgroundAlarmsLocked(uid, packageName); @Override public void unblockAlarmsForUid(int uid) { synchronized (mLock) { sendPendingBackgroundAlarmsLocked(uid, null); } } @Override public void unblockAlarmsForUidPackage(int uid, String packageName) { synchronized (mLock) { sendPendingBackgroundAlarmsLocked(uid, packageName); } } }; private final BroadcastStats getStatsLocked(PendingIntent pi) { String pkg = pi.getCreatorPackage(); Loading services/core/java/com/android/server/DeviceIdleController.java +9 −10 Original line number Diff line number Diff line Loading @@ -119,7 +119,6 @@ public class DeviceIdleController extends SystemService private PowerManagerInternal mLocalPowerManager; private PowerManager mPowerManager; private ConnectivityService mConnectivityService; private AlarmManagerService.LocalService mLocalAlarmManager; private INetworkPolicyManager mNetworkPolicyManager; private SensorManager mSensorManager; private Sensor mMotionSensor; Loading Loading @@ -1435,7 +1434,6 @@ public class DeviceIdleController extends SystemService mGoingIdleWakeLock.setReferenceCounted(true); mConnectivityService = (ConnectivityService)ServiceManager.getService( Context.CONNECTIVITY_SERVICE); mLocalAlarmManager = getLocalService(AlarmManagerService.LocalService.class); mNetworkPolicyManager = INetworkPolicyManager.Stub.asInterface( ServiceManager.getService(Context.NETWORK_POLICY_SERVICE)); mNetworkPolicyManagerInternal = getLocalService(NetworkPolicyManagerInternal.class); Loading Loading @@ -1500,8 +1498,8 @@ public class DeviceIdleController extends SystemService mLocalActivityManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray); mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray); mLocalAlarmManager.setDeviceIdleUserWhitelist(mPowerSaveWhitelistUserAppIdArray); passWhiteListToForceAppStandbyTrackerLocked(); updateInteractivityLocked(); } updateConnectivityState(null); Loading Loading @@ -2477,13 +2475,7 @@ public class DeviceIdleController extends SystemService } mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray); } if (mLocalAlarmManager != null) { if (DEBUG) { Slog.d(TAG, "Setting alarm whitelist to " + Arrays.toString(mPowerSaveWhitelistUserAppIdArray)); } mLocalAlarmManager.setDeviceIdleUserWhitelist(mPowerSaveWhitelistUserAppIdArray); } passWhiteListToForceAppStandbyTrackerLocked(); } private void updateTempWhitelistAppIdsLocked(int appId, boolean adding) { Loading @@ -2509,6 +2501,7 @@ public class DeviceIdleController extends SystemService } mLocalPowerManager.setDeviceIdleTempWhitelist(mTempWhitelistAppIdArray); } passWhiteListToForceAppStandbyTrackerLocked(); } private void reportPowerSaveWhitelistChangedLocked() { Loading @@ -2523,6 +2516,12 @@ public class DeviceIdleController extends SystemService getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM); } private void passWhiteListToForceAppStandbyTrackerLocked() { ForceAppStandbyTracker.getInstance(getContext()).setPowerSaveWhitelistAppIds( mPowerSaveWhitelistAllAppIdArray, mTempWhitelistAppIdArray); } void readConfigFileLocked() { if (DEBUG) Slog.d(TAG, "Reading config from " + mConfigFile.getBaseFile()); mPowerSaveWhitelistUserApps.clear(); Loading services/core/java/com/android/server/ForceAppStandbyTracker.java +537 −85 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/proto/android/server/alarmmanagerservice.proto +4 −4 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import "frameworks/base/core/proto/android/app/alarmmanager.proto"; import "frameworks/base/core/proto/android/app/pendingintent.proto"; import "frameworks/base/core/proto/android/internal/locallog.proto"; import "frameworks/base/core/proto/android/os/worksource.proto"; import "frameworks/base/core/proto/android/server/forceappstandbytracker.proto"; package com.android.server; Loading @@ -32,10 +33,9 @@ message AlarmManagerServiceProto { optional int64 last_time_change_realtime = 4; // Current settings optional ConstantsProto settings = 5; // UIDs currently in the foreground. repeated int32 foreground_uids = 6; // Packages forced into app standby. repeated string forced_app_standby_packages = 7; // Dump from ForceAppStandbyTracker. optional ForceAppStandbyTrackerProto force_app_standby_tracker = 6; optional bool is_interactive = 8; // Only valid if is_interactive is false. Loading
core/proto/android/server/forceappstandbytracker.proto 0 → 100644 +44 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ syntax = "proto2"; package com.android.server; option java_multiple_files = true; // Dump from ForceAppStandbyTracker. message ForceAppStandbyTrackerProto { // Whether all apps are forced standby or not. optional bool force_all_apps_standby = 1; // UIDs currently in the foreground. repeated int32 foreground_uids = 2; // App ids that are in power-save whitelist. repeated int32 power_save_whitelist_app_ids = 3; // App ids that are in temporary power-save whitelist. repeated int32 temp_power_save_whitelist_app_ids = 4; message RunAnyInBackgroundRestrictedPackages { optional int32 uid = 1; optional string package_name = 2; } // Packages that are disallowed OP_RUN_ANY_IN_BACKGROUND. repeated RunAnyInBackgroundRestrictedPackages run_any_in_background_restricted_packages = 5; }
services/core/java/com/android/server/AlarmManagerService.java +81 −109 Original line number Diff line number Diff line Loading @@ -46,7 +46,6 @@ import android.os.Message; import android.os.PowerManager; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; import android.os.SystemProperties; import android.os.Trace; Loading @@ -56,7 +55,6 @@ import android.provider.Settings; import android.text.TextUtils; import android.text.format.DateFormat; import android.util.ArrayMap; import android.util.ArraySet; import android.util.KeyValueListParser; import android.util.Log; import android.util.Slog; Loading @@ -82,6 +80,7 @@ import java.util.Locale; import java.util.Random; import java.util.TimeZone; import java.util.TreeSet; import java.util.function.Predicate; import static android.app.AlarmManager.RTC_WAKEUP; import static android.app.AlarmManager.RTC; Loading @@ -89,11 +88,17 @@ import static android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP; import static android.app.AlarmManager.ELAPSED_REALTIME; import com.android.internal.annotations.GuardedBy; import com.android.internal.app.IAppOpsCallback; import com.android.internal.app.IAppOpsService; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.DumpUtils; import com.android.internal.util.LocalLog; import com.android.server.ForceAppStandbyTracker.Listener; /** * Alarm manager implementaion. * * Unit test: atest $ANDROID_BUILD_TOP/frameworks/base/services/tests/servicestests/src/com/android/server/AlarmManagerServiceTest.java */ class AlarmManagerService extends SystemService { private static final int RTC_WAKEUP_MASK = 1 << RTC_WAKEUP; private static final int RTC_MASK = 1 << RTC; Loading Loading @@ -132,13 +137,10 @@ class AlarmManagerService extends SystemService { final LocalLog mLog = new LocalLog(TAG); AppOpsManager mAppOps; IAppOpsService mAppOpsService; DeviceIdleController.LocalService mLocalDeviceIdleController; final Object mLock = new Object(); ArraySet<String> mForcedAppStandbyPackages = new ArraySet<>(); SparseBooleanArray mForegroundUids = new SparseBooleanArray(); // List of alarms per uid deferred due to user applied background restrictions on the source app SparseArray<ArrayList<Alarm>> mPendingBackgroundAlarms = new SparseArray<>(); long mNativeData; Loading Loading @@ -184,12 +186,6 @@ class AlarmManagerService extends SystemService { */ int mSystemUiUid; /** * The current set of user whitelisted apps for device idle mode, meaning these are allowed * to freely schedule alarms. */ int[] mDeviceIdleUserWhitelist = new int[0]; /** * For each uid, this is the last time we dispatched an "allow while idle" alarm, * used to determine the earliest we can dispatch the next such alarm. Times are in the Loading Loading @@ -224,6 +220,8 @@ class AlarmManagerService extends SystemService { private final SparseArray<AlarmManager.AlarmClockInfo> mHandlerSparseAlarmClockArray = new SparseArray<>(); private final ForceAppStandbyTracker mForceAppStandbyTracker; /** * All times are in milliseconds. These constants are kept synchronized with the system * global Settings. Any access to this class or its fields should be done while Loading Loading @@ -758,6 +756,9 @@ class AlarmManagerService extends SystemService { public AlarmManagerService(Context context) { super(context); mConstants = new Constants(mHandler); mForceAppStandbyTracker = ForceAppStandbyTracker.getInstance(context); mForceAppStandbyTracker.addListener(mForceAppStandbyListener); } static long convertToElapsed(long when, int type) { Loading Loading @@ -895,17 +896,48 @@ class AlarmManagerService extends SystemService { deliverPendingBackgroundAlarmsLocked(alarmsToDeliver, SystemClock.elapsedRealtime()); } void sendPendingBackgroundAlarmsForAppIdLocked(int appId) { /** * Check all alarms in {@link #mPendingBackgroundAlarms} and send the ones that are not * restricted. * * This is only called when the global "force all apps-standby" flag changes or when the * power save whitelist changes, so it's okay to be slow. */ void sendAllUnrestrictedPendingBackgroundAlarmsLocked() { final ArrayList<Alarm> alarmsToDeliver = new ArrayList<>(); for (int i = mPendingBackgroundAlarms.size() - 1; i >= 0; i--) { final int uid = mPendingBackgroundAlarms.keyAt(i); final ArrayList<Alarm> alarmsForUid = mPendingBackgroundAlarms.valueAt(i); if (UserHandle.getAppId(uid) == appId) { alarmsToDeliver.addAll(alarmsForUid); mPendingBackgroundAlarms.removeAt(i); findAllUnrestrictedPendingBackgroundAlarmsLockedInner( mPendingBackgroundAlarms, alarmsToDeliver, this::isBackgroundRestricted); if (alarmsToDeliver.size() > 0) { deliverPendingBackgroundAlarmsLocked(alarmsToDeliver, SystemClock.elapsedRealtime()); } } @VisibleForTesting static void findAllUnrestrictedPendingBackgroundAlarmsLockedInner( SparseArray<ArrayList<Alarm>> pendingAlarms, ArrayList<Alarm> unrestrictedAlarms, Predicate<Alarm> isBackgroundRestricted) { for (int uidIndex = pendingAlarms.size() - 1; uidIndex >= 0; uidIndex--) { final int uid = pendingAlarms.keyAt(uidIndex); final ArrayList<Alarm> alarmsForUid = pendingAlarms.valueAt(uidIndex); for (int alarmIndex = alarmsForUid.size() - 1; alarmIndex >= 0; alarmIndex--) { final Alarm alarm = alarmsForUid.get(alarmIndex); if (isBackgroundRestricted.test(alarm)) { continue; } unrestrictedAlarms.add(alarm); alarmsForUid.remove(alarmIndex); } if (alarmsForUid.size() == 0) { pendingAlarms.removeAt(uidIndex); } } deliverPendingBackgroundAlarmsLocked(alarmsToDeliver, SystemClock.elapsedRealtime()); } private void deliverPendingBackgroundAlarmsLocked(ArrayList<Alarm> alarms, long nowELAPSED) { Loading Loading @@ -1235,10 +1267,8 @@ class AlarmManagerService extends SystemService { } catch (RemoteException e) { // ignored; both services live in system_server } mAppOpsService = IAppOpsService.Stub.asInterface( ServiceManager.getService(Context.APP_OPS_SERVICE)); publishBinderService(Context.ALARM_SERVICE, mService); publishLocalService(LocalService.class, new LocalService()); mForceAppStandbyTracker.start(); } @Override Loading @@ -1248,13 +1278,6 @@ class AlarmManagerService extends SystemService { mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE); mLocalDeviceIdleController = LocalServices.getService(DeviceIdleController.LocalService.class); try { mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, null, new AppOpsWatcher()); } catch (RemoteException rexc) { // Shouldn't happen as they are in the same process. Slog.e(TAG, "AppOps service not reachable", rexc); } } } Loading Loading @@ -1583,8 +1606,7 @@ class AlarmManagerService extends SystemService { // timing restrictions. } else if (workSource == null && (callingUid < Process.FIRST_APPLICATION_UID || callingUid == mSystemUiUid || Arrays.binarySearch(mDeviceIdleUserWhitelist, UserHandle.getAppId(callingUid)) >= 0)) { || mForceAppStandbyTracker.isUidPowerSaveWhitelisted(callingUid))) { flags |= AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED; flags &= ~AlarmManager.FLAG_ALLOW_WHILE_IDLE; } Loading Loading @@ -1661,24 +1683,14 @@ class AlarmManagerService extends SystemService { } }; public final class LocalService { public void setDeviceIdleUserWhitelist(int[] appids) { setDeviceIdleUserWhitelistImpl(appids); } } void dumpImpl(PrintWriter pw) { synchronized (mLock) { pw.println("Current Alarm Manager state:"); mConstants.dump(pw); pw.println(); pw.print(" Foreground uids: ["); for (int i = 0; i < mForegroundUids.size(); i++) { if (mForegroundUids.valueAt(i)) pw.print(mForegroundUids.keyAt(i) + " "); } pw.println("]"); pw.println(" Forced app standby packages: " + mForcedAppStandbyPackages); mForceAppStandbyTracker.dump(pw, " "); final long nowRTC = System.currentTimeMillis(); final long nowELAPSED = SystemClock.elapsedRealtime(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Loading Loading @@ -1718,7 +1730,6 @@ class AlarmManagerService extends SystemService { pw.print(" set at "); TimeUtils.formatDuration(mLastWakeupSet, nowELAPSED, pw); pw.println(); pw.print(" Num time change events: "); pw.println(mNumTimeChanged); pw.println(" mDeviceIdleUserWhitelist=" + Arrays.toString(mDeviceIdleUserWhitelist)); pw.println(); pw.println(" Next alarm clock information: "); Loading Loading @@ -1991,15 +2002,8 @@ class AlarmManagerService extends SystemService { mConstants.dumpProto(proto, AlarmManagerServiceProto.SETTINGS); final int foregroundUidsSize = mForegroundUids.size(); for (int i = 0; i < foregroundUidsSize; i++) { if (mForegroundUids.valueAt(i)) { proto.write(AlarmManagerServiceProto.FOREGROUND_UIDS, mForegroundUids.keyAt(i)); } } for (String pkg : mForcedAppStandbyPackages) { proto.write(AlarmManagerServiceProto.FORCED_APP_STANDBY_PACKAGES, pkg); } mForceAppStandbyTracker.dumpProto(proto, AlarmManagerServiceProto.FORCE_APP_STANDBY_TRACKER); proto.write(AlarmManagerServiceProto.IS_INTERACTIVE, mInteractive); if (!mInteractive) { Loading @@ -2023,9 +2027,6 @@ class AlarmManagerService extends SystemService { proto.write(AlarmManagerServiceProto.TIME_SINCE_LAST_WAKEUP_SET_MS, nowElapsed - mLastWakeupSet); proto.write(AlarmManagerServiceProto.TIME_CHANGE_EVENT_COUNT, mNumTimeChanged); for (int i : mDeviceIdleUserWhitelist) { proto.write(AlarmManagerServiceProto.DEVICE_IDLE_USER_WHITELIST_APP_IDS, i); } final TreeSet<Integer> users = new TreeSet<>(); final int nextAlarmClockForUserSize = mNextAlarmClockForUser.size(); Loading Loading @@ -2267,28 +2268,6 @@ class AlarmManagerService extends SystemService { } } void setDeviceIdleUserWhitelistImpl(int[] appids) { synchronized (mLock) { // appids are sorted, just send pending alarms for any new appids added to the whitelist int i = 0, j = 0; while (i < appids.length) { while (j < mDeviceIdleUserWhitelist.length && mDeviceIdleUserWhitelist[j] < appids[i]) { j++; } if (j < mDeviceIdleUserWhitelist.length && appids[i] != mDeviceIdleUserWhitelist[j]) { if (DEBUG_BG_LIMIT) { Slog.d(TAG, "Sending blocked alarms for whitelisted appid " + appids[j]); } sendPendingBackgroundAlarmsForAppIdLocked(appids[j]); } i++; } mDeviceIdleUserWhitelist = appids; } } AlarmManager.AlarmClockInfo getNextAlarmClockImpl(int userId) { synchronized (mLock) { return mNextAlarmClockForUser.get(userId); Loading Loading @@ -2711,9 +2690,7 @@ class AlarmManagerService extends SystemService { final String sourcePackage = (alarm.operation != null) ? alarm.operation.getCreatorPackage() : alarm.packageName; final int sourceUid = alarm.creatorUid; return mForcedAppStandbyPackages.contains(sourcePackage) && !mForegroundUids.get(sourceUid) && Arrays.binarySearch(mDeviceIdleUserWhitelist, UserHandle.getAppId(sourceUid)) < 0; return mForceAppStandbyTracker.areAlarmsRestricted(sourceUid, sourcePackage); } private native long init(); Loading Loading @@ -2860,7 +2837,8 @@ class AlarmManagerService extends SystemService { } } private static class Alarm { @VisibleForTesting static class Alarm { public final int type; public final long origWhen; public final boolean wakeup; Loading Loading @@ -3483,17 +3461,10 @@ class AlarmManagerService extends SystemService { if (disabled) { removeForStoppedLocked(uid); } mForegroundUids.delete(uid); } } @Override public void onUidActive(int uid) { synchronized (mLock) { if (!mForegroundUids.get(uid)) { mForegroundUids.put(uid, true); sendPendingBackgroundAlarmsLocked(uid, null); } } } @Override public void onUidIdle(int uid, boolean disabled) { Loading @@ -3501,7 +3472,6 @@ class AlarmManagerService extends SystemService { if (disabled) { removeForStoppedLocked(uid); } mForegroundUids.delete(uid); } } Loading @@ -3509,27 +3479,29 @@ class AlarmManagerService extends SystemService { } }; private final class AppOpsWatcher extends IAppOpsCallback.Stub { private final Listener mForceAppStandbyListener = new Listener() { @Override public void opChanged(int op, int uid, String packageName) throws RemoteException { public void unblockAllUnrestrictedAlarms() { synchronized (mLock) { final int mode = mAppOpsService.checkOperation(op, uid, packageName); if (DEBUG_BG_LIMIT) { Slog.d(TAG, "Appop changed for " + uid + ", " + packageName + " to " + mode); sendAllUnrestrictedPendingBackgroundAlarmsLocked(); } final boolean changed; if (mode != AppOpsManager.MODE_ALLOWED) { changed = mForcedAppStandbyPackages.add(packageName); } else { changed = mForcedAppStandbyPackages.remove(packageName); } if (changed && mode == AppOpsManager.MODE_ALLOWED) { sendPendingBackgroundAlarmsLocked(uid, packageName); @Override public void unblockAlarmsForUid(int uid) { synchronized (mLock) { sendPendingBackgroundAlarmsLocked(uid, null); } } @Override public void unblockAlarmsForUidPackage(int uid, String packageName) { synchronized (mLock) { sendPendingBackgroundAlarmsLocked(uid, packageName); } } }; private final BroadcastStats getStatsLocked(PendingIntent pi) { String pkg = pi.getCreatorPackage(); Loading
services/core/java/com/android/server/DeviceIdleController.java +9 −10 Original line number Diff line number Diff line Loading @@ -119,7 +119,6 @@ public class DeviceIdleController extends SystemService private PowerManagerInternal mLocalPowerManager; private PowerManager mPowerManager; private ConnectivityService mConnectivityService; private AlarmManagerService.LocalService mLocalAlarmManager; private INetworkPolicyManager mNetworkPolicyManager; private SensorManager mSensorManager; private Sensor mMotionSensor; Loading Loading @@ -1435,7 +1434,6 @@ public class DeviceIdleController extends SystemService mGoingIdleWakeLock.setReferenceCounted(true); mConnectivityService = (ConnectivityService)ServiceManager.getService( Context.CONNECTIVITY_SERVICE); mLocalAlarmManager = getLocalService(AlarmManagerService.LocalService.class); mNetworkPolicyManager = INetworkPolicyManager.Stub.asInterface( ServiceManager.getService(Context.NETWORK_POLICY_SERVICE)); mNetworkPolicyManagerInternal = getLocalService(NetworkPolicyManagerInternal.class); Loading Loading @@ -1500,8 +1498,8 @@ public class DeviceIdleController extends SystemService mLocalActivityManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray); mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray); mLocalAlarmManager.setDeviceIdleUserWhitelist(mPowerSaveWhitelistUserAppIdArray); passWhiteListToForceAppStandbyTrackerLocked(); updateInteractivityLocked(); } updateConnectivityState(null); Loading Loading @@ -2477,13 +2475,7 @@ public class DeviceIdleController extends SystemService } mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray); } if (mLocalAlarmManager != null) { if (DEBUG) { Slog.d(TAG, "Setting alarm whitelist to " + Arrays.toString(mPowerSaveWhitelistUserAppIdArray)); } mLocalAlarmManager.setDeviceIdleUserWhitelist(mPowerSaveWhitelistUserAppIdArray); } passWhiteListToForceAppStandbyTrackerLocked(); } private void updateTempWhitelistAppIdsLocked(int appId, boolean adding) { Loading @@ -2509,6 +2501,7 @@ public class DeviceIdleController extends SystemService } mLocalPowerManager.setDeviceIdleTempWhitelist(mTempWhitelistAppIdArray); } passWhiteListToForceAppStandbyTrackerLocked(); } private void reportPowerSaveWhitelistChangedLocked() { Loading @@ -2523,6 +2516,12 @@ public class DeviceIdleController extends SystemService getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM); } private void passWhiteListToForceAppStandbyTrackerLocked() { ForceAppStandbyTracker.getInstance(getContext()).setPowerSaveWhitelistAppIds( mPowerSaveWhitelistAllAppIdArray, mTempWhitelistAppIdArray); } void readConfigFileLocked() { if (DEBUG) Slog.d(TAG, "Reading config from " + mConfigFile.getBaseFile()); mPowerSaveWhitelistUserApps.clear(); Loading
services/core/java/com/android/server/ForceAppStandbyTracker.java +537 −85 File changed.Preview size limit exceeded, changes collapsed. Show changes