1 /* 2 * Copyright (C) 2006 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 */ 16 17 package com.android.server.alarm; 18 19 import static android.app.ActivityManager.UidFrozenStateChangedCallback.UID_FROZEN_STATE_FROZEN; 20 import static android.app.ActivityManagerInternal.ALLOW_NON_FULL; 21 import static android.app.AlarmManager.ELAPSED_REALTIME; 22 import static android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP; 23 import static android.app.AlarmManager.EXACT_LISTENER_ALARMS_DROPPED_ON_CACHED; 24 import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE; 25 import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE_COMPAT; 26 import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED; 27 import static android.app.AlarmManager.FLAG_IDLE_UNTIL; 28 import static android.app.AlarmManager.FLAG_PRIORITIZE; 29 import static android.app.AlarmManager.FLAG_WAKE_FROM_IDLE; 30 import static android.app.AlarmManager.INTERVAL_DAY; 31 import static android.app.AlarmManager.INTERVAL_HOUR; 32 import static android.app.AlarmManager.RTC; 33 import static android.app.AlarmManager.RTC_WAKEUP; 34 import static android.content.PermissionChecker.PERMISSION_GRANTED; 35 import static android.content.PermissionChecker.PID_UNKNOWN; 36 import static android.content.PermissionChecker.checkPermissionForPreflight; 37 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; 38 import static android.os.PowerExemptionManager.REASON_ALARM_MANAGER_ALARM_CLOCK; 39 import static android.os.PowerExemptionManager.REASON_DENIED; 40 import static android.os.PowerExemptionManager.REASON_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED; 41 import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED; 42 import static android.os.PowerWhitelistManager.REASON_ALARM_MANAGER_WHILE_IDLE; 43 import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED; 44 import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED; 45 import static android.os.UserHandle.USER_SYSTEM; 46 47 import static com.android.server.SystemClockTime.TIME_CONFIDENCE_HIGH; 48 import static com.android.server.SystemTimeZone.TIME_ZONE_CONFIDENCE_HIGH; 49 import static com.android.server.alarm.Alarm.APP_STANDBY_POLICY_INDEX; 50 import static com.android.server.alarm.Alarm.BATTERY_SAVER_POLICY_INDEX; 51 import static com.android.server.alarm.Alarm.DEVICE_IDLE_POLICY_INDEX; 52 import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_ALLOW_LIST; 53 import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_COMPAT; 54 import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_LISTENER; 55 import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_NOT_APPLICABLE; 56 import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_PERMISSION; 57 import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_POLICY_PERMISSION; 58 import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_PRIORITIZED; 59 import static com.android.server.alarm.Alarm.REQUESTER_POLICY_INDEX; 60 import static com.android.server.alarm.AlarmManagerService.AlarmHandler.REMOVE_EXACT_LISTENER_ALARMS_ON_CACHED; 61 import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_REASON_ALARM_CANCELLED; 62 import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_REASON_DATA_CLEARED; 63 import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_REASON_EXACT_PERMISSION_REVOKED; 64 import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_REASON_LISTENER_BINDER_DIED; 65 import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_REASON_LISTENER_CACHED; 66 import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_REASON_PI_CANCELLED; 67 import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_REASON_UNDEFINED; 68 69 import android.Manifest; 70 import android.annotation.CurrentTimeMillisLong; 71 import android.annotation.ElapsedRealtimeLong; 72 import android.annotation.EnforcePermission; 73 import android.annotation.IntDef; 74 import android.annotation.NonNull; 75 import android.annotation.SuppressLint; 76 import android.annotation.UserIdInt; 77 import android.app.Activity; 78 import android.app.ActivityManager; 79 import android.app.ActivityManagerInternal; 80 import android.app.ActivityOptions; 81 import android.app.AlarmManager; 82 import android.app.AppOpsManager; 83 import android.app.BroadcastOptions; 84 import android.app.IAlarmCompleteListener; 85 import android.app.IAlarmListener; 86 import android.app.IAlarmManager; 87 import android.app.PendingIntent; 88 import android.app.compat.CompatChanges; 89 import android.app.role.RoleManager; 90 import android.app.usage.UsageStatsManager; 91 import android.app.usage.UsageStatsManagerInternal; 92 import android.content.BroadcastReceiver; 93 import android.content.Context; 94 import android.content.Intent; 95 import android.content.IntentFilter; 96 import android.content.pm.PackageManager; 97 import android.content.pm.PackageManagerInternal; 98 import android.content.pm.UserPackage; 99 import android.net.Uri; 100 import android.os.BatteryManager; 101 import android.os.BatteryStatsInternal; 102 import android.os.Binder; 103 import android.os.Build; 104 import android.os.Bundle; 105 import android.os.Handler; 106 import android.os.HandlerExecutor; 107 import android.os.IBinder; 108 import android.os.Looper; 109 import android.os.Message; 110 import android.os.PowerExemptionManager; 111 import android.os.PowerManager; 112 import android.os.Process; 113 import android.os.RemoteException; 114 import android.os.ResultReceiver; 115 import android.os.ServiceManager; 116 import android.os.ShellCallback; 117 import android.os.ShellCommand; 118 import android.os.SystemClock; 119 import android.os.SystemProperties; 120 import android.os.ThreadLocalWorkSource; 121 import android.os.Trace; 122 import android.os.UserHandle; 123 import android.os.WorkSource; 124 import android.provider.DeviceConfig; 125 import android.provider.Settings; 126 import android.system.Os; 127 import android.text.TextUtils; 128 import android.text.format.DateFormat; 129 import android.util.ArrayMap; 130 import android.util.ArraySet; 131 import android.util.EventLog; 132 import android.util.IndentingPrintWriter; 133 import android.util.IntArray; 134 import android.util.Log; 135 import android.util.LongArrayQueue; 136 import android.util.Slog; 137 import android.util.SparseArray; 138 import android.util.SparseBooleanArray; 139 import android.util.SparseIntArray; 140 import android.util.SparseLongArray; 141 import android.util.TimeUtils; 142 import android.util.proto.ProtoOutputStream; 143 144 import com.android.internal.annotations.GuardedBy; 145 import com.android.internal.annotations.VisibleForTesting; 146 import com.android.internal.app.IAppOpsCallback; 147 import com.android.internal.app.IAppOpsService; 148 import com.android.internal.util.ArrayUtils; 149 import com.android.internal.util.DumpUtils; 150 import com.android.internal.util.FrameworkStatsLog; 151 import com.android.internal.util.LocalLog; 152 import com.android.internal.util.RingBuffer; 153 import com.android.internal.util.StatLogger; 154 import com.android.server.AlarmManagerInternal; 155 import com.android.server.AppSchedulingModuleThread; 156 import com.android.server.AppStateTracker; 157 import com.android.server.AppStateTrackerImpl; 158 import com.android.server.AppStateTrackerImpl.Listener; 159 import com.android.server.DeviceIdleInternal; 160 import com.android.server.EventLogTags; 161 import com.android.server.LocalServices; 162 import com.android.server.SystemClockTime; 163 import com.android.server.SystemClockTime.TimeConfidence; 164 import com.android.server.SystemService; 165 import com.android.server.SystemServiceManager; 166 import com.android.server.SystemTimeZone; 167 import com.android.server.SystemTimeZone.TimeZoneConfidence; 168 import com.android.server.pm.permission.PermissionManagerService; 169 import com.android.server.pm.permission.PermissionManagerServiceInternal; 170 import com.android.server.pm.pkg.AndroidPackage; 171 import com.android.server.usage.AppStandbyInternal; 172 import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener; 173 174 import dalvik.annotation.optimization.NeverCompile; 175 176 import java.io.FileDescriptor; 177 import java.io.PrintWriter; 178 import java.lang.annotation.Retention; 179 import java.lang.annotation.RetentionPolicy; 180 import java.text.SimpleDateFormat; 181 import java.time.Instant; 182 import java.time.zone.ZoneOffsetTransition; 183 import java.time.zone.ZoneRules; 184 import java.util.ArrayList; 185 import java.util.Arrays; 186 import java.util.Calendar; 187 import java.util.Collections; 188 import java.util.Comparator; 189 import java.util.Date; 190 import java.util.Locale; 191 import java.util.Set; 192 import java.util.TimeZone; 193 import java.util.TreeSet; 194 import java.util.concurrent.ThreadLocalRandom; 195 import java.util.concurrent.TimeUnit; 196 import java.util.function.Predicate; 197 198 /** 199 * Alarm manager implementation. 200 * 201 * Unit test: 202 * atest FrameworksMockingServicesTests:com.android.server.alarm.AlarmManagerServiceTest 203 */ 204 public class AlarmManagerService extends SystemService { 205 private static final int RTC_WAKEUP_MASK = 1 << RTC_WAKEUP; 206 private static final int ELAPSED_REALTIME_WAKEUP_MASK = 1 << ELAPSED_REALTIME_WAKEUP; 207 private static final int REMOVAL_HISTORY_SIZE_PER_UID = 10; 208 static final int TIME_CHANGED_MASK = 1 << 16; 209 static final int IS_WAKEUP_MASK = RTC_WAKEUP_MASK | ELAPSED_REALTIME_WAKEUP_MASK; 210 211 static final String TAG = "AlarmManager"; 212 static final String TIME_TICK_TAG = "TIME_TICK"; 213 static final boolean localLOGV = false; 214 static final boolean DEBUG_BATCH = localLOGV || false; 215 static final boolean DEBUG_ALARM_CLOCK = localLOGV || false; 216 static final boolean DEBUG_LISTENER_CALLBACK = localLOGV || false; 217 static final boolean DEBUG_WAKELOCK = localLOGV || false; 218 static final boolean DEBUG_BG_LIMIT = localLOGV || false; 219 static final boolean DEBUG_STANDBY = localLOGV || false; 220 static final boolean RECORD_ALARMS_IN_HISTORY = true; 221 static final boolean RECORD_DEVICE_IDLE_ALARMS = false; 222 223 static final int TICK_HISTORY_DEPTH = 10; 224 static final long INDEFINITE_DELAY = 365 * INTERVAL_DAY; 225 226 // Indices into the KEYS_APP_STANDBY_QUOTAS array. 227 static final int ACTIVE_INDEX = 0; 228 static final int WORKING_INDEX = 1; 229 static final int FREQUENT_INDEX = 2; 230 static final int RARE_INDEX = 3; 231 static final int NEVER_INDEX = 4; 232 233 private static final long TEMPORARY_QUOTA_DURATION = INTERVAL_DAY; 234 235 // System properties read on some device configurations to initialize time properly and 236 // perform DST transitions at the bootloader level. 237 private static final String TIMEOFFSET_PROPERTY = "persist.sys.time.offset"; 238 private static final String DST_TRANSITION_PROPERTY = "persist.sys.time.dst_transition"; 239 private static final String DST_OFFSET_PROPERTY = "persist.sys.time.dst_offset"; 240 241 242 private final Intent mBackgroundIntent 243 = new Intent().addFlags(Intent.FLAG_FROM_BACKGROUND); 244 245 private static final Intent NEXT_ALARM_CLOCK_CHANGED_INTENT = 246 new Intent(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED) 247 .addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING 248 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); 249 250 final LocalLog mLog = new LocalLog(TAG); 251 252 AppOpsManager mAppOps; 253 DeviceIdleInternal mLocalDeviceIdleController; 254 private UsageStatsManagerInternal mUsageStatsManagerInternal; 255 private ActivityManagerInternal mActivityManagerInternal; 256 private PackageManagerInternal mPackageManagerInternal; 257 private BatteryStatsInternal mBatteryStatsInternal; 258 private RoleManager mRoleManager; 259 private volatile PermissionManagerServiceInternal mLocalPermissionManager; 260 261 final Object mLock = new Object(); 262 263 /** Immutable set of app ids requesting {@link Manifest.permission#SCHEDULE_EXACT_ALARM} */ 264 @VisibleForTesting 265 volatile Set<Integer> mExactAlarmCandidates = Collections.emptySet(); 266 267 /** 268 * A map from uid to the last op-mode we have seen for 269 * {@link AppOpsManager#OP_SCHEDULE_EXACT_ALARM}. Used for evaluating permission state change 270 * when the app-op changes. 271 */ 272 @VisibleForTesting 273 @GuardedBy("mLock") 274 SparseIntArray mLastOpScheduleExactAlarm = new SparseIntArray(); 275 276 // List of alarms per uid deferred due to user applied background restrictions on the source app 277 SparseArray<ArrayList<Alarm>> mPendingBackgroundAlarms = new SparseArray<>(); 278 279 private boolean mStartUserBeforeScheduledAlarms; 280 private long mNextWakeup; 281 private long mNextNonWakeup; 282 private long mNextWakeUpSetAt; 283 private long mNextNonWakeUpSetAt; 284 private long mLastWakeup; 285 private long mLastTrigger; 286 287 private long mLastTickSet; 288 private long mLastTickReceived; 289 // ring buffer of recent TIME_TICK issuance, in the elapsed timebase 290 private final long[] mTickHistory = new long[TICK_HISTORY_DEPTH]; 291 private int mNextTickHistory; 292 293 private final Injector mInjector; 294 int mBroadcastRefCount = 0; 295 boolean mUseFrozenStateToDropListenerAlarms; 296 MetricsHelper mMetricsHelper; 297 PowerManager.WakeLock mWakeLock; 298 SparseIntArray mAlarmsPerUid = new SparseIntArray(); 299 ArrayList<Alarm> mPendingNonWakeupAlarms = new ArrayList<>(); 300 ArrayList<InFlight> mInFlight = new ArrayList<>(); 301 private final ArrayList<AlarmManagerInternal.InFlightListener> mInFlightListeners = 302 new ArrayList<>(); 303 AlarmHandler mHandler; 304 AppWakeupHistory mAppWakeupHistory; 305 AppWakeupHistory mAllowWhileIdleHistory; 306 AppWakeupHistory mAllowWhileIdleCompatHistory; 307 TemporaryQuotaReserve mTemporaryQuotaReserve; 308 private final SparseLongArray mLastPriorityAlarmDispatch = new SparseLongArray(); 309 private final SparseArray<RingBuffer<RemovedAlarm>> mRemovalHistory = new SparseArray<>(); 310 ClockReceiver mClockReceiver; 311 final DeliveryTracker mDeliveryTracker = new DeliveryTracker(); 312 IBinder.DeathRecipient mListenerDeathRecipient; 313 Intent mTimeTickIntent; 314 Bundle mTimeTickOptions; 315 IAlarmListener mTimeTickTrigger; 316 PendingIntent mDateChangeSender; 317 boolean mInteractive = true; 318 long mNonInteractiveStartTime; 319 long mNonInteractiveTime; 320 long mLastAlarmDeliveryTime; 321 long mStartCurrentDelayTime; 322 long mNextNonWakeupDeliveryTime; 323 long mLastTimeChangeClockTime; 324 long mLastTimeChangeRealtime; 325 int mNumTimeChanged; 326 327 /** 328 * At boot we use SYSTEM_UI_SELF_PERMISSION to look up the definer's uid. 329 */ 330 int mSystemUiUid; 331 isTimeTickAlarm(Alarm a)332 static boolean isTimeTickAlarm(Alarm a) { 333 return a.uid == Process.SYSTEM_UID && TIME_TICK_TAG.equals(a.listenerTag); 334 } 335 336 final static class IdleDispatchEntry { 337 int uid; 338 String pkg; 339 String tag; 340 String op; 341 long elapsedRealtime; 342 long argRealtime; 343 } 344 final ArrayList<IdleDispatchEntry> mAllowWhileIdleDispatches = new ArrayList(); 345 346 interface Stats { 347 int REORDER_ALARMS_FOR_STANDBY = 0; 348 int HAS_SCHEDULE_EXACT_ALARM = 1; 349 } 350 351 private final StatLogger mStatLogger = new StatLogger("Alarm manager stats", new String[]{ 352 "REORDER_ALARMS_FOR_STANDBY", 353 "HAS_SCHEDULE_EXACT_ALARM", 354 }); 355 356 BroadcastOptions mOptsWithFgs = makeBasicAlarmBroadcastOptions(); 357 BroadcastOptions mOptsWithFgsForAlarmClock = makeBasicAlarmBroadcastOptions(); 358 BroadcastOptions mOptsWithoutFgs = makeBasicAlarmBroadcastOptions(); 359 BroadcastOptions mOptsTimeBroadcast = makeBasicAlarmBroadcastOptions(); 360 ActivityOptions mActivityOptsRestrictBal = ActivityOptions.makeBasic(); 361 BroadcastOptions mBroadcastOptsRestrictBal = makeBasicAlarmBroadcastOptions(); 362 makeBasicAlarmBroadcastOptions()363 private static BroadcastOptions makeBasicAlarmBroadcastOptions() { 364 final BroadcastOptions b = BroadcastOptions.makeBasic(); 365 b.setAlarmBroadcast(true); 366 return b; 367 } 368 369 // TODO(b/172085676): Move inside alarm store. 370 private final SparseArray<AlarmManager.AlarmClockInfo> mNextAlarmClockForUser = 371 new SparseArray<>(); 372 private final SparseArray<AlarmManager.AlarmClockInfo> mTmpSparseAlarmClockArray = 373 new SparseArray<>(); 374 private final SparseBooleanArray mPendingSendNextAlarmClockChangedForUser = 375 new SparseBooleanArray(); 376 private boolean mNextAlarmClockMayChange; 377 378 @GuardedBy("mLock") 379 private final Runnable mAlarmClockUpdater = () -> mNextAlarmClockMayChange = true; 380 381 // May only use on mHandler's thread, locking not required. 382 private final SparseArray<AlarmManager.AlarmClockInfo> mHandlerSparseAlarmClockArray = 383 new SparseArray<>(); 384 385 private AppStateTrackerImpl mAppStateTracker; 386 @VisibleForTesting 387 boolean mAppStandbyParole; 388 389 /** 390 * Holds information about temporary quota that can be allotted to apps to use as a "reserve" 391 * when they run out of their standard app-standby quota. 392 * This reserve only lasts for a fixed duration of time from when it was last replenished. 393 */ 394 static class TemporaryQuotaReserve { 395 396 private static class QuotaInfo { 397 public int remainingQuota; 398 public long expirationTime; 399 public long lastUsage; 400 } 401 /** Map of {package, user} -> {quotaInfo} */ 402 private final ArrayMap<UserPackage, QuotaInfo> mQuotaBuffer = new ArrayMap<>(); 403 404 private long mMaxDuration; 405 TemporaryQuotaReserve(long maxDuration)406 TemporaryQuotaReserve(long maxDuration) { 407 mMaxDuration = maxDuration; 408 } 409 replenishQuota(String packageName, int userId, int quota, long nowElapsed)410 void replenishQuota(String packageName, int userId, int quota, long nowElapsed) { 411 if (quota <= 0) { 412 return; 413 } 414 final UserPackage userPackage = UserPackage.of(userId, packageName); 415 QuotaInfo currentQuotaInfo = mQuotaBuffer.get(userPackage); 416 if (currentQuotaInfo == null) { 417 currentQuotaInfo = new QuotaInfo(); 418 mQuotaBuffer.put(userPackage, currentQuotaInfo); 419 } 420 currentQuotaInfo.remainingQuota = quota; 421 currentQuotaInfo.expirationTime = nowElapsed + mMaxDuration; 422 } 423 424 /** Returns if the supplied package has reserve quota to fire at the given time. */ hasQuota(String packageName, int userId, long triggerElapsed)425 boolean hasQuota(String packageName, int userId, long triggerElapsed) { 426 final UserPackage userPackage = UserPackage.of(userId, packageName); 427 final QuotaInfo quotaInfo = mQuotaBuffer.get(userPackage); 428 429 return quotaInfo != null && quotaInfo.remainingQuota > 0 430 && triggerElapsed <= quotaInfo.expirationTime; 431 } 432 433 /** 434 * Records quota usage of the given package at the given time and subtracts quota if 435 * required. 436 */ recordUsage(String packageName, int userId, long nowElapsed)437 void recordUsage(String packageName, int userId, long nowElapsed) { 438 final UserPackage userPackage = UserPackage.of(userId, packageName); 439 final QuotaInfo quotaInfo = mQuotaBuffer.get(userPackage); 440 441 if (quotaInfo == null) { 442 Slog.wtf(TAG, "Temporary quota being consumed at " + nowElapsed 443 + " but not found for package: " + packageName + ", user: " + userId); 444 return; 445 } 446 // Only consume quota if this usage is later than the last one recorded. This is 447 // needed as this can be called multiple times when a batch of alarms is delivered. 448 if (nowElapsed > quotaInfo.lastUsage) { 449 if (quotaInfo.remainingQuota <= 0) { 450 Slog.wtf(TAG, "Temporary quota being consumed at " + nowElapsed 451 + " but remaining only " + quotaInfo.remainingQuota 452 + " for package: " + packageName + ", user: " + userId); 453 } else if (quotaInfo.expirationTime < nowElapsed) { 454 Slog.wtf(TAG, "Temporary quota being consumed at " + nowElapsed 455 + " but expired at " + quotaInfo.expirationTime 456 + " for package: " + packageName + ", user: " + userId); 457 } else { 458 quotaInfo.remainingQuota--; 459 // We keep the quotaInfo entry even if remaining quota reduces to 0 as 460 // following calls can be made with nowElapsed <= lastUsage. The object will 461 // eventually be removed in cleanUpExpiredQuotas or reused in replenishQuota. 462 } 463 quotaInfo.lastUsage = nowElapsed; 464 } 465 } 466 467 /** Clean up any quotas that have expired before the given time. */ cleanUpExpiredQuotas(long nowElapsed)468 void cleanUpExpiredQuotas(long nowElapsed) { 469 for (int i = mQuotaBuffer.size() - 1; i >= 0; i--) { 470 final QuotaInfo quotaInfo = mQuotaBuffer.valueAt(i); 471 if (quotaInfo.expirationTime < nowElapsed) { 472 mQuotaBuffer.removeAt(i); 473 } 474 } 475 } 476 removeForUser(int userId)477 void removeForUser(int userId) { 478 for (int i = mQuotaBuffer.size() - 1; i >= 0; i--) { 479 final UserPackage userPackageKey = mQuotaBuffer.keyAt(i); 480 if (userPackageKey.userId == userId) { 481 mQuotaBuffer.removeAt(i); 482 } 483 } 484 } 485 removeForPackage(String packageName, int userId)486 void removeForPackage(String packageName, int userId) { 487 final UserPackage userPackage = UserPackage.of(userId, packageName); 488 mQuotaBuffer.remove(userPackage); 489 } 490 dump(IndentingPrintWriter pw, long nowElapsed)491 void dump(IndentingPrintWriter pw, long nowElapsed) { 492 pw.increaseIndent(); 493 for (int i = 0; i < mQuotaBuffer.size(); i++) { 494 final UserPackage userPackage = mQuotaBuffer.keyAt(i); 495 final QuotaInfo quotaInfo = mQuotaBuffer.valueAt(i); 496 pw.print(userPackage.packageName); 497 pw.print(", u"); 498 pw.print(userPackage.userId); 499 pw.print(": "); 500 if (quotaInfo == null) { 501 pw.print("--"); 502 } else { 503 pw.print("quota: "); 504 pw.print(quotaInfo.remainingQuota); 505 pw.print(", expiration: "); 506 TimeUtils.formatDuration(quotaInfo.expirationTime, nowElapsed, pw); 507 pw.print(" last used: "); 508 TimeUtils.formatDuration(quotaInfo.lastUsage, nowElapsed, pw); 509 } 510 pw.println(); 511 } 512 pw.decreaseIndent(); 513 } 514 } 515 516 /** 517 * A container to keep rolling window history of previous times when an alarm was sent to 518 * a package. 519 */ 520 @VisibleForTesting 521 static class AppWakeupHistory { 522 private final ArrayMap<UserPackage, LongArrayQueue> mPackageHistory = new ArrayMap<>(); 523 private long mWindowSize; 524 AppWakeupHistory(long windowSize)525 AppWakeupHistory(long windowSize) { 526 mWindowSize = windowSize; 527 } 528 recordAlarmForPackage(String packageName, int userId, long nowElapsed)529 void recordAlarmForPackage(String packageName, int userId, long nowElapsed) { 530 final UserPackage userPackage = UserPackage.of(userId, packageName); 531 LongArrayQueue history = mPackageHistory.get(userPackage); 532 if (history == null) { 533 history = new LongArrayQueue(); 534 mPackageHistory.put(userPackage, history); 535 } 536 if (history.size() == 0 || history.peekLast() < nowElapsed) { 537 history.addLast(nowElapsed); 538 } 539 snapToWindow(history); 540 } 541 removeForUser(int userId)542 void removeForUser(int userId) { 543 for (int i = mPackageHistory.size() - 1; i >= 0; i--) { 544 final UserPackage userPackageKey = mPackageHistory.keyAt(i); 545 if (userPackageKey.userId == userId) { 546 mPackageHistory.removeAt(i); 547 } 548 } 549 } 550 removeForPackage(String packageName, int userId)551 void removeForPackage(String packageName, int userId) { 552 final UserPackage userPackage = UserPackage.of(userId, packageName); 553 mPackageHistory.remove(userPackage); 554 } 555 snapToWindow(LongArrayQueue history)556 private void snapToWindow(LongArrayQueue history) { 557 while (history.peekFirst() + mWindowSize < history.peekLast()) { 558 history.removeFirst(); 559 } 560 } 561 getTotalWakeupsInWindow(String packageName, int userId)562 int getTotalWakeupsInWindow(String packageName, int userId) { 563 final LongArrayQueue history = mPackageHistory.get(UserPackage.of(userId, packageName)); 564 return (history == null) ? 0 : history.size(); 565 } 566 567 /** 568 * @param n The desired nth-last wakeup 569 * (1=1st-last=the ultimate wakeup and 2=2nd-last=the penultimate wakeup) 570 */ getNthLastWakeupForPackage(String packageName, int userId, int n)571 long getNthLastWakeupForPackage(String packageName, int userId, int n) { 572 final LongArrayQueue history = mPackageHistory.get(UserPackage.of(userId, packageName)); 573 if (history == null) { 574 return 0; 575 } 576 final int i = history.size() - n; 577 return (i < 0) ? 0 : history.get(i); 578 } 579 dump(IndentingPrintWriter pw, long nowElapsed)580 void dump(IndentingPrintWriter pw, long nowElapsed) { 581 pw.increaseIndent(); 582 for (int i = 0; i < mPackageHistory.size(); i++) { 583 final UserPackage userPackage = mPackageHistory.keyAt(i); 584 final LongArrayQueue timestamps = mPackageHistory.valueAt(i); 585 pw.print(userPackage.packageName); 586 pw.print(", u"); 587 pw.print(userPackage.userId); 588 pw.print(": "); 589 // limit dumping to a max of 100 values 590 final int lastIdx = Math.max(0, timestamps.size() - 100); 591 for (int j = timestamps.size() - 1; j >= lastIdx; j--) { 592 TimeUtils.formatDuration(timestamps.get(j), nowElapsed, pw); 593 pw.print(", "); 594 } 595 pw.println(); 596 } 597 pw.decreaseIndent(); 598 } 599 } 600 601 static class RemovedAlarm { 602 static final int REMOVE_REASON_UNDEFINED = 0; 603 static final int REMOVE_REASON_ALARM_CANCELLED = 1; 604 static final int REMOVE_REASON_EXACT_PERMISSION_REVOKED = 2; 605 static final int REMOVE_REASON_DATA_CLEARED = 3; 606 static final int REMOVE_REASON_PI_CANCELLED = 4; 607 static final int REMOVE_REASON_LISTENER_BINDER_DIED = 5; 608 static final int REMOVE_REASON_LISTENER_CACHED = 6; 609 610 final Alarm.Snapshot mAlarmSnapshot; 611 final long mWhenRemovedElapsed; 612 final long mWhenRemovedRtc; 613 final int mRemoveReason; 614 RemovedAlarm(Alarm a, int removeReason, long nowRtc, long nowElapsed)615 RemovedAlarm(Alarm a, int removeReason, long nowRtc, long nowElapsed) { 616 mAlarmSnapshot = new Alarm.Snapshot(a); 617 mRemoveReason = removeReason; 618 mWhenRemovedRtc = nowRtc; 619 mWhenRemovedElapsed = nowElapsed; 620 } 621 isLoggable(int reason)622 static final boolean isLoggable(int reason) { 623 // We don't want to log meaningless reasons. This also gives a way for callers to 624 // opt out of logging, e.g. when replacing an alarm. 625 return reason != REMOVE_REASON_UNDEFINED; 626 } 627 removeReasonToString(int reason)628 static final String removeReasonToString(int reason) { 629 switch (reason) { 630 case REMOVE_REASON_ALARM_CANCELLED: 631 return "alarm_cancelled"; 632 case REMOVE_REASON_EXACT_PERMISSION_REVOKED: 633 return "exact_alarm_permission_revoked"; 634 case REMOVE_REASON_DATA_CLEARED: 635 return "data_cleared"; 636 case REMOVE_REASON_PI_CANCELLED: 637 return "pi_cancelled"; 638 case REMOVE_REASON_LISTENER_BINDER_DIED: 639 return "listener_binder_died"; 640 case REMOVE_REASON_LISTENER_CACHED: 641 return "listener_cached"; 642 default: 643 return "unknown:" + reason; 644 } 645 } 646 dump(IndentingPrintWriter pw, long nowElapsed, SimpleDateFormat sdf)647 void dump(IndentingPrintWriter pw, long nowElapsed, SimpleDateFormat sdf) { 648 pw.increaseIndent(); 649 650 pw.print("Reason", removeReasonToString(mRemoveReason)); 651 pw.print("elapsed="); 652 TimeUtils.formatDuration(mWhenRemovedElapsed, nowElapsed, pw); 653 pw.print(" rtc="); 654 pw.print(sdf.format(new Date(mWhenRemovedRtc))); 655 pw.println(); 656 657 pw.println("Snapshot:"); 658 pw.increaseIndent(); 659 mAlarmSnapshot.dump(pw, nowElapsed); 660 pw.decreaseIndent(); 661 662 pw.decreaseIndent(); 663 } 664 } 665 666 /** 667 * All times are in milliseconds. These constants are kept synchronized with the system 668 * global Settings. Any access to this class or its fields should be done while 669 * holding the AlarmManagerService.mLock lock. 670 */ 671 @VisibleForTesting 672 final class Constants implements DeviceConfig.OnPropertiesChangedListener { 673 // Key names stored in the settings value. 674 @VisibleForTesting 675 static final String KEY_MIN_FUTURITY = "min_futurity"; 676 @VisibleForTesting 677 static final String KEY_MIN_INTERVAL = "min_interval"; 678 @VisibleForTesting 679 static final String KEY_MAX_INTERVAL = "max_interval"; 680 @VisibleForTesting 681 static final String KEY_MIN_WINDOW = "min_window"; 682 @VisibleForTesting 683 static final String KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION 684 = "allow_while_idle_whitelist_duration"; 685 @VisibleForTesting 686 static final String KEY_LISTENER_TIMEOUT = "listener_timeout"; 687 @VisibleForTesting 688 static final String KEY_MAX_ALARMS_PER_UID = "max_alarms_per_uid"; 689 private static final String KEY_APP_STANDBY_WINDOW = "app_standby_window"; 690 private static final String KEY_PREFIX_STANDBY_QUOTA = "standby_quota_"; 691 @VisibleForTesting 692 final String[] KEYS_APP_STANDBY_QUOTAS = { 693 KEY_PREFIX_STANDBY_QUOTA + "active", 694 KEY_PREFIX_STANDBY_QUOTA + "working", 695 KEY_PREFIX_STANDBY_QUOTA + "frequent", 696 KEY_PREFIX_STANDBY_QUOTA + "rare", 697 KEY_PREFIX_STANDBY_QUOTA + "never", 698 }; 699 // Not putting this in the KEYS_APP_STANDBY_QUOTAS array because this uses a different 700 // window size. 701 private static final String KEY_APP_STANDBY_RESTRICTED_QUOTA = 702 KEY_PREFIX_STANDBY_QUOTA + "restricted"; 703 private static final String KEY_APP_STANDBY_RESTRICTED_WINDOW = 704 "app_standby_restricted_window"; 705 706 private static final String KEY_TIME_TICK_ALLOWED_WHILE_IDLE = 707 "time_tick_allowed_while_idle"; 708 709 private static final String KEY_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF = 710 "delay_nonwakeup_alarms_while_screen_off"; 711 712 @VisibleForTesting 713 static final String KEY_ALLOW_WHILE_IDLE_QUOTA = "allow_while_idle_quota"; 714 715 @VisibleForTesting 716 static final String KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA = "allow_while_idle_compat_quota"; 717 718 @VisibleForTesting 719 static final String KEY_ALLOW_WHILE_IDLE_WINDOW = "allow_while_idle_window"; 720 @VisibleForTesting 721 static final String KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW = "allow_while_idle_compat_window"; 722 723 @VisibleForTesting 724 static final String KEY_PRIORITY_ALARM_DELAY = "priority_alarm_delay"; 725 @VisibleForTesting 726 static final String KEY_MIN_DEVICE_IDLE_FUZZ = "min_device_idle_fuzz"; 727 @VisibleForTesting 728 static final String KEY_MAX_DEVICE_IDLE_FUZZ = "max_device_idle_fuzz"; 729 @VisibleForTesting 730 static final String KEY_TEMPORARY_QUOTA_BUMP = "temporary_quota_bump"; 731 @VisibleForTesting 732 static final String KEY_CACHED_LISTENER_REMOVAL_DELAY = "cached_listener_removal_delay"; 733 734 private static final long DEFAULT_MIN_FUTURITY = 5 * 1000; 735 private static final long DEFAULT_MIN_INTERVAL = 60 * 1000; 736 private static final long DEFAULT_MAX_INTERVAL = 365 * INTERVAL_DAY; 737 private static final long DEFAULT_MIN_WINDOW = 10 * 60 * 1000; 738 private static final long DEFAULT_ALLOW_WHILE_IDLE_ALLOWLIST_DURATION = 10 * 1000; 739 private static final long DEFAULT_LISTENER_TIMEOUT = 5 * 1000; 740 private static final int DEFAULT_MAX_ALARMS_PER_UID = 500; 741 private static final long DEFAULT_APP_STANDBY_WINDOW = 60 * 60 * 1000; // 1 hr 742 /** 743 * Max number of times an app can receive alarms in {@link #APP_STANDBY_WINDOW} 744 */ 745 private final int[] DEFAULT_APP_STANDBY_QUOTAS = { 746 720, // Active 747 10, // Working 748 2, // Frequent 749 1, // Rare 750 0 // Never 751 }; 752 private static final int DEFAULT_APP_STANDBY_RESTRICTED_QUOTA = 1; 753 private static final long DEFAULT_APP_STANDBY_RESTRICTED_WINDOW = INTERVAL_DAY; 754 755 private static final boolean DEFAULT_TIME_TICK_ALLOWED_WHILE_IDLE = true; 756 757 /** 758 * Default quota for pre-S apps. The same as allowing an alarm slot once 759 * every ALLOW_WHILE_IDLE_LONG_DELAY, which was 9 minutes. 760 */ 761 private static final int DEFAULT_ALLOW_WHILE_IDLE_COMPAT_QUOTA = 7; 762 private static final int DEFAULT_ALLOW_WHILE_IDLE_QUOTA = 72; 763 764 private static final long DEFAULT_ALLOW_WHILE_IDLE_WINDOW = 60 * 60 * 1000; // 1 hour. 765 private static final long DEFAULT_ALLOW_WHILE_IDLE_COMPAT_WINDOW = 60 * 60 * 1000; 766 767 private static final long DEFAULT_PRIORITY_ALARM_DELAY = 9 * 60_000; 768 769 private static final long DEFAULT_MIN_DEVICE_IDLE_FUZZ = 2 * 60_000; 770 private static final long DEFAULT_MAX_DEVICE_IDLE_FUZZ = 15 * 60_000; 771 772 private static final int DEFAULT_TEMPORARY_QUOTA_BUMP = 0; 773 774 private static final boolean DEFAULT_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF = true; 775 776 private static final long DEFAULT_CACHED_LISTENER_REMOVAL_DELAY = 10_000; 777 778 // Minimum futurity of a new alarm 779 public long MIN_FUTURITY = DEFAULT_MIN_FUTURITY; 780 781 // Minimum alarm recurrence interval 782 public long MIN_INTERVAL = DEFAULT_MIN_INTERVAL; 783 784 // Maximum alarm recurrence interval 785 public long MAX_INTERVAL = DEFAULT_MAX_INTERVAL; 786 787 // Minimum window size for inexact alarms 788 public long MIN_WINDOW = DEFAULT_MIN_WINDOW; 789 790 // BroadcastOptions.setTemporaryAppWhitelistDuration() to use for FLAG_ALLOW_WHILE_IDLE. 791 public long ALLOW_WHILE_IDLE_WHITELIST_DURATION 792 = DEFAULT_ALLOW_WHILE_IDLE_ALLOWLIST_DURATION; 793 794 // Direct alarm listener callback timeout 795 public long LISTENER_TIMEOUT = DEFAULT_LISTENER_TIMEOUT; 796 public int MAX_ALARMS_PER_UID = DEFAULT_MAX_ALARMS_PER_UID; 797 798 public long APP_STANDBY_WINDOW = DEFAULT_APP_STANDBY_WINDOW; 799 public int[] APP_STANDBY_QUOTAS = new int[DEFAULT_APP_STANDBY_QUOTAS.length]; 800 public int APP_STANDBY_RESTRICTED_QUOTA = DEFAULT_APP_STANDBY_RESTRICTED_QUOTA; 801 public long APP_STANDBY_RESTRICTED_WINDOW = DEFAULT_APP_STANDBY_RESTRICTED_WINDOW; 802 803 public boolean TIME_TICK_ALLOWED_WHILE_IDLE = DEFAULT_TIME_TICK_ALLOWED_WHILE_IDLE; 804 805 public int ALLOW_WHILE_IDLE_QUOTA = DEFAULT_ALLOW_WHILE_IDLE_QUOTA; 806 807 /** 808 * Used to provide backwards compatibility to pre-S apps with a quota equivalent to the 809 * earlier delay throttling mechanism. 810 */ 811 public int ALLOW_WHILE_IDLE_COMPAT_QUOTA = DEFAULT_ALLOW_WHILE_IDLE_COMPAT_QUOTA; 812 813 /** 814 * The window used for enforcing {@link #ALLOW_WHILE_IDLE_COMPAT_QUOTA}. 815 * Can be configured, but only recommended for testing. 816 */ 817 public long ALLOW_WHILE_IDLE_COMPAT_WINDOW = DEFAULT_ALLOW_WHILE_IDLE_COMPAT_WINDOW; 818 819 /** 820 * The window used for enforcing {@link #ALLOW_WHILE_IDLE_COMPAT_QUOTA}. 821 * Can be configured, but only recommended for testing. 822 */ 823 public long ALLOW_WHILE_IDLE_WINDOW = DEFAULT_ALLOW_WHILE_IDLE_WINDOW; 824 825 /** 826 * Minimum delay between two slots that an app can get for their prioritized alarms, while 827 * the device is in doze. 828 */ 829 public long PRIORITY_ALARM_DELAY = DEFAULT_PRIORITY_ALARM_DELAY; 830 831 /** 832 * Minimum time interval that an IDLE_UNTIL will be pulled earlier to a subsequent 833 * WAKE_FROM_IDLE alarm. 834 */ 835 public long MIN_DEVICE_IDLE_FUZZ = DEFAULT_MIN_DEVICE_IDLE_FUZZ; 836 837 /** 838 * Maximum time interval that an IDLE_UNTIL will be pulled earlier to a subsequent 839 * WAKE_FROM_IDLE alarm. 840 */ 841 public long MAX_DEVICE_IDLE_FUZZ = DEFAULT_MAX_DEVICE_IDLE_FUZZ; 842 843 /** 844 * The amount of temporary reserve quota to give apps on receiving the 845 * {@link AppIdleStateChangeListener#triggerTemporaryQuotaBump(String, int)} callback 846 * from {@link com.android.server.usage.AppStandbyController}. 847 * <p> This quota adds on top of the standard standby bucket quota available to the app, and 848 * works the same way, i.e. each count of quota denotes one point in time when the app can 849 * receive any number of alarms together. 850 * This quota is tracked per package and expires after {@link #TEMPORARY_QUOTA_DURATION}. 851 */ 852 public int TEMPORARY_QUOTA_BUMP = DEFAULT_TEMPORARY_QUOTA_BUMP; 853 854 public boolean DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF = 855 DEFAULT_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF; 856 857 /** 858 * Exact listener alarms for apps that get cached are removed after this duration. This is 859 * a grace period to allow for transient procstate changes, e.g., when the app switches 860 * between different lifecycles. 861 */ 862 public long CACHED_LISTENER_REMOVAL_DELAY = DEFAULT_CACHED_LISTENER_REMOVAL_DELAY; 863 864 private long mLastAllowWhileIdleWhitelistDuration = -1; 865 private int mVersion = 0; 866 Constants(Handler handler)867 Constants(Handler handler) { 868 updateAllowWhileIdleWhitelistDurationLocked(); 869 for (int i = 0; i < APP_STANDBY_QUOTAS.length; i++) { 870 APP_STANDBY_QUOTAS[i] = DEFAULT_APP_STANDBY_QUOTAS[i]; 871 } 872 } 873 getVersion()874 public int getVersion() { 875 synchronized (mLock) { 876 return mVersion; 877 } 878 } 879 start()880 public void start() { 881 mInjector.registerDeviceConfigListener(this); 882 onPropertiesChanged(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_ALARM_MANAGER)); 883 } 884 885 @SuppressLint("MissingPermission") updateAllowWhileIdleWhitelistDurationLocked()886 public void updateAllowWhileIdleWhitelistDurationLocked() { 887 if (mLastAllowWhileIdleWhitelistDuration != ALLOW_WHILE_IDLE_WHITELIST_DURATION) { 888 mLastAllowWhileIdleWhitelistDuration = ALLOW_WHILE_IDLE_WHITELIST_DURATION; 889 890 mOptsWithFgs.setTemporaryAppAllowlist(ALLOW_WHILE_IDLE_WHITELIST_DURATION, 891 TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, 892 REASON_ALARM_MANAGER_WHILE_IDLE, ""); 893 mOptsWithFgsForAlarmClock.setTemporaryAppAllowlist( 894 ALLOW_WHILE_IDLE_WHITELIST_DURATION, 895 TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, 896 REASON_ALARM_MANAGER_ALARM_CLOCK, ""); 897 mOptsWithoutFgs.setTemporaryAppAllowlist(ALLOW_WHILE_IDLE_WHITELIST_DURATION, 898 TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED, REASON_DENIED, ""); 899 } 900 } 901 902 @Override onPropertiesChanged(@onNull DeviceConfig.Properties properties)903 public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) { 904 boolean standbyQuotaUpdated = false; 905 boolean deviceIdleFuzzBoundariesUpdated = false; 906 synchronized (mLock) { 907 mVersion++; 908 for (String name : properties.getKeyset()) { 909 if (name == null) { 910 continue; 911 } 912 913 switch (name) { 914 case KEY_MIN_FUTURITY: 915 MIN_FUTURITY = properties.getLong( 916 KEY_MIN_FUTURITY, DEFAULT_MIN_FUTURITY); 917 break; 918 case KEY_MIN_INTERVAL: 919 MIN_INTERVAL = properties.getLong( 920 KEY_MIN_INTERVAL, DEFAULT_MIN_INTERVAL); 921 break; 922 case KEY_MAX_INTERVAL: 923 MAX_INTERVAL = properties.getLong( 924 KEY_MAX_INTERVAL, DEFAULT_MAX_INTERVAL); 925 break; 926 case KEY_ALLOW_WHILE_IDLE_QUOTA: 927 ALLOW_WHILE_IDLE_QUOTA = properties.getInt(KEY_ALLOW_WHILE_IDLE_QUOTA, 928 DEFAULT_ALLOW_WHILE_IDLE_QUOTA); 929 if (ALLOW_WHILE_IDLE_QUOTA <= 0) { 930 Slog.w(TAG, "Must have positive allow_while_idle quota"); 931 ALLOW_WHILE_IDLE_QUOTA = 1; 932 } 933 break; 934 case KEY_MIN_WINDOW: 935 MIN_WINDOW = properties.getLong(KEY_MIN_WINDOW, DEFAULT_MIN_WINDOW); 936 break; 937 case KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA: 938 ALLOW_WHILE_IDLE_COMPAT_QUOTA = properties.getInt( 939 KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA, 940 DEFAULT_ALLOW_WHILE_IDLE_COMPAT_QUOTA); 941 if (ALLOW_WHILE_IDLE_COMPAT_QUOTA <= 0) { 942 Slog.w(TAG, "Must have positive allow_while_idle_compat quota"); 943 ALLOW_WHILE_IDLE_COMPAT_QUOTA = 1; 944 } 945 break; 946 case KEY_ALLOW_WHILE_IDLE_WINDOW: 947 ALLOW_WHILE_IDLE_WINDOW = properties.getLong( 948 KEY_ALLOW_WHILE_IDLE_WINDOW, DEFAULT_ALLOW_WHILE_IDLE_WINDOW); 949 950 if (ALLOW_WHILE_IDLE_WINDOW > INTERVAL_HOUR) { 951 Slog.w(TAG, "Cannot have allow_while_idle_window > " 952 + INTERVAL_HOUR); 953 ALLOW_WHILE_IDLE_WINDOW = INTERVAL_HOUR; 954 } else if (ALLOW_WHILE_IDLE_WINDOW != DEFAULT_ALLOW_WHILE_IDLE_WINDOW) { 955 Slog.w(TAG, "Using a non-default allow_while_idle_window = " 956 + ALLOW_WHILE_IDLE_WINDOW); 957 } 958 break; 959 case KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW: 960 ALLOW_WHILE_IDLE_COMPAT_WINDOW = properties.getLong( 961 KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW, 962 DEFAULT_ALLOW_WHILE_IDLE_COMPAT_WINDOW); 963 964 if (ALLOW_WHILE_IDLE_COMPAT_WINDOW > INTERVAL_HOUR) { 965 Slog.w(TAG, "Cannot have allow_while_idle_compat_window > " 966 + INTERVAL_HOUR); 967 ALLOW_WHILE_IDLE_COMPAT_WINDOW = INTERVAL_HOUR; 968 } else if (ALLOW_WHILE_IDLE_COMPAT_WINDOW 969 != DEFAULT_ALLOW_WHILE_IDLE_COMPAT_WINDOW) { 970 Slog.w(TAG, "Using a non-default allow_while_idle_compat_window = " 971 + ALLOW_WHILE_IDLE_COMPAT_WINDOW); 972 } 973 break; 974 case KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION: 975 ALLOW_WHILE_IDLE_WHITELIST_DURATION = properties.getLong( 976 KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION, 977 DEFAULT_ALLOW_WHILE_IDLE_ALLOWLIST_DURATION); 978 updateAllowWhileIdleWhitelistDurationLocked(); 979 break; 980 case KEY_LISTENER_TIMEOUT: 981 LISTENER_TIMEOUT = properties.getLong( 982 KEY_LISTENER_TIMEOUT, DEFAULT_LISTENER_TIMEOUT); 983 break; 984 case KEY_MAX_ALARMS_PER_UID: 985 MAX_ALARMS_PER_UID = properties.getInt( 986 KEY_MAX_ALARMS_PER_UID, DEFAULT_MAX_ALARMS_PER_UID); 987 if (MAX_ALARMS_PER_UID < DEFAULT_MAX_ALARMS_PER_UID) { 988 Slog.w(TAG, "Cannot set " + KEY_MAX_ALARMS_PER_UID + " lower than " 989 + DEFAULT_MAX_ALARMS_PER_UID); 990 MAX_ALARMS_PER_UID = DEFAULT_MAX_ALARMS_PER_UID; 991 } 992 break; 993 case KEY_APP_STANDBY_WINDOW: 994 case KEY_APP_STANDBY_RESTRICTED_WINDOW: 995 updateStandbyWindowsLocked(); 996 break; 997 case KEY_TIME_TICK_ALLOWED_WHILE_IDLE: 998 TIME_TICK_ALLOWED_WHILE_IDLE = properties.getBoolean( 999 KEY_TIME_TICK_ALLOWED_WHILE_IDLE, 1000 DEFAULT_TIME_TICK_ALLOWED_WHILE_IDLE); 1001 break; 1002 case KEY_PRIORITY_ALARM_DELAY: 1003 PRIORITY_ALARM_DELAY = properties.getLong(KEY_PRIORITY_ALARM_DELAY, 1004 DEFAULT_PRIORITY_ALARM_DELAY); 1005 break; 1006 case KEY_MIN_DEVICE_IDLE_FUZZ: 1007 case KEY_MAX_DEVICE_IDLE_FUZZ: 1008 if (!deviceIdleFuzzBoundariesUpdated) { 1009 updateDeviceIdleFuzzBoundaries(); 1010 deviceIdleFuzzBoundariesUpdated = true; 1011 } 1012 break; 1013 case KEY_TEMPORARY_QUOTA_BUMP: 1014 TEMPORARY_QUOTA_BUMP = properties.getInt(KEY_TEMPORARY_QUOTA_BUMP, 1015 DEFAULT_TEMPORARY_QUOTA_BUMP); 1016 break; 1017 case KEY_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF: 1018 DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF = properties.getBoolean( 1019 KEY_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF, 1020 DEFAULT_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF); 1021 break; 1022 case KEY_CACHED_LISTENER_REMOVAL_DELAY: 1023 CACHED_LISTENER_REMOVAL_DELAY = properties.getLong( 1024 KEY_CACHED_LISTENER_REMOVAL_DELAY, 1025 DEFAULT_CACHED_LISTENER_REMOVAL_DELAY); 1026 break; 1027 default: 1028 if (name.startsWith(KEY_PREFIX_STANDBY_QUOTA) && !standbyQuotaUpdated) { 1029 // The quotas need to be updated in order, so we can't just rely 1030 // on the property iteration order. 1031 updateStandbyQuotasLocked(); 1032 standbyQuotaUpdated = true; 1033 } 1034 break; 1035 } 1036 } 1037 } 1038 } 1039 updateDeviceIdleFuzzBoundaries()1040 private void updateDeviceIdleFuzzBoundaries() { 1041 final DeviceConfig.Properties properties = DeviceConfig.getProperties( 1042 DeviceConfig.NAMESPACE_ALARM_MANAGER, 1043 KEY_MIN_DEVICE_IDLE_FUZZ, KEY_MAX_DEVICE_IDLE_FUZZ); 1044 1045 MIN_DEVICE_IDLE_FUZZ = properties.getLong(KEY_MIN_DEVICE_IDLE_FUZZ, 1046 DEFAULT_MIN_DEVICE_IDLE_FUZZ); 1047 MAX_DEVICE_IDLE_FUZZ = properties.getLong(KEY_MAX_DEVICE_IDLE_FUZZ, 1048 DEFAULT_MAX_DEVICE_IDLE_FUZZ); 1049 1050 if (MAX_DEVICE_IDLE_FUZZ < MIN_DEVICE_IDLE_FUZZ) { 1051 Slog.w(TAG, "max_device_idle_fuzz cannot be smaller than" 1052 + " min_device_idle_fuzz! Increasing to " 1053 + MIN_DEVICE_IDLE_FUZZ); 1054 MAX_DEVICE_IDLE_FUZZ = MIN_DEVICE_IDLE_FUZZ; 1055 } 1056 } 1057 updateStandbyQuotasLocked()1058 private void updateStandbyQuotasLocked() { 1059 // The bucket quotas need to be read as an atomic unit but the properties passed to 1060 // onPropertiesChanged may only have one key populated at a time. 1061 final DeviceConfig.Properties properties = DeviceConfig.getProperties( 1062 DeviceConfig.NAMESPACE_ALARM_MANAGER, KEYS_APP_STANDBY_QUOTAS); 1063 1064 APP_STANDBY_QUOTAS[ACTIVE_INDEX] = properties.getInt( 1065 KEYS_APP_STANDBY_QUOTAS[ACTIVE_INDEX], 1066 DEFAULT_APP_STANDBY_QUOTAS[ACTIVE_INDEX]); 1067 for (int i = WORKING_INDEX; i < KEYS_APP_STANDBY_QUOTAS.length; i++) { 1068 APP_STANDBY_QUOTAS[i] = properties.getInt( 1069 KEYS_APP_STANDBY_QUOTAS[i], 1070 Math.min(APP_STANDBY_QUOTAS[i - 1], DEFAULT_APP_STANDBY_QUOTAS[i])); 1071 } 1072 1073 APP_STANDBY_RESTRICTED_QUOTA = Math.max(1, 1074 DeviceConfig.getInt(DeviceConfig.NAMESPACE_ALARM_MANAGER, 1075 KEY_APP_STANDBY_RESTRICTED_QUOTA, 1076 DEFAULT_APP_STANDBY_RESTRICTED_QUOTA)); 1077 } 1078 updateStandbyWindowsLocked()1079 private void updateStandbyWindowsLocked() { 1080 // The bucket windows need to be read as an atomic unit but the properties passed to 1081 // onPropertiesChanged may only have one key populated at a time. 1082 final DeviceConfig.Properties properties = DeviceConfig.getProperties( 1083 DeviceConfig.NAMESPACE_ALARM_MANAGER, 1084 KEY_APP_STANDBY_WINDOW, KEY_APP_STANDBY_RESTRICTED_WINDOW); 1085 APP_STANDBY_WINDOW = properties.getLong( 1086 KEY_APP_STANDBY_WINDOW, DEFAULT_APP_STANDBY_WINDOW); 1087 if (APP_STANDBY_WINDOW > DEFAULT_APP_STANDBY_WINDOW) { 1088 Slog.w(TAG, "Cannot exceed the app_standby_window size of " 1089 + DEFAULT_APP_STANDBY_WINDOW); 1090 APP_STANDBY_WINDOW = DEFAULT_APP_STANDBY_WINDOW; 1091 } else if (APP_STANDBY_WINDOW < DEFAULT_APP_STANDBY_WINDOW) { 1092 // Not recommended outside of testing. 1093 Slog.w(TAG, "Using a non-default app_standby_window of " + APP_STANDBY_WINDOW); 1094 } 1095 1096 APP_STANDBY_RESTRICTED_WINDOW = Math.max(APP_STANDBY_WINDOW, 1097 properties.getLong( 1098 KEY_APP_STANDBY_RESTRICTED_WINDOW, 1099 DEFAULT_APP_STANDBY_RESTRICTED_WINDOW)); 1100 } 1101 dump(IndentingPrintWriter pw)1102 void dump(IndentingPrintWriter pw) { 1103 pw.println("Settings:"); 1104 1105 pw.increaseIndent(); 1106 1107 pw.print("version", mVersion); 1108 pw.println(); 1109 1110 pw.print(KEY_MIN_FUTURITY); 1111 pw.print("="); 1112 TimeUtils.formatDuration(MIN_FUTURITY, pw); 1113 pw.println(); 1114 1115 pw.print(KEY_MIN_INTERVAL); 1116 pw.print("="); 1117 TimeUtils.formatDuration(MIN_INTERVAL, pw); 1118 pw.println(); 1119 1120 pw.print(KEY_MAX_INTERVAL); 1121 pw.print("="); 1122 TimeUtils.formatDuration(MAX_INTERVAL, pw); 1123 pw.println(); 1124 1125 pw.print(KEY_MIN_WINDOW); 1126 pw.print("="); 1127 TimeUtils.formatDuration(MIN_WINDOW, pw); 1128 pw.println(); 1129 1130 pw.print(KEY_LISTENER_TIMEOUT); 1131 pw.print("="); 1132 TimeUtils.formatDuration(LISTENER_TIMEOUT, pw); 1133 pw.println(); 1134 1135 pw.print(KEY_ALLOW_WHILE_IDLE_QUOTA, ALLOW_WHILE_IDLE_QUOTA); 1136 pw.println(); 1137 1138 pw.print(KEY_ALLOW_WHILE_IDLE_WINDOW); 1139 pw.print("="); 1140 TimeUtils.formatDuration(ALLOW_WHILE_IDLE_WINDOW, pw); 1141 pw.println(); 1142 1143 pw.print(KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA, ALLOW_WHILE_IDLE_COMPAT_QUOTA); 1144 pw.println(); 1145 1146 pw.print(KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW); 1147 pw.print("="); 1148 TimeUtils.formatDuration(ALLOW_WHILE_IDLE_COMPAT_WINDOW, pw); 1149 pw.println(); 1150 1151 pw.print(KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION); 1152 pw.print("="); 1153 TimeUtils.formatDuration(ALLOW_WHILE_IDLE_WHITELIST_DURATION, pw); 1154 pw.println(); 1155 1156 pw.print(KEY_MAX_ALARMS_PER_UID, MAX_ALARMS_PER_UID); 1157 pw.println(); 1158 1159 pw.print(KEY_APP_STANDBY_WINDOW); 1160 pw.print("="); 1161 TimeUtils.formatDuration(APP_STANDBY_WINDOW, pw); 1162 pw.println(); 1163 1164 for (int i = 0; i < KEYS_APP_STANDBY_QUOTAS.length; i++) { 1165 pw.print(KEYS_APP_STANDBY_QUOTAS[i], APP_STANDBY_QUOTAS[i]); 1166 pw.println(); 1167 } 1168 1169 pw.print(KEY_APP_STANDBY_RESTRICTED_QUOTA, APP_STANDBY_RESTRICTED_QUOTA); 1170 pw.println(); 1171 1172 pw.print(KEY_APP_STANDBY_RESTRICTED_WINDOW); 1173 pw.print("="); 1174 TimeUtils.formatDuration(APP_STANDBY_RESTRICTED_WINDOW, pw); 1175 pw.println(); 1176 1177 pw.print(KEY_TIME_TICK_ALLOWED_WHILE_IDLE, TIME_TICK_ALLOWED_WHILE_IDLE); 1178 pw.println(); 1179 1180 pw.print(KEY_PRIORITY_ALARM_DELAY); 1181 pw.print("="); 1182 TimeUtils.formatDuration(PRIORITY_ALARM_DELAY, pw); 1183 pw.println(); 1184 1185 pw.print(KEY_MIN_DEVICE_IDLE_FUZZ); 1186 pw.print("="); 1187 TimeUtils.formatDuration(MIN_DEVICE_IDLE_FUZZ, pw); 1188 pw.println(); 1189 1190 pw.print(KEY_MAX_DEVICE_IDLE_FUZZ); 1191 pw.print("="); 1192 TimeUtils.formatDuration(MAX_DEVICE_IDLE_FUZZ, pw); 1193 pw.println(); 1194 1195 pw.print(KEY_TEMPORARY_QUOTA_BUMP, TEMPORARY_QUOTA_BUMP); 1196 pw.println(); 1197 1198 pw.print(KEY_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF, 1199 DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF); 1200 pw.println(); 1201 1202 pw.print(KEY_CACHED_LISTENER_REMOVAL_DELAY); 1203 pw.print("="); 1204 TimeUtils.formatDuration(CACHED_LISTENER_REMOVAL_DELAY, pw); 1205 pw.println(); 1206 1207 pw.decreaseIndent(); 1208 } 1209 dumpProto(ProtoOutputStream proto, long fieldId)1210 void dumpProto(ProtoOutputStream proto, long fieldId) { 1211 final long token = proto.start(fieldId); 1212 1213 proto.write(ConstantsProto.MIN_FUTURITY_DURATION_MS, MIN_FUTURITY); 1214 proto.write(ConstantsProto.MIN_INTERVAL_DURATION_MS, MIN_INTERVAL); 1215 proto.write(ConstantsProto.MAX_INTERVAL_DURATION_MS, MAX_INTERVAL); 1216 proto.write(ConstantsProto.LISTENER_TIMEOUT_DURATION_MS, LISTENER_TIMEOUT); 1217 proto.write(ConstantsProto.ALLOW_WHILE_IDLE_WHITELIST_DURATION_MS, 1218 ALLOW_WHILE_IDLE_WHITELIST_DURATION); 1219 1220 proto.end(token); 1221 } 1222 } 1223 1224 Constants mConstants; 1225 1226 /** Dispatch priority to use for system alarms. */ 1227 static final int PRIORITY_SYSTEM = 0; 1228 /** Dispatch priority to use for a package that has any wakeup alarm in the pending batch. */ 1229 static final int PRIORITY_WAKEUP = 1; 1230 /** The default dispatch priority to use when no special conditions apply. */ 1231 static final int PRIORITY_NORMAL = 2; 1232 1233 /** 1234 * Priority to assign to alarms in an outgoing batch. Higher priority alarms are considered more 1235 * urgent than lower priority ones (smaller value is higher priority). Priorities are assigned 1236 * per package, so all alarms in one package will share the same priority in an outgoing batch - 1237 * which should be the highest (minimum) priority computed over all its alarms. 1238 * This is done to ensure that alarms in the same package preserve their relative ordering. 1239 */ 1240 @IntDef(prefix = "PRIORITY_", value = { 1241 PRIORITY_SYSTEM, 1242 PRIORITY_WAKEUP, 1243 PRIORITY_NORMAL, 1244 }) 1245 @Retention(RetentionPolicy.SOURCE) 1246 public @interface DispatchPriority {} 1247 1248 final Comparator<Alarm> mAlarmDispatchComparator = (lhs, rhs) -> { 1249 1250 // Alarm to exit device_idle should go out first. 1251 final boolean idleUntil1 = (lhs.flags & FLAG_IDLE_UNTIL) != 0; 1252 final boolean idleUntil2 = (rhs.flags & FLAG_IDLE_UNTIL) != 0; 1253 if (idleUntil1 != idleUntil2) { 1254 return idleUntil1 ? -1 : 1; 1255 } 1256 1257 // Then, priority class trumps everything. SYSTEM < WAKEUP < NORMAL 1258 if (lhs.priorityClass < rhs.priorityClass) { 1259 return -1; 1260 } else if (lhs.priorityClass > rhs.priorityClass) { 1261 return 1; 1262 } 1263 1264 // Within all system alarms, pulling time_tick to the front, as it is time-sensitive. 1265 final boolean timeTick1 = (lhs.listener == mTimeTickTrigger); 1266 final boolean timeTick2 = (rhs.listener == mTimeTickTrigger); 1267 if (timeTick1 != timeTick2) { 1268 return timeTick1 ? -1 : 1; 1269 } 1270 1271 // Within each class, sort by requested delivery time 1272 if (lhs.getRequestedElapsed() < rhs.getRequestedElapsed()) { 1273 return -1; 1274 } else if (lhs.getRequestedElapsed() > rhs.getRequestedElapsed()) { 1275 return 1; 1276 } 1277 1278 return 0; 1279 }; 1280 1281 /** 1282 * Assigns a {@link DispatchPriority} to each alarm that will be used to order alarms in an 1283 * outgoing batch. 1284 * 1285 * @param alarms The batch of alarms about to be sent. 1286 */ calculateDeliveryPriorities(ArrayList<Alarm> alarms)1287 void calculateDeliveryPriorities(ArrayList<Alarm> alarms) { 1288 final int N = alarms.size(); 1289 1290 // Batches are expected to be small (generally N < 10). So an additional iteration to 1291 // collect a small set of UserPackage objects should be unnoticeable. 1292 final ArraySet<UserPackage> wakeupPackages = new ArraySet<>(4); 1293 for (int i = 0; i < N; i++) { 1294 final Alarm a = alarms.get(i); 1295 if (a.wakeup) { 1296 wakeupPackages.add( 1297 UserPackage.of(UserHandle.getUserId(a.creatorUid), a.sourcePackage)); 1298 } 1299 } 1300 1301 for (int i = 0; i < N; i++) { 1302 final Alarm a = alarms.get(i); 1303 1304 if (a.creatorUid == Process.SYSTEM_UID && "android".equals(a.sourcePackage)) { 1305 a.priorityClass = PRIORITY_SYSTEM; 1306 } else if (wakeupPackages.contains( 1307 UserPackage.of(UserHandle.getUserId(a.creatorUid), a.sourcePackage))) { 1308 a.priorityClass = PRIORITY_WAKEUP; 1309 } else { 1310 a.priorityClass = PRIORITY_NORMAL; 1311 } 1312 } 1313 } 1314 1315 // minimum recurrence period or alarm futurity for us to be able to fuzz it 1316 static final long MIN_FUZZABLE_INTERVAL = 10000; 1317 @GuardedBy("mLock") 1318 AlarmStore mAlarmStore; 1319 1320 UserWakeupStore mUserWakeupStore; 1321 // set to non-null if in idle mode; while in this mode, any alarms we don't want 1322 // to run during this time are rescehduled to go off after this alarm. 1323 Alarm mPendingIdleUntil = null; 1324 Alarm mNextWakeFromIdle = null; 1325 1326 @VisibleForTesting AlarmManagerService(Context context, Injector injector)1327 AlarmManagerService(Context context, Injector injector) { 1328 super(context); 1329 mInjector = injector; 1330 } 1331 AlarmManagerService(Context context)1332 public AlarmManagerService(Context context) { 1333 this(context, new Injector(context)); 1334 } 1335 isRtc(int type)1336 static boolean isRtc(int type) { 1337 return (type == RTC || type == RTC_WAKEUP); 1338 } 1339 convertToElapsed(long when, int type)1340 private long convertToElapsed(long when, int type) { 1341 if (isRtc(type)) { 1342 when -= mInjector.getCurrentTimeMillis() - mInjector.getElapsedRealtimeMillis(); 1343 } 1344 return when; 1345 } 1346 1347 /** 1348 * This is the minimum window that can be requested for the given alarm. Windows smaller than 1349 * this value will be elongated to match it. 1350 * Current heuristic is similar to {@link #maxTriggerTime(long, long, long)}, the minimum 1351 * allowed window is either {@link Constants#MIN_WINDOW} or 75% of the alarm's futurity, 1352 * whichever is smaller. 1353 */ getMinimumAllowedWindow(long nowElapsed, long triggerElapsed)1354 long getMinimumAllowedWindow(long nowElapsed, long triggerElapsed) { 1355 final long futurity = triggerElapsed - nowElapsed; 1356 return Math.min((long) (futurity * 0.75), mConstants.MIN_WINDOW); 1357 } 1358 1359 // Apply a heuristic to { recurrence interval, futurity of the trigger time } to 1360 // calculate the end of our nominal delivery window for the alarm. maxTriggerTime(long now, long triggerAtTime, long interval)1361 static long maxTriggerTime(long now, long triggerAtTime, long interval) { 1362 // Current heuristic: batchable window is 75% of either the recurrence interval 1363 // [for a periodic alarm] or of the time from now to the desired delivery time, 1364 // with a minimum delay/interval of 10 seconds, under which we will simply not 1365 // defer the alarm. 1366 long futurity = (interval == 0) 1367 ? (triggerAtTime - now) 1368 : interval; 1369 if (futurity < MIN_FUZZABLE_INTERVAL) { 1370 futurity = 0; 1371 } 1372 long maxElapsed = addClampPositive(triggerAtTime, (long) (0.75 * futurity)); 1373 // For non-repeating alarms, window is capped at a maximum of one hour from the requested 1374 // delivery time. This allows for inexact-while-idle alarms to be slightly more reliable. 1375 // In practice, the delivery window should generally be much smaller than that 1376 // when the device is not idling. 1377 if (interval == 0) { 1378 maxElapsed = Math.min(maxElapsed, addClampPositive(triggerAtTime, INTERVAL_HOUR)); 1379 } 1380 return maxElapsed; 1381 } 1382 1383 // The RTC clock has moved arbitrarily, so we need to recalculate all the RTC alarm deliveries. reevaluateRtcAlarms()1384 void reevaluateRtcAlarms() { 1385 synchronized (mLock) { 1386 boolean changed = mAlarmStore.updateAlarmDeliveries(a -> { 1387 if (!isRtc(a.type)) { 1388 return false; 1389 } 1390 return restoreRequestedTime(a); 1391 }); 1392 1393 if (changed && mPendingIdleUntil != null) { 1394 if (mNextWakeFromIdle != null && isRtc(mNextWakeFromIdle.type)) { 1395 // The next wake from idle got updated due to the rtc time change, so we need 1396 // to update the time we have to come out of idle too. 1397 final boolean idleUntilUpdated = mAlarmStore.updateAlarmDeliveries( 1398 a -> (a == mPendingIdleUntil) && adjustIdleUntilTime(a)); 1399 if (idleUntilUpdated) { 1400 mAlarmStore.updateAlarmDeliveries( 1401 alarm -> adjustDeliveryTimeBasedOnDeviceIdle(alarm)); 1402 } 1403 } 1404 } 1405 1406 if (changed) { 1407 rescheduleKernelAlarmsLocked(); 1408 // Only time shifted, so the next alarm clock will not change 1409 } 1410 } 1411 } 1412 1413 /** 1414 * Recalculates alarm send times based on the current app-standby buckets 1415 * 1416 * @param targetPackages [Package, User] pairs for which alarms need to be re-evaluated, 1417 * null indicates all 1418 * @return True if there was any reordering done to the current list. 1419 */ reorderAlarmsBasedOnStandbyBuckets(ArraySet<UserPackage> targetPackages)1420 boolean reorderAlarmsBasedOnStandbyBuckets(ArraySet<UserPackage> targetPackages) { 1421 final long start = mStatLogger.getTime(); 1422 1423 final boolean changed = mAlarmStore.updateAlarmDeliveries(a -> { 1424 final UserPackage userPackage = 1425 UserPackage.of(UserHandle.getUserId(a.creatorUid), a.sourcePackage); 1426 if (targetPackages != null && !targetPackages.contains(userPackage)) { 1427 return false; 1428 } 1429 return adjustDeliveryTimeBasedOnBucketLocked(a); 1430 }); 1431 1432 mStatLogger.logDurationStat(Stats.REORDER_ALARMS_FOR_STANDBY, start); 1433 return changed; 1434 } 1435 restoreRequestedTime(Alarm a)1436 private boolean restoreRequestedTime(Alarm a) { 1437 return a.setPolicyElapsed(REQUESTER_POLICY_INDEX, convertToElapsed(a.origWhen, a.type)); 1438 } 1439 clampPositive(long val)1440 static long clampPositive(long val) { 1441 return (val >= 0) ? val : Long.MAX_VALUE; 1442 } 1443 addClampPositive(long val1, long val2)1444 static long addClampPositive(long val1, long val2) { 1445 long val = val1 + val2; 1446 if (val >= 0) { 1447 return val; 1448 } else if (val1 >= 0 && val2 >= 0) { 1449 /* Both are +ve, so overflow happened. */ 1450 return Long.MAX_VALUE; 1451 } else { 1452 return 0; 1453 } 1454 } 1455 1456 /** 1457 * Sends alarms that were blocked due to user applied background restrictions - either because 1458 * the user lifted those or the uid came to foreground. 1459 * 1460 * @param uid uid to filter on 1461 * @param packageName package to filter on, or null for all packages in uid 1462 */ 1463 @GuardedBy("mLock") sendPendingBackgroundAlarmsLocked(int uid, String packageName)1464 void sendPendingBackgroundAlarmsLocked(int uid, String packageName) { 1465 final ArrayList<Alarm> alarmsForUid = mPendingBackgroundAlarms.get(uid); 1466 if (alarmsForUid == null || alarmsForUid.size() == 0) { 1467 return; 1468 } 1469 final ArrayList<Alarm> alarmsToDeliver; 1470 if (packageName != null) { 1471 if (DEBUG_BG_LIMIT) { 1472 Slog.d(TAG, "Sending blocked alarms for uid " + uid + ", package " + packageName); 1473 } 1474 alarmsToDeliver = new ArrayList<>(); 1475 for (int i = alarmsForUid.size() - 1; i >= 0; i--) { 1476 final Alarm a = alarmsForUid.get(i); 1477 if (a.matches(packageName)) { 1478 alarmsToDeliver.add(alarmsForUid.remove(i)); 1479 } 1480 } 1481 if (alarmsForUid.size() == 0) { 1482 mPendingBackgroundAlarms.remove(uid); 1483 } 1484 } else { 1485 if (DEBUG_BG_LIMIT) { 1486 Slog.d(TAG, "Sending blocked alarms for uid " + uid); 1487 } 1488 alarmsToDeliver = alarmsForUid; 1489 mPendingBackgroundAlarms.remove(uid); 1490 } 1491 deliverPendingBackgroundAlarmsLocked(alarmsToDeliver, mInjector.getElapsedRealtimeMillis()); 1492 } 1493 1494 /** 1495 * Check all alarms in {@link #mPendingBackgroundAlarms} and send the ones that are not 1496 * restricted. 1497 * 1498 * This is only called when the power save allowlist changes, so it's okay to be slow. 1499 */ 1500 @GuardedBy("mLock") sendAllUnrestrictedPendingBackgroundAlarmsLocked()1501 void sendAllUnrestrictedPendingBackgroundAlarmsLocked() { 1502 final ArrayList<Alarm> alarmsToDeliver = new ArrayList<>(); 1503 1504 findAllUnrestrictedPendingBackgroundAlarmsLockedInner( 1505 mPendingBackgroundAlarms, alarmsToDeliver, this::isBackgroundRestricted); 1506 1507 if (alarmsToDeliver.size() > 0) { 1508 deliverPendingBackgroundAlarmsLocked( 1509 alarmsToDeliver, mInjector.getElapsedRealtimeMillis()); 1510 } 1511 } 1512 1513 @VisibleForTesting findAllUnrestrictedPendingBackgroundAlarmsLockedInner( SparseArray<ArrayList<Alarm>> pendingAlarms, ArrayList<Alarm> unrestrictedAlarms, Predicate<Alarm> isBackgroundRestricted)1514 static void findAllUnrestrictedPendingBackgroundAlarmsLockedInner( 1515 SparseArray<ArrayList<Alarm>> pendingAlarms, ArrayList<Alarm> unrestrictedAlarms, 1516 Predicate<Alarm> isBackgroundRestricted) { 1517 1518 for (int uidIndex = pendingAlarms.size() - 1; uidIndex >= 0; uidIndex--) { 1519 final ArrayList<Alarm> alarmsForUid = pendingAlarms.valueAt(uidIndex); 1520 1521 for (int alarmIndex = alarmsForUid.size() - 1; alarmIndex >= 0; alarmIndex--) { 1522 final Alarm alarm = alarmsForUid.get(alarmIndex); 1523 1524 if (isBackgroundRestricted.test(alarm)) { 1525 continue; 1526 } 1527 1528 unrestrictedAlarms.add(alarm); 1529 alarmsForUid.remove(alarmIndex); 1530 } 1531 1532 if (alarmsForUid.size() == 0) { 1533 pendingAlarms.removeAt(uidIndex); 1534 } 1535 } 1536 } 1537 1538 @GuardedBy("mLock") deliverPendingBackgroundAlarmsLocked(ArrayList<Alarm> alarms, long nowELAPSED)1539 private void deliverPendingBackgroundAlarmsLocked(ArrayList<Alarm> alarms, long nowELAPSED) { 1540 final int N = alarms.size(); 1541 boolean hasWakeup = false; 1542 for (int i = 0; i < N; i++) { 1543 final Alarm alarm = alarms.get(i); 1544 if (alarm.wakeup) { 1545 hasWakeup = true; 1546 } 1547 alarm.count = 1; 1548 // Recurring alarms may have passed several alarm intervals while the 1549 // alarm was kept pending. Send the appropriate trigger count. 1550 if (alarm.repeatInterval > 0) { 1551 alarm.count += (nowELAPSED - alarm.getRequestedElapsed()) / alarm.repeatInterval; 1552 // Also schedule its next recurrence 1553 final long delta = alarm.count * alarm.repeatInterval; 1554 final long nextElapsed = alarm.getRequestedElapsed() + delta; 1555 final long nextMaxElapsed = maxTriggerTime(nowELAPSED, nextElapsed, 1556 alarm.repeatInterval); 1557 setImplLocked(alarm.type, alarm.origWhen + delta, nextElapsed, 1558 nextMaxElapsed - nextElapsed, alarm.repeatInterval, alarm.operation, null, 1559 null, alarm.flags, alarm.workSource, alarm.alarmClock, alarm.uid, 1560 alarm.packageName, null, EXACT_ALLOW_REASON_NOT_APPLICABLE); 1561 // Kernel alarms will be rescheduled as needed in setImplLocked 1562 } 1563 } 1564 if (!hasWakeup && checkAllowNonWakeupDelayLocked(nowELAPSED)) { 1565 // No need to wakeup for non wakeup alarms 1566 if (mPendingNonWakeupAlarms.size() == 0) { 1567 mStartCurrentDelayTime = nowELAPSED; 1568 mNextNonWakeupDeliveryTime = nowELAPSED 1569 + ((currentNonWakeupFuzzLocked(nowELAPSED) * 3) / 2); 1570 } 1571 mPendingNonWakeupAlarms.addAll(alarms); 1572 mNumDelayedAlarms += alarms.size(); 1573 } else { 1574 if (DEBUG_BG_LIMIT) { 1575 Slog.d(TAG, "Waking up to deliver pending blocked alarms"); 1576 } 1577 // Since we are waking up, also deliver any pending non wakeup alarms we have. 1578 if (mPendingNonWakeupAlarms.size() > 0) { 1579 alarms.addAll(mPendingNonWakeupAlarms); 1580 final long thisDelayTime = nowELAPSED - mStartCurrentDelayTime; 1581 mTotalDelayTime += thisDelayTime; 1582 if (mMaxDelayTime < thisDelayTime) { 1583 mMaxDelayTime = thisDelayTime; 1584 } 1585 mPendingNonWakeupAlarms.clear(); 1586 } 1587 calculateDeliveryPriorities(alarms); 1588 Collections.sort(alarms, mAlarmDispatchComparator); 1589 deliverAlarmsLocked(alarms, nowELAPSED); 1590 } 1591 } 1592 1593 static final class InFlight { 1594 final PendingIntent mPendingIntent; 1595 final long mWhenElapsed; 1596 final IBinder mListener; 1597 final WorkSource mWorkSource; 1598 final int mUid; 1599 final int mCreatorUid; 1600 final String mTag; 1601 final BroadcastStats mBroadcastStats; 1602 final FilterStats mFilterStats; 1603 final int mAlarmType; 1604 final int mPriorityClass; 1605 InFlight(AlarmManagerService service, Alarm alarm, long nowELAPSED)1606 InFlight(AlarmManagerService service, Alarm alarm, long nowELAPSED) { 1607 mPendingIntent = alarm.operation; 1608 mWhenElapsed = nowELAPSED; 1609 mListener = alarm.listener != null ? alarm.listener.asBinder() : null; 1610 mWorkSource = alarm.workSource; 1611 mUid = alarm.uid; 1612 mCreatorUid = alarm.creatorUid; 1613 mTag = alarm.statsTag; 1614 mBroadcastStats = (alarm.operation != null) 1615 ? service.getStatsLocked(alarm.operation) 1616 : service.getStatsLocked(alarm.uid, alarm.packageName); 1617 FilterStats fs = mBroadcastStats.filterStats.get(mTag); 1618 if (fs == null) { 1619 fs = new FilterStats(mBroadcastStats, mTag); 1620 mBroadcastStats.filterStats.put(mTag, fs); 1621 } 1622 fs.lastTime = nowELAPSED; 1623 mFilterStats = fs; 1624 mAlarmType = alarm.type; 1625 mPriorityClass = alarm.priorityClass; 1626 } 1627 isBroadcast()1628 boolean isBroadcast() { 1629 return mPendingIntent != null && mPendingIntent.isBroadcast(); 1630 } 1631 1632 @Override toString()1633 public String toString() { 1634 return "InFlight{" 1635 + "pendingIntent=" + mPendingIntent 1636 + ", when=" + mWhenElapsed 1637 + ", workSource=" + mWorkSource 1638 + ", uid=" + mUid 1639 + ", creatorUid=" + mCreatorUid 1640 + ", tag=" + mTag 1641 + ", broadcastStats=" + mBroadcastStats 1642 + ", filterStats=" + mFilterStats 1643 + ", alarmType=" + mAlarmType 1644 + ", priorityClass=" + mPriorityClass 1645 + "}"; 1646 } 1647 dumpDebug(ProtoOutputStream proto, long fieldId)1648 public void dumpDebug(ProtoOutputStream proto, long fieldId) { 1649 final long token = proto.start(fieldId); 1650 1651 proto.write(InFlightProto.UID, mUid); 1652 proto.write(InFlightProto.TAG, mTag); 1653 proto.write(InFlightProto.WHEN_ELAPSED_MS, mWhenElapsed); 1654 proto.write(InFlightProto.ALARM_TYPE, mAlarmType); 1655 if (mPendingIntent != null) { 1656 mPendingIntent.dumpDebug(proto, InFlightProto.PENDING_INTENT); 1657 } 1658 if (mBroadcastStats != null) { 1659 mBroadcastStats.dumpDebug(proto, InFlightProto.BROADCAST_STATS); 1660 } 1661 if (mFilterStats != null) { 1662 mFilterStats.dumpDebug(proto, InFlightProto.FILTER_STATS); 1663 } 1664 if (mWorkSource != null) { 1665 mWorkSource.dumpDebug(proto, InFlightProto.WORK_SOURCE); 1666 } 1667 1668 proto.end(token); 1669 } 1670 } 1671 notifyBroadcastAlarmPendingLocked(int uid)1672 private void notifyBroadcastAlarmPendingLocked(int uid) { 1673 final int numListeners = mInFlightListeners.size(); 1674 for (int i = 0; i < numListeners; i++) { 1675 mInFlightListeners.get(i).broadcastAlarmPending(uid); 1676 } 1677 } 1678 notifyBroadcastAlarmCompleteLocked(int uid)1679 private void notifyBroadcastAlarmCompleteLocked(int uid) { 1680 final int numListeners = mInFlightListeners.size(); 1681 for (int i = 0; i < numListeners; i++) { 1682 mInFlightListeners.get(i).broadcastAlarmComplete(uid); 1683 } 1684 } 1685 1686 static final class FilterStats { 1687 final BroadcastStats mBroadcastStats; 1688 final String mTag; 1689 1690 long lastTime; 1691 long aggregateTime; 1692 int count; 1693 int numWakeup; 1694 long startTime; 1695 int nesting; 1696 FilterStats(BroadcastStats broadcastStats, String tag)1697 FilterStats(BroadcastStats broadcastStats, String tag) { 1698 mBroadcastStats = broadcastStats; 1699 mTag = tag; 1700 } 1701 1702 @Override toString()1703 public String toString() { 1704 return "FilterStats{" 1705 + "tag=" + mTag 1706 + ", lastTime=" + lastTime 1707 + ", aggregateTime=" + aggregateTime 1708 + ", count=" + count 1709 + ", numWakeup=" + numWakeup 1710 + ", startTime=" + startTime 1711 + ", nesting=" + nesting 1712 + "}"; 1713 } 1714 dumpDebug(ProtoOutputStream proto, long fieldId)1715 public void dumpDebug(ProtoOutputStream proto, long fieldId) { 1716 final long token = proto.start(fieldId); 1717 1718 proto.write(FilterStatsProto.TAG, mTag); 1719 proto.write(FilterStatsProto.LAST_FLIGHT_TIME_REALTIME, lastTime); 1720 proto.write(FilterStatsProto.TOTAL_FLIGHT_DURATION_MS, aggregateTime); 1721 proto.write(FilterStatsProto.COUNT, count); 1722 proto.write(FilterStatsProto.WAKEUP_COUNT, numWakeup); 1723 proto.write(FilterStatsProto.START_TIME_REALTIME, startTime); 1724 proto.write(FilterStatsProto.NESTING, nesting); 1725 1726 proto.end(token); 1727 } 1728 } 1729 1730 static final class BroadcastStats { 1731 final int mUid; 1732 final String mPackageName; 1733 1734 long aggregateTime; 1735 int count; 1736 int numWakeup; 1737 long startTime; 1738 int nesting; 1739 final ArrayMap<String, FilterStats> filterStats = new ArrayMap<String, FilterStats>(); 1740 BroadcastStats(int uid, String packageName)1741 BroadcastStats(int uid, String packageName) { 1742 mUid = uid; 1743 mPackageName = packageName; 1744 } 1745 1746 @Override toString()1747 public String toString() { 1748 return "BroadcastStats{" 1749 + "uid=" + mUid 1750 + ", packageName=" + mPackageName 1751 + ", aggregateTime=" + aggregateTime 1752 + ", count=" + count 1753 + ", numWakeup=" + numWakeup 1754 + ", startTime=" + startTime 1755 + ", nesting=" + nesting 1756 + "}"; 1757 } 1758 dumpDebug(ProtoOutputStream proto, long fieldId)1759 public void dumpDebug(ProtoOutputStream proto, long fieldId) { 1760 final long token = proto.start(fieldId); 1761 1762 proto.write(BroadcastStatsProto.UID, mUid); 1763 proto.write(BroadcastStatsProto.PACKAGE_NAME, mPackageName); 1764 proto.write(BroadcastStatsProto.TOTAL_FLIGHT_DURATION_MS, aggregateTime); 1765 proto.write(BroadcastStatsProto.COUNT, count); 1766 proto.write(BroadcastStatsProto.WAKEUP_COUNT, numWakeup); 1767 proto.write(BroadcastStatsProto.START_TIME_REALTIME, startTime); 1768 proto.write(BroadcastStatsProto.NESTING, nesting); 1769 1770 proto.end(token); 1771 } 1772 } 1773 1774 final SparseArray<ArrayMap<String, BroadcastStats>> mBroadcastStats 1775 = new SparseArray<ArrayMap<String, BroadcastStats>>(); 1776 1777 int mNumDelayedAlarms = 0; 1778 long mTotalDelayTime = 0; 1779 long mMaxDelayTime = 0; 1780 1781 @Override onStart()1782 public void onStart() { 1783 mInjector.init(); 1784 mHandler = new AlarmHandler(); 1785 1786 mOptsWithFgs.setPendingIntentBackgroundActivityLaunchAllowed(false); 1787 mOptsWithFgsForAlarmClock.setPendingIntentBackgroundActivityLaunchAllowed(false); 1788 mOptsWithoutFgs.setPendingIntentBackgroundActivityLaunchAllowed(false); 1789 mOptsTimeBroadcast.setPendingIntentBackgroundActivityLaunchAllowed(false); 1790 mActivityOptsRestrictBal.setPendingIntentBackgroundActivityLaunchAllowed(false); 1791 mBroadcastOptsRestrictBal.setPendingIntentBackgroundActivityLaunchAllowed(false); 1792 1793 mMetricsHelper = new MetricsHelper(getContext(), mLock); 1794 mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); 1795 1796 mUseFrozenStateToDropListenerAlarms = Flags.useFrozenStateToDropListenerAlarms(); 1797 mStartUserBeforeScheduledAlarms = Flags.startUserBeforeScheduledAlarms(); 1798 if (mStartUserBeforeScheduledAlarms) { 1799 mUserWakeupStore = new UserWakeupStore(); 1800 mUserWakeupStore.init(); 1801 } 1802 if (mUseFrozenStateToDropListenerAlarms) { 1803 final ActivityManager.UidFrozenStateChangedCallback callback = (uids, frozenStates) -> { 1804 final int size = frozenStates.length; 1805 if (uids.length != size) { 1806 Slog.wtf(TAG, "Got different length arrays in frozen state callback!" 1807 + " uids.length: " + uids.length + " frozenStates.length: " + size); 1808 // Cannot process received data in any meaningful way. 1809 return; 1810 } 1811 final IntArray affectedUids = new IntArray(); 1812 for (int i = 0; i < size; i++) { 1813 if (frozenStates[i] != UID_FROZEN_STATE_FROZEN) { 1814 continue; 1815 } 1816 if (!CompatChanges.isChangeEnabled(EXACT_LISTENER_ALARMS_DROPPED_ON_CACHED, 1817 uids[i])) { 1818 continue; 1819 } 1820 affectedUids.add(uids[i]); 1821 } 1822 if (affectedUids.size() > 0) { 1823 removeExactListenerAlarms(affectedUids.toArray()); 1824 } 1825 }; 1826 final ActivityManager am = getContext().getSystemService(ActivityManager.class); 1827 am.registerUidFrozenStateChangedCallback(new HandlerExecutor(mHandler), callback); 1828 } 1829 1830 mListenerDeathRecipient = new IBinder.DeathRecipient() { 1831 @Override 1832 public void binderDied() { 1833 } 1834 1835 @Override 1836 public void binderDied(IBinder who) { 1837 final IAlarmListener listener = IAlarmListener.Stub.asInterface(who); 1838 synchronized (mLock) { 1839 removeLocked(null, listener, REMOVE_REASON_LISTENER_BINDER_DIED); 1840 } 1841 } 1842 }; 1843 1844 synchronized (mLock) { 1845 mConstants = new Constants(mHandler); 1846 1847 mAlarmStore = new LazyAlarmStore(); 1848 mAlarmStore.setAlarmClockRemovalListener(mAlarmClockUpdater); 1849 1850 mAppWakeupHistory = new AppWakeupHistory(Constants.DEFAULT_APP_STANDBY_WINDOW); 1851 mAllowWhileIdleHistory = new AppWakeupHistory(INTERVAL_HOUR); 1852 mAllowWhileIdleCompatHistory = new AppWakeupHistory(INTERVAL_HOUR); 1853 1854 mTemporaryQuotaReserve = new TemporaryQuotaReserve(TEMPORARY_QUOTA_DURATION); 1855 1856 mNextWakeup = mNextNonWakeup = 0; 1857 1858 // Ensure that we're booting with a halfway sensible current time. 1859 mInjector.initializeTimeIfRequired(); 1860 1861 mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class); 1862 // Determine SysUI's uid 1863 mSystemUiUid = mInjector.getSystemUiUid(mPackageManagerInternal); 1864 if (mSystemUiUid <= 0) { 1865 Slog.wtf(TAG, "SysUI package not found!"); 1866 } 1867 mWakeLock = mInjector.getAlarmWakeLock(); 1868 1869 mTimeTickIntent = new Intent(Intent.ACTION_TIME_TICK).addFlags( 1870 Intent.FLAG_RECEIVER_REGISTERED_ONLY 1871 | Intent.FLAG_RECEIVER_FOREGROUND 1872 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); 1873 mTimeTickOptions = BroadcastOptions.makeBasic() 1874 .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT) 1875 .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE) 1876 .toBundle(); 1877 mTimeTickTrigger = new IAlarmListener.Stub() { 1878 @Override 1879 public void doAlarm(final IAlarmCompleteListener callback) throws RemoteException { 1880 if (DEBUG_BATCH) { 1881 Slog.v(TAG, "Received TIME_TICK alarm; rescheduling"); 1882 } 1883 1884 // Via handler because dispatch invokes this within its lock. OnAlarmListener 1885 // takes care of this automatically, but we're using the direct internal 1886 // interface here rather than that client-side wrapper infrastructure. 1887 mHandler.post(() -> { 1888 getContext().sendBroadcastAsUser(mTimeTickIntent, UserHandle.ALL, null, 1889 mTimeTickOptions); 1890 try { 1891 callback.alarmComplete(this); 1892 } catch (RemoteException e) { /* local method call */ } 1893 }); 1894 1895 synchronized (mLock) { 1896 mLastTickReceived = mInjector.getCurrentTimeMillis(); 1897 } 1898 mClockReceiver.scheduleTimeTickEvent(); 1899 } 1900 }; 1901 1902 Intent intent = new Intent(Intent.ACTION_DATE_CHANGED); 1903 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING 1904 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); 1905 mDateChangeSender = PendingIntent.getBroadcastAsUser(getContext(), 0, intent, 1906 Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT, UserHandle.ALL); 1907 1908 mClockReceiver = mInjector.getClockReceiver(this); 1909 new ChargingReceiver(); 1910 new InteractiveStateReceiver(); 1911 new UninstallReceiver(); 1912 1913 if (mInjector.isAlarmDriverPresent()) { 1914 AlarmThread waitThread = new AlarmThread(); 1915 waitThread.start(); 1916 } else { 1917 Slog.w(TAG, "Failed to open alarm driver. Falling back to a handler."); 1918 } 1919 } 1920 publishLocalService(AlarmManagerInternal.class, new LocalService()); 1921 publishBinderService(Context.ALARM_SERVICE, mService); 1922 } 1923 removeExactListenerAlarms(int... whichUids)1924 private void removeExactListenerAlarms(int... whichUids) { 1925 synchronized (mLock) { 1926 removeAlarmsInternalLocked(a -> { 1927 if (!ArrayUtils.contains(whichUids, a.uid) || a.listener == null 1928 || a.windowLength != 0) { 1929 return false; 1930 } 1931 Slog.w(TAG, "Alarm " + a.listenerTag + " being removed for " 1932 + UserHandle.formatUid(a.uid) + ":" + a.packageName 1933 + " because the app got frozen"); 1934 return true; 1935 }, REMOVE_REASON_LISTENER_CACHED); 1936 } 1937 } 1938 refreshExactAlarmCandidates()1939 void refreshExactAlarmCandidates() { 1940 final String[] candidates = mLocalPermissionManager.getAppOpPermissionPackages( 1941 Manifest.permission.SCHEDULE_EXACT_ALARM); 1942 final Set<Integer> newAppIds = new ArraySet<>(candidates.length); 1943 for (final String candidate : candidates) { 1944 final int uid = mPackageManagerInternal.getPackageUid(candidate, 1945 PackageManager.MATCH_ANY_USER, USER_SYSTEM); 1946 if (uid > 0) { 1947 newAppIds.add(UserHandle.getAppId(uid)); 1948 } 1949 } 1950 // Some packages may have lost permission to schedule exact alarms on update, their alarms 1951 // will be removed while handling CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE after this. 1952 1953 // No need to lock. Assignment is always atomic. 1954 mExactAlarmCandidates = Collections.unmodifiableSet(newAppIds); 1955 } 1956 1957 @Override onUserStarting(TargetUser user)1958 public void onUserStarting(TargetUser user) { 1959 super.onUserStarting(user); 1960 final int userId = user.getUserIdentifier(); 1961 if (mStartUserBeforeScheduledAlarms) { 1962 mUserWakeupStore.onUserStarting(userId); 1963 } 1964 mHandler.post(() -> { 1965 for (final int appId : mExactAlarmCandidates) { 1966 final int uid = UserHandle.getUid(userId, appId); 1967 final AndroidPackage androidPackage = mPackageManagerInternal.getPackage(uid); 1968 // It will be null if it is not installed on the starting user. 1969 if (androidPackage != null) { 1970 final int mode = mAppOps.checkOpNoThrow(AppOpsManager.OP_SCHEDULE_EXACT_ALARM, 1971 uid, androidPackage.getPackageName()); 1972 synchronized (mLock) { 1973 mLastOpScheduleExactAlarm.put(uid, mode); 1974 } 1975 } 1976 } 1977 }); 1978 } 1979 1980 @Override onBootPhase(int phase)1981 public void onBootPhase(int phase) { 1982 if (phase == PHASE_SYSTEM_SERVICES_READY) { 1983 synchronized (mLock) { 1984 mConstants.start(); 1985 1986 mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE); 1987 1988 mLocalDeviceIdleController = 1989 LocalServices.getService(DeviceIdleInternal.class); 1990 mUsageStatsManagerInternal = 1991 LocalServices.getService(UsageStatsManagerInternal.class); 1992 1993 mAppStateTracker = 1994 (AppStateTrackerImpl) LocalServices.getService(AppStateTracker.class); 1995 mAppStateTracker.addListener(mForceAppStandbyListener); 1996 1997 final BatteryManager bm = getContext().getSystemService(BatteryManager.class); 1998 mAppStandbyParole = bm.isCharging(); 1999 2000 mClockReceiver.scheduleTimeTickEvent(); 2001 mClockReceiver.scheduleDateChangedEvent(); 2002 } 2003 IAppOpsService iAppOpsService = mInjector.getAppOpsService(); 2004 try { 2005 iAppOpsService.startWatchingMode(AppOpsManager.OP_SCHEDULE_EXACT_ALARM, null, 2006 new IAppOpsCallback.Stub() { 2007 @Override 2008 public void opChanged(int op, int uid, String packageName, 2009 String persistentDeviceId) throws RemoteException { 2010 final int userId = UserHandle.getUserId(uid); 2011 if (op != AppOpsManager.OP_SCHEDULE_EXACT_ALARM 2012 || !isExactAlarmChangeEnabled(packageName, userId)) { 2013 return; 2014 } 2015 if (hasUseExactAlarmInternal(packageName, uid)) { 2016 return; 2017 } 2018 if (!mExactAlarmCandidates.contains(UserHandle.getAppId(uid))) { 2019 // Permission not requested, app op doesn't matter. 2020 return; 2021 } 2022 2023 final int newMode = mAppOps.checkOpNoThrow( 2024 AppOpsManager.OP_SCHEDULE_EXACT_ALARM, uid, packageName); 2025 2026 final int oldMode; 2027 synchronized (mLock) { 2028 final int index = mLastOpScheduleExactAlarm.indexOfKey(uid); 2029 if (index < 0) { 2030 oldMode = AppOpsManager.opToDefaultMode( 2031 AppOpsManager.OP_SCHEDULE_EXACT_ALARM); 2032 mLastOpScheduleExactAlarm.put(uid, newMode); 2033 } else { 2034 oldMode = mLastOpScheduleExactAlarm.valueAt(index); 2035 mLastOpScheduleExactAlarm.setValueAt(index, newMode); 2036 } 2037 } 2038 if (oldMode == newMode) { 2039 return; 2040 } 2041 final boolean deniedByDefault = isScheduleExactAlarmDeniedByDefault( 2042 packageName, UserHandle.getUserId(uid)); 2043 2044 final boolean hadPermission; 2045 final boolean hasPermission; 2046 2047 if (deniedByDefault) { 2048 final boolean permissionState = getContext().checkPermission( 2049 Manifest.permission.SCHEDULE_EXACT_ALARM, PID_UNKNOWN, 2050 uid) == PackageManager.PERMISSION_GRANTED; 2051 hadPermission = (oldMode == AppOpsManager.MODE_DEFAULT) 2052 ? permissionState 2053 : (oldMode == AppOpsManager.MODE_ALLOWED); 2054 hasPermission = (newMode == AppOpsManager.MODE_DEFAULT) 2055 ? permissionState 2056 : (newMode == AppOpsManager.MODE_ALLOWED); 2057 } else { 2058 hadPermission = (oldMode == AppOpsManager.MODE_DEFAULT) 2059 || (oldMode == AppOpsManager.MODE_ALLOWED); 2060 hasPermission = (newMode == AppOpsManager.MODE_DEFAULT) 2061 || (newMode == AppOpsManager.MODE_ALLOWED); 2062 } 2063 2064 if (hadPermission && !hasPermission) { 2065 mHandler.obtainMessage(AlarmHandler.REMOVE_EXACT_ALARMS, 2066 uid, 0, packageName).sendToTarget(); 2067 } else if (!hadPermission && hasPermission) { 2068 sendScheduleExactAlarmPermissionStateChangedBroadcast( 2069 packageName, userId); 2070 } 2071 } 2072 }); 2073 } catch (RemoteException e) { 2074 } 2075 2076 mLocalPermissionManager = LocalServices.getService( 2077 PermissionManagerServiceInternal.class); 2078 refreshExactAlarmCandidates(); 2079 2080 AppStandbyInternal appStandbyInternal = 2081 LocalServices.getService(AppStandbyInternal.class); 2082 appStandbyInternal.addListener(new AppStandbyTracker()); 2083 2084 mBatteryStatsInternal = LocalServices.getService(BatteryStatsInternal.class); 2085 2086 mRoleManager = getContext().getSystemService(RoleManager.class); 2087 2088 mMetricsHelper.registerPuller(() -> mAlarmStore); 2089 } 2090 } 2091 2092 @Override finalize()2093 protected void finalize() throws Throwable { 2094 try { 2095 mInjector.close(); 2096 } finally { 2097 super.finalize(); 2098 } 2099 } 2100 setTimeImpl( @urrentTimeMillisLong long newSystemClockTimeMillis, @TimeConfidence int confidence, @NonNull String logMsg)2101 boolean setTimeImpl( 2102 @CurrentTimeMillisLong long newSystemClockTimeMillis, @TimeConfidence int confidence, 2103 @NonNull String logMsg) { 2104 synchronized (mLock) { 2105 mInjector.setCurrentTimeMillis(newSystemClockTimeMillis, confidence, logMsg); 2106 2107 // The native implementation of setKernelTime can return -1 even when the kernel 2108 // time was set correctly, so assume setting kernel time was successful and always 2109 // return true. 2110 return true; 2111 } 2112 } 2113 setTimeZoneImpl(String tzId, @TimeZoneConfidence int confidence, String logInfo)2114 void setTimeZoneImpl(String tzId, @TimeZoneConfidence int confidence, String logInfo) { 2115 if (TextUtils.isEmpty(tzId)) { 2116 return; 2117 } 2118 2119 TimeZone newZone = TimeZone.getTimeZone(tzId); 2120 // Prevent reentrant calls from stepping on each other when writing 2121 // the time zone property 2122 boolean timeZoneWasChanged; 2123 synchronized (this) { 2124 // TimeZone.getTimeZone() can return a time zone with a different ID (e.g. it can return 2125 // "GMT" if the ID is unrecognized). The parameter ID is used here rather than 2126 // newZone.getId(). It will be rejected if it is invalid. 2127 timeZoneWasChanged = SystemTimeZone.setTimeZoneId(tzId, confidence, logInfo); 2128 2129 final int gmtOffset = newZone.getOffset(mInjector.getCurrentTimeMillis()); 2130 SystemProperties.set(TIMEOFFSET_PROPERTY, String.valueOf(gmtOffset)); 2131 2132 final ZoneRules rules = newZone.toZoneId().getRules(); 2133 final ZoneOffsetTransition transition = rules.nextTransition(Instant.now()); 2134 if (null != transition) { 2135 // Get the offset between the time after the DST transition and before. 2136 final long transitionOffset = TimeUnit.SECONDS.toMillis(( 2137 transition.getOffsetAfter().getTotalSeconds() 2138 - transition.getOffsetBefore().getTotalSeconds())); 2139 // Time when the next DST transition is programmed. 2140 final long nextTransition = TimeUnit.SECONDS.toMillis(transition.toEpochSecond()); 2141 SystemProperties.set(DST_TRANSITION_PROPERTY, String.valueOf(nextTransition)); 2142 SystemProperties.set(DST_OFFSET_PROPERTY, String.valueOf(transitionOffset)); 2143 } 2144 } 2145 2146 // Clear the default time zone in the system server process. This forces the next call 2147 // to TimeZone.getDefault() to re-read the device settings. 2148 TimeZone.setDefault(null); 2149 2150 if (timeZoneWasChanged) { 2151 // Don't wait for broadcasts to update our midnight alarm 2152 mClockReceiver.scheduleDateChangedEvent(); 2153 2154 // And now let everyone else know 2155 Intent intent = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 2156 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING 2157 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND 2158 | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT 2159 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); 2160 intent.putExtra(Intent.EXTRA_TIMEZONE, newZone.getID()); 2161 mOptsTimeBroadcast.setTemporaryAppAllowlist( 2162 mActivityManagerInternal.getBootTimeTempAllowListDuration(), 2163 TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED, 2164 PowerExemptionManager.REASON_TIMEZONE_CHANGED, ""); 2165 mOptsTimeBroadcast.setDeliveryGroupPolicy( 2166 BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT); 2167 getContext().sendBroadcastAsUser(intent, UserHandle.ALL, 2168 null /* receiverPermission */, mOptsTimeBroadcast.toBundle()); 2169 } 2170 } 2171 removeImpl(PendingIntent operation, IAlarmListener listener)2172 void removeImpl(PendingIntent operation, IAlarmListener listener) { 2173 synchronized (mLock) { 2174 removeLocked(operation, listener, REMOVE_REASON_UNDEFINED); 2175 } 2176 } 2177 setImpl(int type, long triggerAtTime, long windowLength, long interval, PendingIntent operation, IAlarmListener directReceiver, String listenerTag, int flags, WorkSource workSource, AlarmManager.AlarmClockInfo alarmClock, int callingUid, String callingPackage, Bundle idleOptions, int exactAllowReason)2178 void setImpl(int type, long triggerAtTime, long windowLength, long interval, 2179 PendingIntent operation, IAlarmListener directReceiver, String listenerTag, 2180 int flags, WorkSource workSource, AlarmManager.AlarmClockInfo alarmClock, 2181 int callingUid, String callingPackage, Bundle idleOptions, int exactAllowReason) { 2182 if ((operation == null && directReceiver == null) 2183 || (operation != null && directReceiver != null)) { 2184 Slog.w(TAG, "Alarms must either supply a PendingIntent or an AlarmReceiver"); 2185 // NB: previous releases failed silently here, so we are continuing to do the same 2186 // rather than throw an IllegalArgumentException. 2187 return; 2188 } 2189 2190 if (directReceiver != null) { 2191 try { 2192 directReceiver.asBinder().linkToDeath(mListenerDeathRecipient, 0); 2193 } catch (RemoteException e) { 2194 Slog.w(TAG, "Dropping unreachable alarm listener " + listenerTag); 2195 return; 2196 } 2197 } 2198 2199 // Validate the recurrence interval. This will catch people who supply 2200 // seconds when the API expects milliseconds, or apps trying shenanigans 2201 // around intentional period overflow, etc. 2202 final long minInterval = mConstants.MIN_INTERVAL; 2203 if (interval > 0 && interval < minInterval) { 2204 Slog.w(TAG, "Suspiciously short interval " + interval 2205 + " millis; expanding to " + (minInterval / 1000) 2206 + " seconds"); 2207 interval = minInterval; 2208 } else if (interval > mConstants.MAX_INTERVAL) { 2209 Slog.w(TAG, "Suspiciously long interval " + interval 2210 + " millis; clamping"); 2211 interval = mConstants.MAX_INTERVAL; 2212 } 2213 2214 if (type < RTC_WAKEUP || type > ELAPSED_REALTIME) { 2215 throw new IllegalArgumentException("Invalid alarm type " + type); 2216 } 2217 2218 if (triggerAtTime < 0) { 2219 final long what = Binder.getCallingPid(); 2220 Slog.w(TAG, "Invalid alarm trigger time! " + triggerAtTime + " from uid=" + callingUid 2221 + " pid=" + what); 2222 triggerAtTime = 0; 2223 } 2224 2225 final long nowElapsed = mInjector.getElapsedRealtimeMillis(); 2226 final long nominalTrigger = convertToElapsed(triggerAtTime, type); 2227 // Try to prevent spamming by making sure apps aren't firing alarms in the immediate future 2228 final long minTrigger = nowElapsed 2229 + (UserHandle.isCore(callingUid) ? 0L : mConstants.MIN_FUTURITY); 2230 final long triggerElapsed = Math.max(minTrigger, nominalTrigger); 2231 2232 final long maxElapsed; 2233 if (windowLength == 0) { 2234 maxElapsed = triggerElapsed; 2235 } else if (windowLength < 0) { 2236 maxElapsed = maxTriggerTime(nowElapsed, triggerElapsed, interval); 2237 // Fix this window in place, so that as time approaches we don't collapse it. 2238 windowLength = maxElapsed - triggerElapsed; 2239 } else { 2240 // The window was explicitly requested. Snap it to allowable limits. 2241 final long minAllowedWindow = getMinimumAllowedWindow(nowElapsed, triggerElapsed); 2242 if (windowLength > INTERVAL_DAY) { 2243 Slog.w(TAG, "Window length " + windowLength + "ms too long; limiting to 1 day"); 2244 windowLength = INTERVAL_DAY; 2245 } else if ((flags & FLAG_PRIORITIZE) == 0 && windowLength < minAllowedWindow) { 2246 // Prioritized alarms are exempt from minimum window limits. 2247 if (!isExemptFromMinWindowRestrictions(callingUid) && CompatChanges.isChangeEnabled( 2248 AlarmManager.ENFORCE_MINIMUM_WINDOW_ON_INEXACT_ALARMS, callingPackage, 2249 UserHandle.getUserHandleForUid(callingUid))) { 2250 Slog.w(TAG, "Window length " + windowLength + "ms too short; expanding to " 2251 + minAllowedWindow + "ms."); 2252 windowLength = minAllowedWindow; 2253 } 2254 } 2255 maxElapsed = triggerElapsed + windowLength; 2256 } 2257 synchronized (mLock) { 2258 if (DEBUG_BATCH) { 2259 Slog.v(TAG, "set(" + operation + ") : type=" + type 2260 + " triggerAtTime=" + triggerAtTime + " win=" + windowLength 2261 + " tElapsed=" + triggerElapsed + " maxElapsed=" + maxElapsed 2262 + " interval=" + interval + " flags=0x" + Integer.toHexString(flags)); 2263 } 2264 if (mAlarmsPerUid.get(callingUid, 0) >= mConstants.MAX_ALARMS_PER_UID) { 2265 final String errorMsg = 2266 "Maximum limit of concurrent alarms " + mConstants.MAX_ALARMS_PER_UID 2267 + " reached for uid: " + UserHandle.formatUid(callingUid) 2268 + ", callingPackage: " + callingPackage; 2269 Slog.w(TAG, errorMsg); 2270 if (callingUid != Process.SYSTEM_UID) { 2271 throw new IllegalStateException(errorMsg); 2272 } else { 2273 EventLog.writeEvent(0x534e4554, "234441463", -1, errorMsg); 2274 } 2275 } 2276 setImplLocked(type, triggerAtTime, triggerElapsed, windowLength, interval, operation, 2277 directReceiver, listenerTag, flags, workSource, alarmClock, callingUid, 2278 callingPackage, idleOptions, exactAllowReason); 2279 } 2280 } 2281 2282 @GuardedBy("mLock") setImplLocked(int type, long when, long whenElapsed, long windowLength, long interval, PendingIntent operation, IAlarmListener directReceiver, String listenerTag, int flags, WorkSource workSource, AlarmManager.AlarmClockInfo alarmClock, int callingUid, String callingPackage, Bundle idleOptions, int exactAllowReason)2283 private void setImplLocked(int type, long when, long whenElapsed, long windowLength, 2284 long interval, PendingIntent operation, IAlarmListener directReceiver, 2285 String listenerTag, int flags, WorkSource workSource, 2286 AlarmManager.AlarmClockInfo alarmClock, int callingUid, String callingPackage, 2287 Bundle idleOptions, int exactAllowReason) { 2288 final Alarm a = new Alarm(type, when, whenElapsed, windowLength, interval, 2289 operation, directReceiver, listenerTag, workSource, flags, alarmClock, 2290 callingUid, callingPackage, idleOptions, exactAllowReason); 2291 if (mActivityManagerInternal.isAppStartModeDisabled(callingUid, callingPackage)) { 2292 Slog.w(TAG, "Not setting alarm from " + callingUid + ":" + a 2293 + " -- package not allowed to start"); 2294 return; 2295 } 2296 final int callerProcState = mActivityManagerInternal.getUidProcessState(callingUid); 2297 removeLocked(operation, directReceiver, REMOVE_REASON_UNDEFINED); 2298 incrementAlarmCount(a.uid); 2299 setImplLocked(a); 2300 MetricsHelper.pushAlarmScheduled(a, callerProcState); 2301 } 2302 2303 /** 2304 * Returns the maximum alarms that an app in the specified bucket can receive in a rolling time 2305 * window given by {@link Constants#APP_STANDBY_WINDOW} 2306 */ 2307 @VisibleForTesting getQuotaForBucketLocked(int bucket)2308 int getQuotaForBucketLocked(int bucket) { 2309 final int index; 2310 if (bucket <= UsageStatsManager.STANDBY_BUCKET_ACTIVE) { 2311 index = ACTIVE_INDEX; 2312 } else if (bucket <= UsageStatsManager.STANDBY_BUCKET_WORKING_SET) { 2313 index = WORKING_INDEX; 2314 } else if (bucket <= UsageStatsManager.STANDBY_BUCKET_FREQUENT) { 2315 index = FREQUENT_INDEX; 2316 } else if (bucket < UsageStatsManager.STANDBY_BUCKET_NEVER) { 2317 index = RARE_INDEX; 2318 } else { 2319 index = NEVER_INDEX; 2320 } 2321 return mConstants.APP_STANDBY_QUOTAS[index]; 2322 } 2323 2324 /** 2325 * An alarm with {@link AlarmManager#FLAG_IDLE_UNTIL} is a special alarm that will put the 2326 * system into idle until it goes off. We need to pull it earlier if there are existing alarms 2327 * that have requested to bring us out of idle at an earlier time. 2328 * 2329 * @param alarm The alarm to adjust 2330 * @return true if the alarm delivery time was updated. 2331 */ adjustIdleUntilTime(Alarm alarm)2332 private boolean adjustIdleUntilTime(Alarm alarm) { 2333 if ((alarm.flags & AlarmManager.FLAG_IDLE_UNTIL) == 0) { 2334 return false; 2335 } 2336 final boolean changedBeforeFuzz = restoreRequestedTime(alarm); 2337 if (mNextWakeFromIdle == null) { 2338 // No need to change anything in the absence of a wake-from-idle request. 2339 return changedBeforeFuzz; 2340 } 2341 final long upcomingWakeFromIdle = mNextWakeFromIdle.getWhenElapsed(); 2342 // Add fuzz to make the alarm go off some time before the next upcoming wake-from-idle, as 2343 // these alarms are usually wall-clock aligned. 2344 if (alarm.getWhenElapsed() < (upcomingWakeFromIdle - mConstants.MIN_DEVICE_IDLE_FUZZ)) { 2345 // No need to fuzz as this is already earlier than the coming wake-from-idle. 2346 return changedBeforeFuzz; 2347 } 2348 final long nowElapsed = mInjector.getElapsedRealtimeMillis(); 2349 final long futurity = upcomingWakeFromIdle - nowElapsed; 2350 2351 if (futurity <= mConstants.MIN_DEVICE_IDLE_FUZZ) { 2352 // No point in fuzzing as the minimum fuzz will take the time in the past. 2353 alarm.setPolicyElapsed(REQUESTER_POLICY_INDEX, nowElapsed); 2354 } else { 2355 final ThreadLocalRandom random = ThreadLocalRandom.current(); 2356 final long upperBoundExcl = Math.min(mConstants.MAX_DEVICE_IDLE_FUZZ, futurity) + 1; 2357 final long fuzz = random.nextLong(mConstants.MIN_DEVICE_IDLE_FUZZ, upperBoundExcl); 2358 alarm.setPolicyElapsed(REQUESTER_POLICY_INDEX, upcomingWakeFromIdle - fuzz); 2359 } 2360 return true; 2361 } 2362 2363 /** 2364 * Adjusts the delivery time of the alarm based on battery saver rules. 2365 * 2366 * @param alarm The alarm to adjust 2367 * @return {@code true} if the alarm delivery time was updated. 2368 */ adjustDeliveryTimeBasedOnBatterySaver(Alarm alarm)2369 private boolean adjustDeliveryTimeBasedOnBatterySaver(Alarm alarm) { 2370 final long nowElapsed = mInjector.getElapsedRealtimeMillis(); 2371 if (isExemptFromBatterySaver(alarm)) { 2372 return false; 2373 } 2374 2375 if (mAppStateTracker == null || !mAppStateTracker.areAlarmsRestrictedByBatterySaver( 2376 alarm.creatorUid, alarm.sourcePackage)) { 2377 return alarm.setPolicyElapsed(BATTERY_SAVER_POLICY_INDEX, nowElapsed); 2378 } 2379 2380 final long batterySaverPolicyElapsed; 2381 if ((alarm.flags & (FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED)) != 0) { 2382 // Unrestricted. 2383 batterySaverPolicyElapsed = nowElapsed; 2384 } else if (isAllowedWhileIdleRestricted(alarm)) { 2385 // Allowed but limited. 2386 final int userId = UserHandle.getUserId(alarm.creatorUid); 2387 final int quota; 2388 final long window; 2389 final AppWakeupHistory history; 2390 if ((alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0) { 2391 quota = mConstants.ALLOW_WHILE_IDLE_QUOTA; 2392 window = mConstants.ALLOW_WHILE_IDLE_WINDOW; 2393 history = mAllowWhileIdleHistory; 2394 } else { 2395 quota = mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA; 2396 window = mConstants.ALLOW_WHILE_IDLE_COMPAT_WINDOW; 2397 history = mAllowWhileIdleCompatHistory; 2398 } 2399 final int dispatchesInHistory = history.getTotalWakeupsInWindow( 2400 alarm.sourcePackage, userId); 2401 if (dispatchesInHistory < quota) { 2402 // fine to go out immediately. 2403 batterySaverPolicyElapsed = nowElapsed; 2404 } else { 2405 batterySaverPolicyElapsed = history.getNthLastWakeupForPackage( 2406 alarm.sourcePackage, userId, quota) + window; 2407 } 2408 } else if ((alarm.flags & FLAG_PRIORITIZE) != 0) { 2409 final long lastDispatch = mLastPriorityAlarmDispatch.get(alarm.creatorUid, 0); 2410 batterySaverPolicyElapsed = (lastDispatch == 0) 2411 ? nowElapsed 2412 : lastDispatch + mConstants.PRIORITY_ALARM_DELAY; 2413 } else { 2414 // Not allowed. 2415 batterySaverPolicyElapsed = nowElapsed + INDEFINITE_DELAY; 2416 } 2417 return alarm.setPolicyElapsed(BATTERY_SAVER_POLICY_INDEX, batterySaverPolicyElapsed); 2418 } 2419 2420 /** 2421 * Returns {@code true} if the given alarm has the flag 2422 * {@link AlarmManager#FLAG_ALLOW_WHILE_IDLE} or 2423 * {@link AlarmManager#FLAG_ALLOW_WHILE_IDLE_COMPAT} 2424 * 2425 */ isAllowedWhileIdleRestricted(Alarm a)2426 private static boolean isAllowedWhileIdleRestricted(Alarm a) { 2427 return (a.flags & (FLAG_ALLOW_WHILE_IDLE | FLAG_ALLOW_WHILE_IDLE_COMPAT)) != 0; 2428 } 2429 2430 /** 2431 * Adjusts the delivery time of the alarm based on device_idle (doze) rules. 2432 * 2433 * @param alarm The alarm to adjust 2434 * @return {@code true} if the alarm delivery time was updated. 2435 */ adjustDeliveryTimeBasedOnDeviceIdle(Alarm alarm)2436 private boolean adjustDeliveryTimeBasedOnDeviceIdle(Alarm alarm) { 2437 final long nowElapsed = mInjector.getElapsedRealtimeMillis(); 2438 if (mPendingIdleUntil == null || mPendingIdleUntil == alarm) { 2439 return alarm.setPolicyElapsed(DEVICE_IDLE_POLICY_INDEX, nowElapsed); 2440 } 2441 2442 final long deviceIdlePolicyTime; 2443 if ((alarm.flags & (FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED | FLAG_WAKE_FROM_IDLE)) != 0) { 2444 // Unrestricted. 2445 deviceIdlePolicyTime = nowElapsed; 2446 } else if (isAllowedWhileIdleRestricted(alarm)) { 2447 // Allowed but limited. 2448 final int userId = UserHandle.getUserId(alarm.creatorUid); 2449 final int quota; 2450 final long window; 2451 final AppWakeupHistory history; 2452 if ((alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0) { 2453 quota = mConstants.ALLOW_WHILE_IDLE_QUOTA; 2454 window = mConstants.ALLOW_WHILE_IDLE_WINDOW; 2455 history = mAllowWhileIdleHistory; 2456 } else { 2457 quota = mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA; 2458 window = mConstants.ALLOW_WHILE_IDLE_COMPAT_WINDOW; 2459 history = mAllowWhileIdleCompatHistory; 2460 } 2461 final int dispatchesInHistory = history.getTotalWakeupsInWindow( 2462 alarm.sourcePackage, userId); 2463 if (dispatchesInHistory < quota) { 2464 // fine to go out immediately. 2465 deviceIdlePolicyTime = nowElapsed; 2466 } else { 2467 final long whenInQuota = history.getNthLastWakeupForPackage( 2468 alarm.sourcePackage, userId, quota) + window; 2469 deviceIdlePolicyTime = Math.min(whenInQuota, mPendingIdleUntil.getWhenElapsed()); 2470 } 2471 } else if ((alarm.flags & FLAG_PRIORITIZE) != 0) { 2472 final long lastDispatch = mLastPriorityAlarmDispatch.get(alarm.creatorUid, 0); 2473 final long whenAllowed = (lastDispatch == 0) 2474 ? nowElapsed 2475 : lastDispatch + mConstants.PRIORITY_ALARM_DELAY; 2476 deviceIdlePolicyTime = Math.min(whenAllowed, mPendingIdleUntil.getWhenElapsed()); 2477 } else { 2478 // Not allowed. 2479 deviceIdlePolicyTime = mPendingIdleUntil.getWhenElapsed(); 2480 } 2481 return alarm.setPolicyElapsed(DEVICE_IDLE_POLICY_INDEX, deviceIdlePolicyTime); 2482 } 2483 2484 /** 2485 * Adjusts the alarm's policy time for app_standby. 2486 * 2487 * @param alarm The alarm to update. 2488 * @return {@code true} if the actual delivery time of the given alarm was updated due to 2489 * adjustments made in this call. 2490 */ adjustDeliveryTimeBasedOnBucketLocked(Alarm alarm)2491 private boolean adjustDeliveryTimeBasedOnBucketLocked(Alarm alarm) { 2492 final long nowElapsed = mInjector.getElapsedRealtimeMillis(); 2493 if (isExemptFromAppStandby(alarm) || mAppStandbyParole) { 2494 return alarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, nowElapsed); 2495 } 2496 2497 final String sourcePackage = alarm.sourcePackage; 2498 final int sourceUserId = UserHandle.getUserId(alarm.creatorUid); 2499 final int standbyBucket = mUsageStatsManagerInternal.getAppStandbyBucket( 2500 sourcePackage, sourceUserId, nowElapsed); 2501 2502 final int wakeupsInWindow = mAppWakeupHistory.getTotalWakeupsInWindow(sourcePackage, 2503 sourceUserId); 2504 if (standbyBucket == UsageStatsManager.STANDBY_BUCKET_RESTRICTED) { 2505 // Special case because it's 1/day instead of 1/hour. 2506 // AppWakeupHistory doesn't delete old wakeup times until a new one is logged, so we 2507 // should always have the last wakeup available. 2508 if (wakeupsInWindow > 0) { 2509 final long lastWakeupTime = mAppWakeupHistory.getNthLastWakeupForPackage( 2510 sourcePackage, sourceUserId, mConstants.APP_STANDBY_RESTRICTED_QUOTA); 2511 if ((nowElapsed - lastWakeupTime) < mConstants.APP_STANDBY_RESTRICTED_WINDOW) { 2512 return alarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, 2513 lastWakeupTime + mConstants.APP_STANDBY_RESTRICTED_WINDOW); 2514 } 2515 } 2516 } else { 2517 final int quotaForBucket = getQuotaForBucketLocked(standbyBucket); 2518 if (wakeupsInWindow >= quotaForBucket) { 2519 final long minElapsed; 2520 if (mTemporaryQuotaReserve.hasQuota(sourcePackage, sourceUserId, nowElapsed)) { 2521 // We will let this alarm go out as usual, but mark it so it consumes the quota 2522 // at the time of delivery. 2523 alarm.mUsingReserveQuota = true; 2524 return alarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, nowElapsed); 2525 } 2526 if (quotaForBucket <= 0) { 2527 // Just keep deferring indefinitely till the quota changes. 2528 minElapsed = nowElapsed + INDEFINITE_DELAY; 2529 } else { 2530 // Suppose the quota for window was q, and the qth last delivery time for this 2531 // package was t(q) then the next delivery must be after t(q) + <window_size>. 2532 final long t = mAppWakeupHistory.getNthLastWakeupForPackage( 2533 sourcePackage, sourceUserId, quotaForBucket); 2534 minElapsed = t + mConstants.APP_STANDBY_WINDOW; 2535 } 2536 return alarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, minElapsed); 2537 } 2538 } 2539 // wakeupsInWindow are less than the permitted quota, hence no deferring is needed. 2540 alarm.mUsingReserveQuota = false; 2541 return alarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, nowElapsed); 2542 } 2543 2544 @GuardedBy("mLock") setImplLocked(Alarm a)2545 private void setImplLocked(Alarm a) { 2546 if ((a.flags & AlarmManager.FLAG_IDLE_UNTIL) != 0) { 2547 adjustIdleUntilTime(a); 2548 2549 if (RECORD_DEVICE_IDLE_ALARMS) { 2550 IdleDispatchEntry ent = new IdleDispatchEntry(); 2551 ent.uid = a.uid; 2552 ent.pkg = a.sourcePackage; 2553 ent.tag = a.statsTag; 2554 ent.op = "START IDLE"; 2555 ent.elapsedRealtime = mInjector.getElapsedRealtimeMillis(); 2556 ent.argRealtime = a.getWhenElapsed(); 2557 mAllowWhileIdleDispatches.add(ent); 2558 } 2559 if ((mPendingIdleUntil != a) && (mPendingIdleUntil != null)) { 2560 Slog.wtfStack(TAG, "setImplLocked: idle until changed from " + mPendingIdleUntil 2561 + " to " + a); 2562 mAlarmStore.remove(mPendingIdleUntil::equals); 2563 } 2564 mPendingIdleUntil = a; 2565 mAlarmStore.updateAlarmDeliveries(alarm -> adjustDeliveryTimeBasedOnDeviceIdle(alarm)); 2566 } else if (mPendingIdleUntil != null) { 2567 adjustDeliveryTimeBasedOnDeviceIdle(a); 2568 } 2569 if ((a.flags & FLAG_WAKE_FROM_IDLE) != 0) { 2570 if (mNextWakeFromIdle == null || mNextWakeFromIdle.getWhenElapsed() 2571 > a.getWhenElapsed()) { 2572 mNextWakeFromIdle = a; 2573 // If this wake from idle is earlier than whatever was previously scheduled, 2574 // and we are currently idling, then the idle-until time needs to be updated. 2575 if (mPendingIdleUntil != null) { 2576 final boolean updated = mAlarmStore.updateAlarmDeliveries( 2577 alarm -> (alarm == mPendingIdleUntil) && adjustIdleUntilTime(alarm)); 2578 if (updated) { 2579 // idle-until got updated, so also update all alarms not allowed while idle. 2580 mAlarmStore.updateAlarmDeliveries( 2581 alarm -> adjustDeliveryTimeBasedOnDeviceIdle(alarm)); 2582 } 2583 } 2584 } 2585 } 2586 if (a.alarmClock != null) { 2587 mNextAlarmClockMayChange = true; 2588 } 2589 adjustDeliveryTimeBasedOnBatterySaver(a); 2590 adjustDeliveryTimeBasedOnBucketLocked(a); 2591 mAlarmStore.add(a); 2592 rescheduleKernelAlarmsLocked(); 2593 updateNextAlarmClockLocked(); 2594 } 2595 2596 /** 2597 * System-process internal API 2598 */ 2599 private final class LocalService implements AlarmManagerInternal { 2600 @Override isIdling()2601 public boolean isIdling() { 2602 return isIdlingImpl(); 2603 } 2604 2605 @Override removeAlarmsForUid(int uid)2606 public void removeAlarmsForUid(int uid) { 2607 synchronized (mLock) { 2608 removeLocked(uid, REMOVE_REASON_DATA_CLEARED); 2609 } 2610 } 2611 2612 @Override remove(PendingIntent pi)2613 public void remove(PendingIntent pi) { 2614 mHandler.obtainMessage(AlarmHandler.REMOVE_FOR_CANCELED, pi).sendToTarget(); 2615 } 2616 2617 @Override shouldGetBucketElevation(String packageName, int uid)2618 public boolean shouldGetBucketElevation(String packageName, int uid) { 2619 return hasUseExactAlarmInternal(packageName, uid) || (!CompatChanges.isChangeEnabled( 2620 AlarmManager.SCHEDULE_EXACT_ALARM_DOES_NOT_ELEVATE_BUCKET, packageName, 2621 UserHandle.getUserHandleForUid(uid)) && hasScheduleExactAlarmInternal( 2622 packageName, uid)); 2623 } 2624 2625 @Override setTimeZone(String tzId, @TimeZoneConfidence int confidence, String logInfo)2626 public void setTimeZone(String tzId, @TimeZoneConfidence int confidence, 2627 String logInfo) { 2628 setTimeZoneImpl(tzId, confidence, logInfo); 2629 } 2630 2631 @Override setTime( @urrentTimeMillisLong long unixEpochTimeMillis, int confidence, String logMsg)2632 public void setTime( 2633 @CurrentTimeMillisLong long unixEpochTimeMillis, int confidence, 2634 String logMsg) { 2635 setTimeImpl(unixEpochTimeMillis, confidence, logMsg); 2636 } 2637 2638 @Override registerInFlightListener(InFlightListener callback)2639 public void registerInFlightListener(InFlightListener callback) { 2640 synchronized (mLock) { 2641 mInFlightListeners.add(callback); 2642 } 2643 } 2644 } 2645 hasUseExactAlarmInternal(String packageName, int uid)2646 boolean hasUseExactAlarmInternal(String packageName, int uid) { 2647 return isUseExactAlarmEnabled(packageName, UserHandle.getUserId(uid)) 2648 && (checkPermissionForPreflight(getContext(), Manifest.permission.USE_EXACT_ALARM, 2649 PID_UNKNOWN, uid, packageName) == PERMISSION_GRANTED); 2650 } 2651 hasScheduleExactAlarmInternal(String packageName, int uid)2652 boolean hasScheduleExactAlarmInternal(String packageName, int uid) { 2653 final long start = mStatLogger.getTime(); 2654 2655 // Not using #mLastOpScheduleExactAlarm as it may contain stale values. 2656 // No locking needed as all internal containers being queried are immutable. 2657 final boolean hasPermission; 2658 if (!mExactAlarmCandidates.contains(UserHandle.getAppId(uid))) { 2659 hasPermission = false; 2660 } else if (!isExactAlarmChangeEnabled(packageName, UserHandle.getUserId(uid))) { 2661 hasPermission = false; 2662 } else if (isScheduleExactAlarmDeniedByDefault(packageName, UserHandle.getUserId(uid))) { 2663 hasPermission = (checkPermissionForPreflight(getContext(), 2664 Manifest.permission.SCHEDULE_EXACT_ALARM, PID_UNKNOWN, uid, packageName) 2665 == PERMISSION_GRANTED); 2666 } else { 2667 // Compatibility permission check for older apps. 2668 final int mode = mAppOps.checkOpNoThrow(AppOpsManager.OP_SCHEDULE_EXACT_ALARM, uid, 2669 packageName); 2670 hasPermission = (mode == AppOpsManager.MODE_DEFAULT) 2671 || (mode == AppOpsManager.MODE_ALLOWED); 2672 } 2673 mStatLogger.logDurationStat(Stats.HAS_SCHEDULE_EXACT_ALARM, start); 2674 return hasPermission; 2675 } 2676 2677 /** 2678 * Returns true if the given uid can set window to be as small as it wants. 2679 */ isExemptFromMinWindowRestrictions(int uid)2680 boolean isExemptFromMinWindowRestrictions(int uid) { 2681 return isExemptFromExactAlarmPermissionNoLock(uid); 2682 } 2683 2684 /** 2685 * Returns true if the given uid does not require SCHEDULE_EXACT_ALARM to set exact, 2686 * allow-while-idle alarms. 2687 * <b> Note: This should not be called with {@link #mLock} held.</b> 2688 */ isExemptFromExactAlarmPermissionNoLock(int uid)2689 boolean isExemptFromExactAlarmPermissionNoLock(int uid) { 2690 if (Build.IS_DEBUGGABLE && Thread.holdsLock(mLock)) { 2691 Slog.wtfStack(TAG, "Alarm lock held while calling into DeviceIdleController"); 2692 } 2693 return (UserHandle.isSameApp(mSystemUiUid, uid) 2694 || UserHandle.isCore(uid) 2695 || mLocalDeviceIdleController == null 2696 || mLocalDeviceIdleController.isAppOnWhitelist(UserHandle.getAppId(uid))); 2697 } 2698 2699 /** 2700 * Public-facing binder interface 2701 */ 2702 private final IBinder mService = new IAlarmManager.Stub() { 2703 @Override 2704 public void set(String callingPackage, 2705 int type, long triggerAtTime, long windowLength, long interval, int flags, 2706 PendingIntent operation, IAlarmListener directReceiver, String listenerTag, 2707 WorkSource workSource, AlarmManager.AlarmClockInfo alarmClock) { 2708 final int callingUid = mInjector.getCallingUid(); 2709 final int callingUserId = UserHandle.getUserId(callingUid); 2710 2711 // make sure the caller is not lying about which package should be blamed for 2712 // wakelock time spent in alarm delivery 2713 if (callingUid != mPackageManagerInternal.getPackageUid(callingPackage, 0, 2714 callingUserId)) { 2715 throw new SecurityException("Package " + callingPackage 2716 + " does not belong to the calling uid " + callingUid); 2717 } 2718 2719 // Repeating alarms must use PendingIntent, not direct listener 2720 if (interval != 0 && directReceiver != null) { 2721 throw new IllegalArgumentException("Repeating alarms cannot use AlarmReceivers"); 2722 } 2723 2724 if (workSource != null) { 2725 getContext().enforcePermission( 2726 android.Manifest.permission.UPDATE_DEVICE_STATS, 2727 Binder.getCallingPid(), callingUid, "AlarmManager.set"); 2728 } 2729 2730 if ((flags & AlarmManager.FLAG_IDLE_UNTIL) != 0) { 2731 // Only the system can use FLAG_IDLE_UNTIL -- this is used to tell the alarm 2732 // manager when to come out of idle mode, which is only for DeviceIdleController. 2733 if (callingUid != Process.SYSTEM_UID) { 2734 // TODO (b/169463012): Throw instead of tolerating this mistake. 2735 flags &= ~AlarmManager.FLAG_IDLE_UNTIL; 2736 } else { 2737 // Do not support windows for idle-until alarms. 2738 windowLength = 0; 2739 } 2740 } 2741 2742 // Remove flags reserved for the service, we will apply those later as appropriate. 2743 flags &= ~(FLAG_WAKE_FROM_IDLE | FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED 2744 | FLAG_ALLOW_WHILE_IDLE_COMPAT); 2745 2746 // If this alarm is for an alarm clock, then it must be exact and we will 2747 // use it to wake early from idle if needed. 2748 if (alarmClock != null) { 2749 flags |= FLAG_WAKE_FROM_IDLE; 2750 windowLength = 0; 2751 2752 // If the caller is a core system component or on the user's allowlist, and not calling 2753 // to do work on behalf of someone else, then always set ALLOW_WHILE_IDLE_UNRESTRICTED. 2754 // This means we will allow these alarms to go off as normal even while idle, with no 2755 // timing restrictions. 2756 } else if (workSource == null && (UserHandle.isCore(callingUid) 2757 || UserHandle.isSameApp(callingUid, mSystemUiUid) 2758 || ((mAppStateTracker != null) 2759 && mAppStateTracker.isUidPowerSaveUserExempt(callingUid)))) { 2760 flags |= FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED; 2761 flags &= ~(FLAG_ALLOW_WHILE_IDLE | FLAG_PRIORITIZE); 2762 } 2763 2764 final boolean allowWhileIdle = (flags & FLAG_ALLOW_WHILE_IDLE) != 0; 2765 final boolean exact = (windowLength == 0); 2766 2767 // Make sure the caller is allowed to use the requested kind of alarm, and also 2768 // decide what quota and broadcast options to use. 2769 int exactAllowReason = EXACT_ALLOW_REASON_NOT_APPLICABLE; 2770 Bundle idleOptions = null; 2771 if ((flags & FLAG_PRIORITIZE) != 0) { 2772 getContext().enforcePermission( 2773 Manifest.permission.SCHEDULE_PRIORITIZED_ALARM, 2774 Binder.getCallingPid(), callingUid, "AlarmManager.setPrioritized"); 2775 // The API doesn't allow using both together. 2776 flags &= ~FLAG_ALLOW_WHILE_IDLE; 2777 // Prioritized alarms don't need any extra permission to be exact. 2778 if (exact) { 2779 exactAllowReason = EXACT_ALLOW_REASON_PRIORITIZED; 2780 } 2781 } else if (exact || allowWhileIdle) { 2782 final boolean needsPermission; 2783 boolean lowerQuota; 2784 if (isExactAlarmChangeEnabled(callingPackage, callingUserId)) { 2785 if (directReceiver == null) { 2786 needsPermission = exact; 2787 lowerQuota = !exact; 2788 } else { 2789 needsPermission = false; 2790 lowerQuota = allowWhileIdle; 2791 if (exact) { 2792 exactAllowReason = EXACT_ALLOW_REASON_LISTENER; 2793 } 2794 } 2795 if (exact) { 2796 idleOptions = (alarmClock != null) ? mOptsWithFgsForAlarmClock.toBundle() 2797 : mOptsWithFgs.toBundle(); 2798 } else { 2799 idleOptions = mOptsWithoutFgs.toBundle(); 2800 } 2801 } else { 2802 needsPermission = false; 2803 lowerQuota = allowWhileIdle; 2804 idleOptions = (allowWhileIdle || (alarmClock != null)) 2805 // This avoids exceptions on existing alarms when the app upgrades to 2806 // target S. Note that FGS from pre-S apps isn't restricted anyway. 2807 ? mOptsWithFgs.toBundle() 2808 : null; 2809 if (exact) { 2810 exactAllowReason = EXACT_ALLOW_REASON_COMPAT; 2811 } 2812 } 2813 if (needsPermission) { 2814 if (hasUseExactAlarmInternal(callingPackage, callingUid)) { 2815 exactAllowReason = EXACT_ALLOW_REASON_POLICY_PERMISSION; 2816 } else if (hasScheduleExactAlarmInternal(callingPackage, callingUid)) { 2817 exactAllowReason = EXACT_ALLOW_REASON_PERMISSION; 2818 } else { 2819 if (isExemptFromExactAlarmPermissionNoLock(callingUid)) { 2820 exactAllowReason = EXACT_ALLOW_REASON_ALLOW_LIST; 2821 } else { 2822 final String errorMessage = 2823 "Caller " + callingPackage + " needs to hold " 2824 + Manifest.permission.SCHEDULE_EXACT_ALARM + " or " 2825 + Manifest.permission.USE_EXACT_ALARM + " to set " 2826 + "exact alarms."; 2827 throw new SecurityException(errorMessage); 2828 } 2829 // If the app is on the full system power allow-list (not except-idle), 2830 // or the user-elected allow-list, we allow exact alarms. 2831 // ALLOW_WHILE_IDLE alarms get a lower quota equivalent to what pre-S apps 2832 // got. Note that user-allow-listed apps don't use FLAG_ALLOW_WHILE_IDLE. 2833 // We grant temporary allow-list to allow-while-idle alarms but without FGS 2834 // capability. AlarmClock alarms do not get the temporary allow-list. 2835 // This is consistent with pre-S behavior. Note that apps that are in 2836 // either of the power-save allow-lists do not need it. 2837 idleOptions = allowWhileIdle ? mOptsWithoutFgs.toBundle() : null; 2838 lowerQuota = allowWhileIdle; 2839 } 2840 } 2841 if (lowerQuota) { 2842 flags &= ~FLAG_ALLOW_WHILE_IDLE; 2843 flags |= FLAG_ALLOW_WHILE_IDLE_COMPAT; 2844 } 2845 } 2846 if (exact) { 2847 // If this is an exact time alarm, then it can't be batched with other alarms. 2848 flags |= AlarmManager.FLAG_STANDALONE; 2849 2850 } 2851 2852 setImpl(type, triggerAtTime, windowLength, interval, operation, directReceiver, 2853 listenerTag, flags, workSource, alarmClock, callingUid, callingPackage, 2854 idleOptions, exactAllowReason); 2855 } 2856 2857 @Override 2858 public boolean canScheduleExactAlarms(String packageName) { 2859 final int callingUid = mInjector.getCallingUid(); 2860 final int userId = UserHandle.getUserId(callingUid); 2861 final int packageUid = mPackageManagerInternal.getPackageUid(packageName, 0, userId); 2862 if (callingUid != packageUid) { 2863 throw new SecurityException("Uid " + callingUid 2864 + " cannot query canScheduleExactAlarms for package " + packageName); 2865 } 2866 if (!isExactAlarmChangeEnabled(packageName, userId)) { 2867 return true; 2868 } 2869 return isExemptFromExactAlarmPermissionNoLock(packageUid) 2870 || hasScheduleExactAlarmInternal(packageName, packageUid) 2871 || hasUseExactAlarmInternal(packageName, packageUid); 2872 } 2873 2874 @Override 2875 public boolean hasScheduleExactAlarm(String packageName, int userId) { 2876 final int callingUid = mInjector.getCallingUid(); 2877 if (UserHandle.getUserId(callingUid) != userId) { 2878 getContext().enforceCallingOrSelfPermission( 2879 Manifest.permission.INTERACT_ACROSS_USERS_FULL, "hasScheduleExactAlarm"); 2880 } 2881 final int uid = mPackageManagerInternal.getPackageUid(packageName, 0, userId); 2882 if (callingUid != uid && !UserHandle.isCore(callingUid)) { 2883 throw new SecurityException("Uid " + callingUid 2884 + " cannot query hasScheduleExactAlarm for package " + packageName); 2885 } 2886 return (uid > 0) ? hasScheduleExactAlarmInternal(packageName, uid) : false; 2887 } 2888 2889 @EnforcePermission(android.Manifest.permission.SET_TIME) 2890 @Override 2891 public boolean setTime(@CurrentTimeMillisLong long millis) { 2892 setTime_enforcePermission(); 2893 2894 // The public API (and the shell command that also uses this method) have no concept 2895 // of confidence, but since the time should come either from apps working on behalf of 2896 // the user or a developer, confidence is assumed "high". 2897 final int timeConfidence = TIME_CONFIDENCE_HIGH; 2898 return setTimeImpl(millis, timeConfidence, "AlarmManager.setTime() called"); 2899 } 2900 2901 @EnforcePermission(android.Manifest.permission.SET_TIME_ZONE) 2902 @Override 2903 public void setTimeZone(String tz) { 2904 setTimeZone_enforcePermission(); 2905 2906 final long oldId = Binder.clearCallingIdentity(); 2907 try { 2908 // The public API (and the shell command that also uses this method) have no concept 2909 // of confidence, but since the time zone ID should come either from apps working on 2910 // behalf of the user or a developer, confidence is assumed "high". 2911 final int timeZoneConfidence = TIME_ZONE_CONFIDENCE_HIGH; 2912 setTimeZoneImpl(tz, timeZoneConfidence, "AlarmManager.setTimeZone() called"); 2913 } finally { 2914 Binder.restoreCallingIdentity(oldId); 2915 } 2916 } 2917 2918 @Override 2919 public void remove(PendingIntent operation, IAlarmListener listener) { 2920 if (operation == null && listener == null) { 2921 Slog.w(TAG, "remove() with no intent or listener"); 2922 return; 2923 } 2924 synchronized (mLock) { 2925 removeLocked(operation, listener, REMOVE_REASON_ALARM_CANCELLED); 2926 } 2927 } 2928 2929 @Override 2930 public void removeAll(String callingPackage) { 2931 final int callingUid = mInjector.getCallingUid(); 2932 if (callingUid == Process.SYSTEM_UID) { 2933 Slog.wtfStack(TAG, "Attempt to remove all alarms from the system uid package: " 2934 + callingPackage); 2935 return; 2936 } 2937 if (callingUid != mPackageManagerInternal.getPackageUid(callingPackage, 0, 2938 UserHandle.getUserId(callingUid))) { 2939 throw new SecurityException("Package " + callingPackage 2940 + " does not belong to the calling uid " + callingUid); 2941 } 2942 synchronized (mLock) { 2943 removeAlarmsInternalLocked( 2944 a -> (a.matches(callingPackage) && a.creatorUid == callingUid), 2945 REMOVE_REASON_ALARM_CANCELLED); 2946 } 2947 } 2948 2949 @Override 2950 public long getNextWakeFromIdleTime() { 2951 return getNextWakeFromIdleTimeImpl(); 2952 } 2953 2954 @Override 2955 public AlarmManager.AlarmClockInfo getNextAlarmClock(int userId) { 2956 userId = mActivityManagerInternal.handleIncomingUser(Binder.getCallingPid(), 2957 Binder.getCallingUid(), userId, /*allowAll=*/false, ALLOW_NON_FULL, 2958 "getNextAlarmClock", null); 2959 return getNextAlarmClockImpl(userId); 2960 } 2961 2962 @EnforcePermission(android.Manifest.permission.DUMP) 2963 @Override 2964 public int getConfigVersion() { 2965 getConfigVersion_enforcePermission(); 2966 return mConstants.getVersion(); 2967 } 2968 2969 @Override 2970 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2971 if (!DumpUtils.checkDumpAndUsageStatsPermission(getContext(), TAG, pw)) return; 2972 2973 if (args.length > 0 && "--proto".equals(args[0])) { 2974 dumpProto(fd); 2975 } else { 2976 dumpImpl(new IndentingPrintWriter(pw, " ")); 2977 } 2978 } 2979 2980 @Override 2981 public void onShellCommand(FileDescriptor in, FileDescriptor out, 2982 FileDescriptor err, String[] args, ShellCallback callback, 2983 ResultReceiver resultReceiver) { 2984 (new ShellCmd()).exec(this, in, out, err, args, callback, resultReceiver); 2985 } 2986 }; 2987 isExactAlarmChangeEnabled(String packageName, int userId)2988 private static boolean isExactAlarmChangeEnabled(String packageName, int userId) { 2989 return CompatChanges.isChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, 2990 packageName, UserHandle.of(userId)); 2991 } 2992 isUseExactAlarmEnabled(String packageName, int userId)2993 private static boolean isUseExactAlarmEnabled(String packageName, int userId) { 2994 return CompatChanges.isChangeEnabled(AlarmManager.ENABLE_USE_EXACT_ALARM, 2995 packageName, UserHandle.of(userId)); 2996 } 2997 isScheduleExactAlarmDeniedByDefault(String packageName, int userId)2998 private boolean isScheduleExactAlarmDeniedByDefault(String packageName, int userId) { 2999 return CompatChanges.isChangeEnabled(AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, 3000 packageName, UserHandle.of(userId)); 3001 } 3002 3003 @NeverCompile // Avoid size overhead of debugging code. dumpImpl(IndentingPrintWriter pw)3004 void dumpImpl(IndentingPrintWriter pw) { 3005 synchronized (mLock) { 3006 pw.println("Current Alarm Manager state:"); 3007 pw.increaseIndent(); 3008 3009 mConstants.dump(pw); 3010 pw.println(); 3011 3012 pw.println("Feature Flags:"); 3013 pw.increaseIndent(); 3014 pw.print(Flags.FLAG_USE_FROZEN_STATE_TO_DROP_LISTENER_ALARMS, 3015 mUseFrozenStateToDropListenerAlarms); 3016 pw.println(); 3017 pw.print(Flags.FLAG_START_USER_BEFORE_SCHEDULED_ALARMS, 3018 mStartUserBeforeScheduledAlarms); 3019 pw.decreaseIndent(); 3020 pw.println(); 3021 pw.println(); 3022 3023 pw.println("App Standby Parole: " + mAppStandbyParole); 3024 pw.println(); 3025 3026 if (mAppStateTracker != null) { 3027 mAppStateTracker.dump(pw); 3028 pw.println(); 3029 } 3030 3031 final long nowELAPSED = mInjector.getElapsedRealtimeMillis(); 3032 final long nowUPTIME = SystemClock.uptimeMillis(); 3033 final long nowRTC = mInjector.getCurrentTimeMillis(); 3034 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 3035 3036 pw.print("nowRTC="); 3037 pw.print(nowRTC); 3038 pw.print("="); 3039 pw.print(sdf.format(new Date(nowRTC))); 3040 pw.print(" nowELAPSED="); 3041 pw.print(nowELAPSED); 3042 pw.println(); 3043 3044 pw.print("mLastTimeChangeClockTime="); 3045 pw.print(mLastTimeChangeClockTime); 3046 pw.print("="); 3047 pw.println(sdf.format(new Date(mLastTimeChangeClockTime))); 3048 3049 pw.print("mLastTimeChangeRealtime="); 3050 pw.println(mLastTimeChangeRealtime); 3051 3052 pw.print("mLastTickReceived="); 3053 pw.println(sdf.format(new Date(mLastTickReceived))); 3054 3055 pw.print("mLastTickSet="); 3056 pw.println(sdf.format(new Date(mLastTickSet))); 3057 3058 if (RECORD_ALARMS_IN_HISTORY) { 3059 pw.println(); 3060 pw.println("Recent TIME_TICK history:"); 3061 pw.increaseIndent(); 3062 int i = mNextTickHistory; 3063 do { 3064 i--; 3065 if (i < 0) i = TICK_HISTORY_DEPTH - 1; 3066 final long time = mTickHistory[i]; 3067 pw.println((time > 0) 3068 ? sdf.format(new Date(nowRTC - (nowELAPSED - time))) 3069 : "-"); 3070 } while (i != mNextTickHistory); 3071 pw.decreaseIndent(); 3072 } 3073 3074 SystemServiceManager ssm = LocalServices.getService(SystemServiceManager.class); 3075 if (ssm != null) { 3076 pw.println(); 3077 pw.print("RuntimeStarted="); 3078 pw.print(sdf.format( 3079 new Date(nowRTC - nowELAPSED + ssm.getRuntimeStartElapsedTime()))); 3080 if (ssm.isRuntimeRestarted()) { 3081 pw.print(" (Runtime restarted)"); 3082 } 3083 pw.println(); 3084 3085 pw.print("Runtime uptime (elapsed): "); 3086 TimeUtils.formatDuration(nowELAPSED, ssm.getRuntimeStartElapsedTime(), pw); 3087 pw.println(); 3088 3089 pw.print("Runtime uptime (uptime): "); 3090 TimeUtils.formatDuration(nowUPTIME, ssm.getRuntimeStartUptime(), pw); 3091 pw.println(); 3092 } 3093 3094 pw.println(); 3095 if (!mInteractive) { 3096 pw.print("Time since non-interactive: "); 3097 TimeUtils.formatDuration(nowELAPSED - mNonInteractiveStartTime, pw); 3098 pw.println(); 3099 } 3100 pw.print("Max wakeup delay: "); 3101 TimeUtils.formatDuration(currentNonWakeupFuzzLocked(nowELAPSED), pw); 3102 pw.println(); 3103 3104 pw.print("Time since last dispatch: "); 3105 TimeUtils.formatDuration(nowELAPSED - mLastAlarmDeliveryTime, pw); 3106 pw.println(); 3107 3108 pw.print("Next non-wakeup delivery time: "); 3109 TimeUtils.formatDuration(mNextNonWakeupDeliveryTime, nowELAPSED, pw); 3110 pw.println(); 3111 3112 long nextWakeupRTC = mNextWakeup + (nowRTC - nowELAPSED); 3113 long nextNonWakeupRTC = mNextNonWakeup + (nowRTC - nowELAPSED); 3114 pw.print("Next non-wakeup alarm: "); 3115 TimeUtils.formatDuration(mNextNonWakeup, nowELAPSED, pw); 3116 pw.print(" = "); 3117 pw.print(mNextNonWakeup); 3118 pw.print(" = "); 3119 pw.println(sdf.format(new Date(nextNonWakeupRTC))); 3120 3121 pw.increaseIndent(); 3122 pw.print("set at "); 3123 TimeUtils.formatDuration(mNextNonWakeUpSetAt, nowELAPSED, pw); 3124 pw.decreaseIndent(); 3125 pw.println(); 3126 3127 pw.print("Next wakeup alarm: "); 3128 TimeUtils.formatDuration(mNextWakeup, nowELAPSED, pw); 3129 pw.print(" = "); 3130 pw.print(mNextWakeup); 3131 pw.print(" = "); 3132 pw.println(sdf.format(new Date(nextWakeupRTC))); 3133 3134 pw.increaseIndent(); 3135 pw.print("set at "); 3136 TimeUtils.formatDuration(mNextWakeUpSetAt, nowELAPSED, pw); 3137 pw.decreaseIndent(); 3138 pw.println(); 3139 3140 pw.print("Next kernel non-wakeup alarm: "); 3141 TimeUtils.formatDuration(mInjector.getNextAlarm(ELAPSED_REALTIME), pw); 3142 pw.println(); 3143 pw.print("Next kernel wakeup alarm: "); 3144 TimeUtils.formatDuration(mInjector.getNextAlarm(ELAPSED_REALTIME_WAKEUP), pw); 3145 pw.println(); 3146 3147 pw.print("Last wakeup: "); 3148 TimeUtils.formatDuration(mLastWakeup, nowELAPSED, pw); 3149 pw.print(" = "); 3150 pw.println(mLastWakeup); 3151 3152 pw.print("Last trigger: "); 3153 TimeUtils.formatDuration(mLastTrigger, nowELAPSED, pw); 3154 pw.print(" = "); 3155 pw.println(mLastTrigger); 3156 3157 pw.print("Num time change events: "); 3158 pw.println(mNumTimeChanged); 3159 3160 pw.println(); 3161 pw.println("App ids requesting SCHEDULE_EXACT_ALARM: " + mExactAlarmCandidates); 3162 3163 pw.println(); 3164 pw.print("Last OP_SCHEDULE_EXACT_ALARM: ["); 3165 for (int i = 0; i < mLastOpScheduleExactAlarm.size(); i++) { 3166 if (i > 0) { 3167 pw.print(", "); 3168 } 3169 UserHandle.formatUid(pw, mLastOpScheduleExactAlarm.keyAt(i)); 3170 pw.print(":" + AppOpsManager.modeToName(mLastOpScheduleExactAlarm.valueAt(i))); 3171 } 3172 pw.println("]"); 3173 3174 pw.println(); 3175 pw.println("Next alarm clock information: "); 3176 pw.increaseIndent(); 3177 final TreeSet<Integer> users = new TreeSet<>(); 3178 for (int i = 0; i < mNextAlarmClockForUser.size(); i++) { 3179 users.add(mNextAlarmClockForUser.keyAt(i)); 3180 } 3181 for (int i = 0; i < mPendingSendNextAlarmClockChangedForUser.size(); i++) { 3182 users.add(mPendingSendNextAlarmClockChangedForUser.keyAt(i)); 3183 } 3184 for (int user : users) { 3185 final AlarmManager.AlarmClockInfo next = mNextAlarmClockForUser.get(user); 3186 final long time = next != null ? next.getTriggerTime() : 0; 3187 final boolean pendingSend = mPendingSendNextAlarmClockChangedForUser.get(user); 3188 pw.print("user:"); 3189 pw.print(user); 3190 pw.print(" pendingSend:"); 3191 pw.print(pendingSend); 3192 pw.print(" time:"); 3193 pw.print(time); 3194 if (time > 0) { 3195 pw.print(" = "); 3196 pw.print(sdf.format(new Date(time))); 3197 pw.print(" = "); 3198 TimeUtils.formatDuration(time, nowRTC, pw); 3199 } 3200 pw.println(); 3201 } 3202 pw.decreaseIndent(); 3203 3204 if (mAlarmStore.size() > 0) { 3205 pw.println(); 3206 mAlarmStore.dump(pw, nowELAPSED, sdf); 3207 } 3208 pw.println(); 3209 3210 pw.println("Pending user blocked background alarms: "); 3211 pw.increaseIndent(); 3212 boolean blocked = false; 3213 for (int i = 0; i < mPendingBackgroundAlarms.size(); i++) { 3214 final ArrayList<Alarm> blockedAlarms = mPendingBackgroundAlarms.valueAt(i); 3215 if (blockedAlarms != null && blockedAlarms.size() > 0) { 3216 blocked = true; 3217 dumpAlarmList(pw, blockedAlarms, nowELAPSED, sdf); 3218 } 3219 } 3220 if (!blocked) { 3221 pw.println("none"); 3222 } 3223 pw.decreaseIndent(); 3224 pw.println(); 3225 3226 pw.print("Pending alarms per uid: ["); 3227 for (int i = 0; i < mAlarmsPerUid.size(); i++) { 3228 if (i > 0) { 3229 pw.print(", "); 3230 } 3231 UserHandle.formatUid(pw, mAlarmsPerUid.keyAt(i)); 3232 pw.print(":"); 3233 pw.print(mAlarmsPerUid.valueAt(i)); 3234 } 3235 pw.println("]"); 3236 pw.println(); 3237 3238 if (mStartUserBeforeScheduledAlarms) { 3239 pw.println("Scheduled user wakeups:"); 3240 mUserWakeupStore.dump(pw, nowELAPSED); 3241 pw.println(); 3242 } 3243 3244 pw.println("App Alarm history:"); 3245 mAppWakeupHistory.dump(pw, nowELAPSED); 3246 3247 pw.println(); 3248 pw.println("Temporary Quota Reserves:"); 3249 mTemporaryQuotaReserve.dump(pw, nowELAPSED); 3250 3251 if (mPendingIdleUntil != null) { 3252 pw.println(); 3253 pw.println("Idle mode state:"); 3254 3255 pw.increaseIndent(); 3256 pw.print("Idling until: "); 3257 if (mPendingIdleUntil != null) { 3258 pw.println(mPendingIdleUntil); 3259 mPendingIdleUntil.dump(pw, nowELAPSED, sdf); 3260 } else { 3261 pw.println("null"); 3262 } 3263 pw.decreaseIndent(); 3264 } 3265 if (mNextWakeFromIdle != null) { 3266 pw.println(); 3267 pw.print("Next wake from idle: "); 3268 pw.println(mNextWakeFromIdle); 3269 3270 pw.increaseIndent(); 3271 mNextWakeFromIdle.dump(pw, nowELAPSED, sdf); 3272 pw.decreaseIndent(); 3273 } 3274 3275 pw.println(); 3276 pw.print("Past-due non-wakeup alarms: "); 3277 if (mPendingNonWakeupAlarms.size() > 0) { 3278 pw.println(mPendingNonWakeupAlarms.size()); 3279 3280 pw.increaseIndent(); 3281 dumpAlarmList(pw, mPendingNonWakeupAlarms, nowELAPSED, sdf); 3282 pw.decreaseIndent(); 3283 } else { 3284 pw.println("(none)"); 3285 } 3286 pw.increaseIndent(); 3287 pw.print("Number of delayed alarms: "); 3288 pw.print(mNumDelayedAlarms); 3289 pw.print(", total delay time: "); 3290 TimeUtils.formatDuration(mTotalDelayTime, pw); 3291 pw.println(); 3292 3293 pw.print("Max delay time: "); 3294 TimeUtils.formatDuration(mMaxDelayTime, pw); 3295 pw.print(", max non-interactive time: "); 3296 TimeUtils.formatDuration(mNonInteractiveTime, pw); 3297 pw.println(); 3298 pw.decreaseIndent(); 3299 3300 pw.println(); 3301 pw.print("Broadcast ref count: "); 3302 pw.println(mBroadcastRefCount); 3303 pw.print("PendingIntent send count: "); 3304 pw.println(mSendCount); 3305 pw.print("PendingIntent finish count: "); 3306 pw.println(mSendFinishCount); 3307 pw.print("Listener send count: "); 3308 pw.println(mListenerCount); 3309 pw.print("Listener finish count: "); 3310 pw.println(mListenerFinishCount); 3311 pw.println(); 3312 3313 if (mInFlight.size() > 0) { 3314 pw.println("Outstanding deliveries:"); 3315 pw.increaseIndent(); 3316 for (int i = 0; i < mInFlight.size(); i++) { 3317 pw.print("#"); 3318 pw.print(i); 3319 pw.print(": "); 3320 pw.println(mInFlight.get(i)); 3321 } 3322 pw.decreaseIndent(); 3323 pw.println(); 3324 } 3325 3326 pw.println("Allow while idle history:"); 3327 mAllowWhileIdleHistory.dump(pw, nowELAPSED); 3328 pw.println(); 3329 3330 pw.println("Allow while idle compat history:"); 3331 mAllowWhileIdleCompatHistory.dump(pw, nowELAPSED); 3332 pw.println(); 3333 3334 if (mLastPriorityAlarmDispatch.size() > 0) { 3335 pw.println("Last priority alarm dispatches:"); 3336 pw.increaseIndent(); 3337 for (int i = 0; i < mLastPriorityAlarmDispatch.size(); i++) { 3338 pw.print("UID: "); 3339 UserHandle.formatUid(pw, mLastPriorityAlarmDispatch.keyAt(i)); 3340 pw.print(": "); 3341 TimeUtils.formatDuration(mLastPriorityAlarmDispatch.valueAt(i), nowELAPSED, pw); 3342 pw.println(); 3343 } 3344 pw.decreaseIndent(); 3345 } 3346 3347 if (mRemovalHistory.size() > 0) { 3348 pw.println("Removal history:"); 3349 pw.increaseIndent(); 3350 for (int i = 0; i < mRemovalHistory.size(); i++) { 3351 UserHandle.formatUid(pw, mRemovalHistory.keyAt(i)); 3352 pw.println(":"); 3353 pw.increaseIndent(); 3354 final RemovedAlarm[] historyForUid = mRemovalHistory.valueAt(i).toArray(); 3355 for (int index = historyForUid.length - 1; index >= 0; index--) { 3356 pw.print("#" + (historyForUid.length - index) + ": "); 3357 historyForUid[index].dump(pw, nowELAPSED, sdf); 3358 } 3359 pw.decreaseIndent(); 3360 } 3361 pw.decreaseIndent(); 3362 pw.println(); 3363 } 3364 3365 if (mLog.dump(pw, "Recent problems:")) { 3366 pw.println(); 3367 } 3368 3369 final FilterStats[] topFilters = new FilterStats[10]; 3370 final Comparator<FilterStats> comparator = new Comparator<FilterStats>() { 3371 @Override 3372 public int compare(FilterStats lhs, FilterStats rhs) { 3373 if (lhs.aggregateTime < rhs.aggregateTime) { 3374 return 1; 3375 } else if (lhs.aggregateTime > rhs.aggregateTime) { 3376 return -1; 3377 } 3378 return 0; 3379 } 3380 }; 3381 int len = 0; 3382 // Get the top 10 FilterStats, ordered by aggregateTime. 3383 for (int iu = 0; iu < mBroadcastStats.size(); iu++) { 3384 ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(iu); 3385 for (int ip = 0; ip < uidStats.size(); ip++) { 3386 BroadcastStats bs = uidStats.valueAt(ip); 3387 for (int is = 0; is < bs.filterStats.size(); is++) { 3388 FilterStats fs = bs.filterStats.valueAt(is); 3389 int pos = len > 0 3390 ? Arrays.binarySearch(topFilters, 0, len, fs, comparator) : 0; 3391 if (pos < 0) { 3392 pos = -pos - 1; 3393 } 3394 if (pos < topFilters.length) { 3395 int copylen = topFilters.length - pos - 1; 3396 if (copylen > 0) { 3397 System.arraycopy(topFilters, pos, topFilters, pos + 1, copylen); 3398 } 3399 topFilters[pos] = fs; 3400 if (len < topFilters.length) { 3401 len++; 3402 } 3403 } 3404 } 3405 } 3406 } 3407 if (len > 0) { 3408 pw.println("Top Alarms:"); 3409 pw.increaseIndent(); 3410 for (int i = 0; i < len; i++) { 3411 FilterStats fs = topFilters[i]; 3412 if (fs.nesting > 0) pw.print("*ACTIVE* "); 3413 TimeUtils.formatDuration(fs.aggregateTime, pw); 3414 pw.print(" running, "); 3415 pw.print(fs.numWakeup); 3416 pw.print(" wakeups, "); 3417 pw.print(fs.count); 3418 pw.print(" alarms: "); 3419 UserHandle.formatUid(pw, fs.mBroadcastStats.mUid); 3420 pw.print(":"); 3421 pw.print(fs.mBroadcastStats.mPackageName); 3422 pw.println(); 3423 3424 pw.increaseIndent(); 3425 pw.print(fs.mTag); 3426 pw.println(); 3427 pw.decreaseIndent(); 3428 } 3429 pw.decreaseIndent(); 3430 } 3431 3432 pw.println(); 3433 pw.println("Alarm Stats:"); 3434 final ArrayList<FilterStats> tmpFilters = new ArrayList<FilterStats>(); 3435 for (int iu = 0; iu < mBroadcastStats.size(); iu++) { 3436 ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(iu); 3437 for (int ip = 0; ip < uidStats.size(); ip++) { 3438 BroadcastStats bs = uidStats.valueAt(ip); 3439 if (bs.nesting > 0) pw.print("*ACTIVE* "); 3440 UserHandle.formatUid(pw, bs.mUid); 3441 pw.print(":"); 3442 pw.print(bs.mPackageName); 3443 pw.print(" "); 3444 TimeUtils.formatDuration(bs.aggregateTime, pw); 3445 pw.print(" running, "); 3446 pw.print(bs.numWakeup); 3447 pw.println(" wakeups:"); 3448 3449 tmpFilters.clear(); 3450 for (int is = 0; is < bs.filterStats.size(); is++) { 3451 tmpFilters.add(bs.filterStats.valueAt(is)); 3452 } 3453 Collections.sort(tmpFilters, comparator); 3454 pw.increaseIndent(); 3455 for (int i = 0; i < tmpFilters.size(); i++) { 3456 FilterStats fs = tmpFilters.get(i); 3457 if (fs.nesting > 0) pw.print("*ACTIVE* "); 3458 TimeUtils.formatDuration(fs.aggregateTime, pw); 3459 pw.print(" "); 3460 pw.print(fs.numWakeup); 3461 pw.print(" wakes "); 3462 pw.print(fs.count); 3463 pw.print(" alarms, last "); 3464 TimeUtils.formatDuration(fs.lastTime, nowELAPSED, pw); 3465 pw.println(":"); 3466 3467 pw.increaseIndent(); 3468 pw.print(fs.mTag); 3469 pw.println(); 3470 pw.decreaseIndent(); 3471 } 3472 pw.decreaseIndent(); 3473 } 3474 } 3475 pw.println(); 3476 mStatLogger.dump(pw); 3477 3478 if (RECORD_DEVICE_IDLE_ALARMS) { 3479 pw.println(); 3480 pw.println("Allow while idle dispatches:"); 3481 pw.increaseIndent(); 3482 for (int i = 0; i < mAllowWhileIdleDispatches.size(); i++) { 3483 IdleDispatchEntry ent = mAllowWhileIdleDispatches.get(i); 3484 TimeUtils.formatDuration(ent.elapsedRealtime, nowELAPSED, pw); 3485 pw.print(": "); 3486 UserHandle.formatUid(pw, ent.uid); 3487 pw.print(":"); 3488 pw.println(ent.pkg); 3489 3490 pw.increaseIndent(); 3491 if (ent.op != null) { 3492 pw.print(ent.op); 3493 pw.print(" / "); 3494 pw.print(ent.tag); 3495 if (ent.argRealtime != 0) { 3496 pw.print(" ("); 3497 TimeUtils.formatDuration(ent.argRealtime, nowELAPSED, pw); 3498 pw.print(")"); 3499 } 3500 pw.println(); 3501 } 3502 pw.decreaseIndent(); 3503 } 3504 pw.decreaseIndent(); 3505 } 3506 } 3507 } 3508 dumpProto(FileDescriptor fd)3509 void dumpProto(FileDescriptor fd) { 3510 final ProtoOutputStream proto = new ProtoOutputStream(fd); 3511 3512 synchronized (mLock) { 3513 final long nowRTC = mInjector.getCurrentTimeMillis(); 3514 final long nowElapsed = mInjector.getElapsedRealtimeMillis(); 3515 proto.write(AlarmManagerServiceDumpProto.CURRENT_TIME, nowRTC); 3516 proto.write(AlarmManagerServiceDumpProto.ELAPSED_REALTIME, nowElapsed); 3517 proto.write(AlarmManagerServiceDumpProto.LAST_TIME_CHANGE_CLOCK_TIME, 3518 mLastTimeChangeClockTime); 3519 proto.write(AlarmManagerServiceDumpProto.LAST_TIME_CHANGE_REALTIME, 3520 mLastTimeChangeRealtime); 3521 3522 mConstants.dumpProto(proto, AlarmManagerServiceDumpProto.SETTINGS); 3523 3524 if (mAppStateTracker != null) { 3525 mAppStateTracker.dumpProto(proto, AlarmManagerServiceDumpProto.APP_STATE_TRACKER); 3526 } 3527 3528 proto.write(AlarmManagerServiceDumpProto.IS_INTERACTIVE, mInteractive); 3529 if (!mInteractive) { 3530 // Durations 3531 proto.write(AlarmManagerServiceDumpProto.TIME_SINCE_NON_INTERACTIVE_MS, 3532 nowElapsed - mNonInteractiveStartTime); 3533 proto.write(AlarmManagerServiceDumpProto.MAX_WAKEUP_DELAY_MS, 3534 currentNonWakeupFuzzLocked(nowElapsed)); 3535 proto.write(AlarmManagerServiceDumpProto.TIME_SINCE_LAST_DISPATCH_MS, 3536 nowElapsed - mLastAlarmDeliveryTime); 3537 proto.write(AlarmManagerServiceDumpProto.TIME_UNTIL_NEXT_NON_WAKEUP_DELIVERY_MS, 3538 nowElapsed - mNextNonWakeupDeliveryTime); 3539 } 3540 3541 proto.write(AlarmManagerServiceDumpProto.TIME_UNTIL_NEXT_NON_WAKEUP_ALARM_MS, 3542 mNextNonWakeup - nowElapsed); 3543 proto.write(AlarmManagerServiceDumpProto.TIME_UNTIL_NEXT_WAKEUP_MS, 3544 mNextWakeup - nowElapsed); 3545 proto.write(AlarmManagerServiceDumpProto.TIME_SINCE_LAST_WAKEUP_MS, 3546 nowElapsed - mLastWakeup); 3547 proto.write(AlarmManagerServiceDumpProto.TIME_SINCE_LAST_WAKEUP_SET_MS, 3548 nowElapsed - mNextWakeUpSetAt); 3549 proto.write(AlarmManagerServiceDumpProto.TIME_CHANGE_EVENT_COUNT, mNumTimeChanged); 3550 3551 final TreeSet<Integer> users = new TreeSet<>(); 3552 final int nextAlarmClockForUserSize = mNextAlarmClockForUser.size(); 3553 for (int i = 0; i < nextAlarmClockForUserSize; i++) { 3554 users.add(mNextAlarmClockForUser.keyAt(i)); 3555 } 3556 final int pendingSendNextAlarmClockChangedForUserSize = 3557 mPendingSendNextAlarmClockChangedForUser.size(); 3558 for (int i = 0; i < pendingSendNextAlarmClockChangedForUserSize; i++) { 3559 users.add(mPendingSendNextAlarmClockChangedForUser.keyAt(i)); 3560 } 3561 for (int user : users) { 3562 final AlarmManager.AlarmClockInfo next = mNextAlarmClockForUser.get(user); 3563 final long time = next != null ? next.getTriggerTime() : 0; 3564 final boolean pendingSend = mPendingSendNextAlarmClockChangedForUser.get(user); 3565 final long aToken = proto.start( 3566 AlarmManagerServiceDumpProto.NEXT_ALARM_CLOCK_METADATA); 3567 proto.write(AlarmClockMetadataProto.USER, user); 3568 proto.write(AlarmClockMetadataProto.IS_PENDING_SEND, pendingSend); 3569 proto.write(AlarmClockMetadataProto.TRIGGER_TIME_MS, time); 3570 proto.end(aToken); 3571 } 3572 mAlarmStore.dumpProto(proto, nowElapsed); 3573 3574 for (int i = 0; i < mPendingBackgroundAlarms.size(); i++) { 3575 final ArrayList<Alarm> blockedAlarms = mPendingBackgroundAlarms.valueAt(i); 3576 if (blockedAlarms != null) { 3577 for (Alarm a : blockedAlarms) { 3578 a.dumpDebug(proto, 3579 AlarmManagerServiceDumpProto.PENDING_USER_BLOCKED_BACKGROUND_ALARMS, 3580 nowElapsed); 3581 } 3582 } 3583 } 3584 if (mPendingIdleUntil != null) { 3585 mPendingIdleUntil.dumpDebug( 3586 proto, AlarmManagerServiceDumpProto.PENDING_IDLE_UNTIL, nowElapsed); 3587 } 3588 if (mNextWakeFromIdle != null) { 3589 mNextWakeFromIdle.dumpDebug(proto, AlarmManagerServiceDumpProto.NEXT_WAKE_FROM_IDLE, 3590 nowElapsed); 3591 } 3592 3593 for (Alarm a : mPendingNonWakeupAlarms) { 3594 a.dumpDebug(proto, AlarmManagerServiceDumpProto.PAST_DUE_NON_WAKEUP_ALARMS, 3595 nowElapsed); 3596 } 3597 3598 proto.write(AlarmManagerServiceDumpProto.DELAYED_ALARM_COUNT, mNumDelayedAlarms); 3599 proto.write(AlarmManagerServiceDumpProto.TOTAL_DELAY_TIME_MS, mTotalDelayTime); 3600 proto.write(AlarmManagerServiceDumpProto.MAX_DELAY_DURATION_MS, mMaxDelayTime); 3601 proto.write(AlarmManagerServiceDumpProto.MAX_NON_INTERACTIVE_DURATION_MS, 3602 mNonInteractiveTime); 3603 3604 proto.write(AlarmManagerServiceDumpProto.BROADCAST_REF_COUNT, mBroadcastRefCount); 3605 proto.write(AlarmManagerServiceDumpProto.PENDING_INTENT_SEND_COUNT, mSendCount); 3606 proto.write(AlarmManagerServiceDumpProto.PENDING_INTENT_FINISH_COUNT, mSendFinishCount); 3607 proto.write(AlarmManagerServiceDumpProto.LISTENER_SEND_COUNT, mListenerCount); 3608 proto.write(AlarmManagerServiceDumpProto.LISTENER_FINISH_COUNT, mListenerFinishCount); 3609 3610 for (InFlight f : mInFlight) { 3611 f.dumpDebug(proto, AlarmManagerServiceDumpProto.OUTSTANDING_DELIVERIES); 3612 } 3613 3614 mLog.dumpDebug(proto, AlarmManagerServiceDumpProto.RECENT_PROBLEMS); 3615 3616 final FilterStats[] topFilters = new FilterStats[10]; 3617 final Comparator<FilterStats> comparator = new Comparator<FilterStats>() { 3618 @Override 3619 public int compare(FilterStats lhs, FilterStats rhs) { 3620 if (lhs.aggregateTime < rhs.aggregateTime) { 3621 return 1; 3622 } else if (lhs.aggregateTime > rhs.aggregateTime) { 3623 return -1; 3624 } 3625 return 0; 3626 } 3627 }; 3628 int len = 0; 3629 // Get the top 10 FilterStats, ordered by aggregateTime. 3630 for (int iu = 0; iu < mBroadcastStats.size(); ++iu) { 3631 ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(iu); 3632 for (int ip = 0; ip < uidStats.size(); ++ip) { 3633 BroadcastStats bs = uidStats.valueAt(ip); 3634 for (int is = 0; is < bs.filterStats.size(); ++is) { 3635 FilterStats fs = bs.filterStats.valueAt(is); 3636 int pos = len > 0 3637 ? Arrays.binarySearch(topFilters, 0, len, fs, comparator) : 0; 3638 if (pos < 0) { 3639 pos = -pos - 1; 3640 } 3641 if (pos < topFilters.length) { 3642 int copylen = topFilters.length - pos - 1; 3643 if (copylen > 0) { 3644 System.arraycopy(topFilters, pos, topFilters, pos + 1, copylen); 3645 } 3646 topFilters[pos] = fs; 3647 if (len < topFilters.length) { 3648 len++; 3649 } 3650 } 3651 } 3652 } 3653 } 3654 for (int i = 0; i < len; ++i) { 3655 final long token = proto.start(AlarmManagerServiceDumpProto.TOP_ALARMS); 3656 FilterStats fs = topFilters[i]; 3657 3658 proto.write(AlarmManagerServiceDumpProto.TopAlarm.UID, fs.mBroadcastStats.mUid); 3659 proto.write(AlarmManagerServiceDumpProto.TopAlarm.PACKAGE_NAME, 3660 fs.mBroadcastStats.mPackageName); 3661 fs.dumpDebug(proto, AlarmManagerServiceDumpProto.TopAlarm.FILTER); 3662 3663 proto.end(token); 3664 } 3665 3666 final ArrayList<FilterStats> tmpFilters = new ArrayList<FilterStats>(); 3667 for (int iu = 0; iu < mBroadcastStats.size(); ++iu) { 3668 ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(iu); 3669 for (int ip = 0; ip < uidStats.size(); ++ip) { 3670 final long token = proto.start(AlarmManagerServiceDumpProto.ALARM_STATS); 3671 3672 BroadcastStats bs = uidStats.valueAt(ip); 3673 bs.dumpDebug(proto, AlarmManagerServiceDumpProto.AlarmStat.BROADCAST); 3674 3675 // uidStats is an ArrayMap, which we can't sort. 3676 tmpFilters.clear(); 3677 for (int is = 0; is < bs.filterStats.size(); ++is) { 3678 tmpFilters.add(bs.filterStats.valueAt(is)); 3679 } 3680 Collections.sort(tmpFilters, comparator); 3681 for (FilterStats fs : tmpFilters) { 3682 fs.dumpDebug(proto, AlarmManagerServiceDumpProto.AlarmStat.FILTERS); 3683 } 3684 3685 proto.end(token); 3686 } 3687 } 3688 3689 if (RECORD_DEVICE_IDLE_ALARMS) { 3690 for (int i = 0; i < mAllowWhileIdleDispatches.size(); i++) { 3691 IdleDispatchEntry ent = mAllowWhileIdleDispatches.get(i); 3692 final long token = proto.start( 3693 AlarmManagerServiceDumpProto.ALLOW_WHILE_IDLE_DISPATCHES); 3694 3695 proto.write(IdleDispatchEntryProto.UID, ent.uid); 3696 proto.write(IdleDispatchEntryProto.PKG, ent.pkg); 3697 proto.write(IdleDispatchEntryProto.TAG, ent.tag); 3698 proto.write(IdleDispatchEntryProto.OP, ent.op); 3699 proto.write(IdleDispatchEntryProto.ENTRY_CREATION_REALTIME, 3700 ent.elapsedRealtime); 3701 proto.write(IdleDispatchEntryProto.ARG_REALTIME, ent.argRealtime); 3702 3703 proto.end(token); 3704 } 3705 } 3706 } 3707 3708 proto.flush(); 3709 } 3710 getNextWakeFromIdleTimeImpl()3711 long getNextWakeFromIdleTimeImpl() { 3712 synchronized (mLock) { 3713 return mNextWakeFromIdle != null ? mNextWakeFromIdle.getWhenElapsed() : Long.MAX_VALUE; 3714 } 3715 } 3716 isIdlingImpl()3717 private boolean isIdlingImpl() { 3718 synchronized (mLock) { 3719 return mPendingIdleUntil != null; 3720 } 3721 } 3722 getNextAlarmClockImpl(int userId)3723 AlarmManager.AlarmClockInfo getNextAlarmClockImpl(int userId) { 3724 synchronized (mLock) { 3725 return mNextAlarmClockForUser.get(userId); 3726 } 3727 } 3728 3729 /** 3730 * Recomputes the next alarm clock for all users. 3731 */ updateNextAlarmClockLocked()3732 private void updateNextAlarmClockLocked() { 3733 if (!mNextAlarmClockMayChange) { 3734 return; 3735 } 3736 mNextAlarmClockMayChange = false; 3737 3738 final SparseArray<AlarmManager.AlarmClockInfo> nextForUser = mTmpSparseAlarmClockArray; 3739 nextForUser.clear(); 3740 3741 final ArrayList<Alarm> allAlarms = mAlarmStore.asList(); 3742 for (final Alarm a : allAlarms) { 3743 if (a.alarmClock != null) { 3744 final int userId = UserHandle.getUserId(a.uid); 3745 final AlarmManager.AlarmClockInfo current = mNextAlarmClockForUser.get(userId); 3746 3747 if (DEBUG_ALARM_CLOCK) { 3748 Log.v(TAG, "Found AlarmClockInfo " + a.alarmClock + " at " 3749 + formatNextAlarm(getContext(), a.alarmClock, userId) 3750 + " for user " + userId); 3751 } 3752 3753 // AlarmClocks are sorted by time, so no need to compare times here. 3754 if (nextForUser.get(userId) == null) { 3755 nextForUser.put(userId, a.alarmClock); 3756 } else if (a.alarmClock.equals(current) 3757 && current.getTriggerTime() <= nextForUser.get(userId).getTriggerTime()) { 3758 // same/earlier time and it's the one we cited before, so stick with it 3759 nextForUser.put(userId, current); 3760 } 3761 } 3762 } 3763 3764 final int newUserCount = nextForUser.size(); 3765 for (int i = 0; i < newUserCount; i++) { 3766 AlarmManager.AlarmClockInfo newAlarm = nextForUser.valueAt(i); 3767 int userId = nextForUser.keyAt(i); 3768 AlarmManager.AlarmClockInfo currentAlarm = mNextAlarmClockForUser.get(userId); 3769 if (!newAlarm.equals(currentAlarm)) { 3770 updateNextAlarmInfoForUserLocked(userId, newAlarm); 3771 } 3772 } 3773 3774 final int oldUserCount = mNextAlarmClockForUser.size(); 3775 for (int i = oldUserCount - 1; i >= 0; i--) { 3776 int userId = mNextAlarmClockForUser.keyAt(i); 3777 if (nextForUser.get(userId) == null) { 3778 updateNextAlarmInfoForUserLocked(userId, null); 3779 } 3780 } 3781 } 3782 updateNextAlarmInfoForUserLocked(int userId, AlarmManager.AlarmClockInfo alarmClock)3783 private void updateNextAlarmInfoForUserLocked(int userId, 3784 AlarmManager.AlarmClockInfo alarmClock) { 3785 if (alarmClock != null) { 3786 if (DEBUG_ALARM_CLOCK) { 3787 Log.v(TAG, "Next AlarmClockInfoForUser(" + userId + "): " + 3788 formatNextAlarm(getContext(), alarmClock, userId)); 3789 } 3790 mNextAlarmClockForUser.put(userId, alarmClock); 3791 if (mStartUserBeforeScheduledAlarms) { 3792 mUserWakeupStore.addUserWakeup(userId, convertToElapsed( 3793 mNextAlarmClockForUser.get(userId).getTriggerTime(), RTC)); 3794 } 3795 } else { 3796 if (DEBUG_ALARM_CLOCK) { 3797 Log.v(TAG, "Next AlarmClockInfoForUser(" + userId + "): None"); 3798 } 3799 if (mStartUserBeforeScheduledAlarms) { 3800 if (mActivityManagerInternal.isUserRunning(userId, 0)) { 3801 mUserWakeupStore.removeUserWakeup(userId); 3802 } 3803 } 3804 mNextAlarmClockForUser.remove(userId); 3805 } 3806 3807 mPendingSendNextAlarmClockChangedForUser.put(userId, true); 3808 mHandler.removeMessages(AlarmHandler.SEND_NEXT_ALARM_CLOCK_CHANGED); 3809 mHandler.sendEmptyMessage(AlarmHandler.SEND_NEXT_ALARM_CLOCK_CHANGED); 3810 } 3811 3812 /** 3813 * Updates NEXT_ALARM_FORMATTED and sends NEXT_ALARM_CLOCK_CHANGED_INTENT for all users 3814 * for which alarm clocks have changed since the last call to this. 3815 * 3816 * Do not call with a lock held. Only call from mHandler's thread. 3817 * 3818 * @see AlarmHandler#SEND_NEXT_ALARM_CLOCK_CHANGED 3819 */ sendNextAlarmClockChanged()3820 private void sendNextAlarmClockChanged() { 3821 SparseArray<AlarmManager.AlarmClockInfo> pendingUsers = mHandlerSparseAlarmClockArray; 3822 pendingUsers.clear(); 3823 3824 synchronized (mLock) { 3825 final int n = mPendingSendNextAlarmClockChangedForUser.size(); 3826 for (int i = 0; i < n; i++) { 3827 int userId = mPendingSendNextAlarmClockChangedForUser.keyAt(i); 3828 pendingUsers.append(userId, mNextAlarmClockForUser.get(userId)); 3829 } 3830 mPendingSendNextAlarmClockChangedForUser.clear(); 3831 } 3832 3833 final int n = pendingUsers.size(); 3834 for (int i = 0; i < n; i++) { 3835 int userId = pendingUsers.keyAt(i); 3836 AlarmManager.AlarmClockInfo alarmClock = pendingUsers.valueAt(i); 3837 Settings.System.putStringForUser(getContext().getContentResolver(), 3838 Settings.System.NEXT_ALARM_FORMATTED, 3839 formatNextAlarm(getContext(), alarmClock, userId), 3840 userId); 3841 3842 getContext().sendBroadcastAsUser(NEXT_ALARM_CLOCK_CHANGED_INTENT, 3843 new UserHandle(userId)); 3844 } 3845 } 3846 3847 /** 3848 * Formats an alarm like platform/packages/apps/DeskClock used to. 3849 */ formatNextAlarm(final Context context, AlarmManager.AlarmClockInfo info, int userId)3850 private static String formatNextAlarm(final Context context, AlarmManager.AlarmClockInfo info, 3851 int userId) { 3852 String skeleton = DateFormat.is24HourFormat(context, userId) ? "EHm" : "Ehma"; 3853 String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton); 3854 return (info == null) ? "" : 3855 DateFormat.format(pattern, info.getTriggerTime()).toString(); 3856 } 3857 3858 @GuardedBy("mLock") rescheduleKernelAlarmsLocked()3859 void rescheduleKernelAlarmsLocked() { 3860 // Schedule the next upcoming wakeup alarm. If there is a deliverable batch 3861 // prior to that which contains no wakeups, we schedule that as well. 3862 final long nowElapsed = mInjector.getElapsedRealtimeMillis(); 3863 long nextNonWakeup = 0; 3864 if (mAlarmStore.size() > 0) { 3865 long firstWakeup = mAlarmStore.getNextWakeupDeliveryTime(); 3866 if (mStartUserBeforeScheduledAlarms && mUserWakeupStore != null) { 3867 final long firstUserWakeup = mUserWakeupStore.getNextWakeupTime(); 3868 if (firstUserWakeup >= 0 && firstUserWakeup < firstWakeup) { 3869 firstWakeup = firstUserWakeup; 3870 } 3871 } 3872 final long first = mAlarmStore.getNextDeliveryTime(); 3873 if (firstWakeup != 0) { 3874 mNextWakeup = firstWakeup; 3875 mNextWakeUpSetAt = nowElapsed; 3876 setLocked(ELAPSED_REALTIME_WAKEUP, firstWakeup); 3877 } 3878 if (first != firstWakeup) { 3879 nextNonWakeup = first; 3880 } 3881 } 3882 if (mPendingNonWakeupAlarms.size() > 0) { 3883 if (nextNonWakeup == 0 || mNextNonWakeupDeliveryTime < nextNonWakeup) { 3884 nextNonWakeup = mNextNonWakeupDeliveryTime; 3885 } 3886 } 3887 if (nextNonWakeup != 0) { 3888 mNextNonWakeup = nextNonWakeup; 3889 mNextNonWakeUpSetAt = nowElapsed; 3890 setLocked(ELAPSED_REALTIME, nextNonWakeup); 3891 } 3892 } 3893 3894 /** 3895 * Called when an app loses the permission to use exact alarms. This will happen when the app 3896 * no longer has either {@link Manifest.permission#SCHEDULE_EXACT_ALARM} or 3897 * {@link Manifest.permission#USE_EXACT_ALARM}. 3898 * 3899 * This is not expected to get called frequently. 3900 */ removeExactAlarmsOnPermissionRevoked(int uid, String packageName, boolean killUid)3901 void removeExactAlarmsOnPermissionRevoked(int uid, String packageName, boolean killUid) { 3902 if (isExemptFromExactAlarmPermissionNoLock(uid) 3903 || !isExactAlarmChangeEnabled(packageName, UserHandle.getUserId(uid))) { 3904 return; 3905 } 3906 Slog.w(TAG, "Package " + packageName + ", uid " + uid 3907 + " lost permission to set exact alarms!"); 3908 3909 final Predicate<Alarm> whichAlarms = a -> (a.uid == uid && a.packageName.equals(packageName) 3910 && a.windowLength == 0); 3911 synchronized (mLock) { 3912 removeAlarmsInternalLocked(whichAlarms, REMOVE_REASON_EXACT_PERMISSION_REVOKED); 3913 } 3914 3915 if (killUid) { 3916 PermissionManagerService.killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid), 3917 "schedule_exact_alarm revoked"); 3918 } 3919 } 3920 3921 @GuardedBy("mLock") removeAlarmsInternalLocked(Predicate<Alarm> whichAlarms, int reason)3922 private void removeAlarmsInternalLocked(Predicate<Alarm> whichAlarms, int reason) { 3923 final long nowRtc = mInjector.getCurrentTimeMillis(); 3924 final long nowElapsed = mInjector.getElapsedRealtimeMillis(); 3925 3926 final ArrayList<Alarm> removedAlarms = mAlarmStore.remove(whichAlarms); 3927 final boolean removedFromStore = !removedAlarms.isEmpty(); 3928 3929 for (int i = mPendingBackgroundAlarms.size() - 1; i >= 0; i--) { 3930 final ArrayList<Alarm> alarmsForUid = mPendingBackgroundAlarms.valueAt(i); 3931 for (int j = alarmsForUid.size() - 1; j >= 0; j--) { 3932 final Alarm alarm = alarmsForUid.get(j); 3933 if (whichAlarms.test(alarm)) { 3934 removedAlarms.add(alarmsForUid.remove(j)); 3935 } 3936 } 3937 if (alarmsForUid.size() == 0) { 3938 mPendingBackgroundAlarms.removeAt(i); 3939 } 3940 } 3941 for (int i = mPendingNonWakeupAlarms.size() - 1; i >= 0; i--) { 3942 final Alarm a = mPendingNonWakeupAlarms.get(i); 3943 if (whichAlarms.test(a)) { 3944 removedAlarms.add(mPendingNonWakeupAlarms.remove(i)); 3945 } 3946 } 3947 3948 for (final Alarm removed : removedAlarms) { 3949 decrementAlarmCount(removed.uid, 1); 3950 if (removed.listener != null) { 3951 removed.listener.asBinder().unlinkToDeath(mListenerDeathRecipient, 0); 3952 } 3953 if (!RemovedAlarm.isLoggable(reason)) { 3954 continue; 3955 } 3956 RingBuffer<RemovedAlarm> bufferForUid = mRemovalHistory.get(removed.uid); 3957 if (bufferForUid == null) { 3958 bufferForUid = new RingBuffer<>(RemovedAlarm.class, REMOVAL_HISTORY_SIZE_PER_UID); 3959 mRemovalHistory.put(removed.uid, bufferForUid); 3960 } 3961 bufferForUid.append(new RemovedAlarm(removed, reason, nowRtc, nowElapsed)); 3962 } 3963 3964 if (removedFromStore) { 3965 boolean idleUntilUpdated = false; 3966 if (mPendingIdleUntil != null && whichAlarms.test(mPendingIdleUntil)) { 3967 mPendingIdleUntil = null; 3968 idleUntilUpdated = true; 3969 } 3970 if (mNextWakeFromIdle != null && whichAlarms.test(mNextWakeFromIdle)) { 3971 mNextWakeFromIdle = mAlarmStore.getNextWakeFromIdleAlarm(); 3972 if (mPendingIdleUntil != null) { 3973 idleUntilUpdated |= mAlarmStore.updateAlarmDeliveries(alarm -> 3974 (alarm == mPendingIdleUntil && adjustIdleUntilTime(alarm))); 3975 } 3976 } 3977 if (idleUntilUpdated) { 3978 mAlarmStore.updateAlarmDeliveries( 3979 alarm -> adjustDeliveryTimeBasedOnDeviceIdle(alarm)); 3980 } 3981 rescheduleKernelAlarmsLocked(); 3982 updateNextAlarmClockLocked(); 3983 } 3984 } 3985 3986 @GuardedBy("mLock") removeLocked(PendingIntent operation, IAlarmListener directReceiver, int reason)3987 void removeLocked(PendingIntent operation, IAlarmListener directReceiver, int reason) { 3988 if (operation == null && directReceiver == null) { 3989 if (localLOGV) { 3990 Slog.w(TAG, "requested remove() of null operation", 3991 new RuntimeException("here")); 3992 } 3993 return; 3994 } 3995 removeAlarmsInternalLocked(a -> a.matches(operation, directReceiver), reason); 3996 } 3997 3998 @GuardedBy("mLock") removeLocked(final int uid, int reason)3999 void removeLocked(final int uid, int reason) { 4000 if (uid == Process.SYSTEM_UID) { 4001 // If a force-stop occurs for a system-uid package, ignore it. 4002 return; 4003 } 4004 removeAlarmsInternalLocked(a -> a.uid == uid, reason); 4005 } 4006 4007 @GuardedBy("mLock") removeLocked(final String packageName, int reason)4008 void removeLocked(final String packageName, int reason) { 4009 if (packageName == null) { 4010 if (localLOGV) { 4011 Slog.w(TAG, "requested remove() of null packageName", 4012 new RuntimeException("here")); 4013 } 4014 return; 4015 } 4016 removeAlarmsInternalLocked(a -> a.matches(packageName), reason); 4017 } 4018 4019 // Only called for ephemeral apps 4020 @GuardedBy("mLock") removeForStoppedLocked(final int uid)4021 void removeForStoppedLocked(final int uid) { 4022 if (uid == Process.SYSTEM_UID) { 4023 // If a force-stop occurs for a system-uid package, ignore it. 4024 return; 4025 } 4026 final Predicate<Alarm> whichAlarms = (a) -> (a.uid == uid 4027 && mActivityManagerInternal.isAppStartModeDisabled(uid, a.packageName)); 4028 removeAlarmsInternalLocked(whichAlarms, REMOVE_REASON_UNDEFINED); 4029 } 4030 4031 @GuardedBy("mLock") removeUserLocked(int userHandle)4032 void removeUserLocked(int userHandle) { 4033 if (userHandle == USER_SYSTEM) { 4034 Slog.w(TAG, "Ignoring attempt to remove system-user state!"); 4035 return; 4036 } 4037 final Predicate<Alarm> whichAlarms = 4038 (Alarm a) -> UserHandle.getUserId(a.uid) == userHandle; 4039 removeAlarmsInternalLocked(whichAlarms, REMOVE_REASON_UNDEFINED); 4040 4041 for (int i = mLastPriorityAlarmDispatch.size() - 1; i >= 0; i--) { 4042 if (UserHandle.getUserId(mLastPriorityAlarmDispatch.keyAt(i)) == userHandle) { 4043 mLastPriorityAlarmDispatch.removeAt(i); 4044 } 4045 } 4046 for (int i = mRemovalHistory.size() - 1; i >= 0; i--) { 4047 if (UserHandle.getUserId(mRemovalHistory.keyAt(i)) == userHandle) { 4048 mRemovalHistory.removeAt(i); 4049 } 4050 } 4051 for (int i = mLastOpScheduleExactAlarm.size() - 1; i >= 0; i--) { 4052 if (UserHandle.getUserId(mLastOpScheduleExactAlarm.keyAt(i)) == userHandle) { 4053 mLastOpScheduleExactAlarm.removeAt(i); 4054 } 4055 } 4056 } 4057 4058 @GuardedBy("mLock") interactiveStateChangedLocked(boolean interactive)4059 void interactiveStateChangedLocked(boolean interactive) { 4060 if (mInteractive != interactive) { 4061 mInteractive = interactive; 4062 final long nowELAPSED = mInjector.getElapsedRealtimeMillis(); 4063 if (interactive) { 4064 if (mPendingNonWakeupAlarms.size() > 0) { 4065 final long thisDelayTime = nowELAPSED - mStartCurrentDelayTime; 4066 mTotalDelayTime += thisDelayTime; 4067 if (mMaxDelayTime < thisDelayTime) { 4068 mMaxDelayTime = thisDelayTime; 4069 } 4070 final ArrayList<Alarm> triggerList = new ArrayList<>(mPendingNonWakeupAlarms); 4071 deliverAlarmsLocked(triggerList, nowELAPSED); 4072 mPendingNonWakeupAlarms.clear(); 4073 } 4074 if (mNonInteractiveStartTime > 0) { 4075 long dur = nowELAPSED - mNonInteractiveStartTime; 4076 if (dur > mNonInteractiveTime) { 4077 mNonInteractiveTime = dur; 4078 } 4079 } 4080 // And send a TIME_TICK right now, since it is important to get the UI updated. 4081 mHandler.post(() -> getContext().sendBroadcastAsUser(mTimeTickIntent, 4082 UserHandle.ALL, null, mTimeTickOptions)); 4083 } else { 4084 mNonInteractiveStartTime = nowELAPSED; 4085 } 4086 } 4087 } 4088 4089 @GuardedBy("mLock") lookForPackageLocked(String packageName, int uid)4090 boolean lookForPackageLocked(String packageName, int uid) { 4091 // This is called extremely rarely, e.g. when the user opens the force-stop page in settings 4092 // so the loops using an iterator should be fine. 4093 for (final Alarm alarm : mAlarmStore.asList()) { 4094 if (alarm.matches(packageName) && alarm.creatorUid == uid) { 4095 return true; 4096 } 4097 } 4098 final ArrayList<Alarm> alarmsForUid = mPendingBackgroundAlarms.get(uid); 4099 if (alarmsForUid != null) { 4100 for (final Alarm alarm : alarmsForUid) { 4101 if (alarm.matches(packageName)) { 4102 return true; 4103 } 4104 } 4105 } 4106 for (final Alarm alarm : mPendingNonWakeupAlarms) { 4107 if (alarm.matches(packageName) && alarm.creatorUid == uid) { 4108 return true; 4109 } 4110 } 4111 return false; 4112 } 4113 setLocked(int type, long when)4114 private void setLocked(int type, long when) { 4115 if (mInjector.isAlarmDriverPresent()) { 4116 mInjector.setAlarm(type, when); 4117 } else { 4118 Message msg = Message.obtain(); 4119 msg.what = AlarmHandler.ALARM_EVENT; 4120 4121 mHandler.removeMessages(msg.what); 4122 mHandler.sendMessageAtTime(msg, when); 4123 } 4124 } 4125 dumpAlarmList(IndentingPrintWriter ipw, ArrayList<Alarm> list, long nowELAPSED, SimpleDateFormat sdf)4126 static final void dumpAlarmList(IndentingPrintWriter ipw, ArrayList<Alarm> list, 4127 long nowELAPSED, SimpleDateFormat sdf) { 4128 final int n = list.size(); 4129 for (int i = n - 1; i >= 0; i--) { 4130 final Alarm a = list.get(i); 4131 final String label = Alarm.typeToString(a.type); 4132 ipw.print(label); 4133 ipw.print(" #"); 4134 ipw.print(n - i); 4135 ipw.print(": "); 4136 ipw.println(a); 4137 ipw.increaseIndent(); 4138 a.dump(ipw, nowELAPSED, sdf); 4139 ipw.decreaseIndent(); 4140 } 4141 } 4142 isExemptFromBatterySaver(Alarm alarm)4143 private static boolean isExemptFromBatterySaver(Alarm alarm) { 4144 if (alarm.alarmClock != null) { 4145 return true; 4146 } 4147 if ((alarm.operation != null) 4148 && (alarm.operation.isActivity() || alarm.operation.isForegroundService())) { 4149 return true; 4150 } 4151 if (UserHandle.isCore(alarm.creatorUid)) { 4152 return true; 4153 } 4154 return false; 4155 } 4156 isBackgroundRestricted(Alarm alarm)4157 private boolean isBackgroundRestricted(Alarm alarm) { 4158 if (alarm.alarmClock != null) { 4159 // Don't defer alarm clocks 4160 return false; 4161 } 4162 if (alarm.operation != null && alarm.operation.isActivity()) { 4163 // Don't defer starting actual UI 4164 return false; 4165 } 4166 final String sourcePackage = alarm.sourcePackage; 4167 final int sourceUid = alarm.creatorUid; 4168 if (UserHandle.isCore(sourceUid)) { 4169 return false; 4170 } 4171 return (mAppStateTracker != null) && mAppStateTracker.areAlarmsRestricted(sourceUid, 4172 sourcePackage); 4173 } 4174 init()4175 private static native long init(); close(long nativeData)4176 private static native void close(long nativeData); set(long nativeData, int type, long seconds, long nanoseconds)4177 private static native int set(long nativeData, int type, long seconds, long nanoseconds); waitForAlarm(long nativeData)4178 private static native int waitForAlarm(long nativeData); getNextAlarm(long nativeData, int type)4179 private static native long getNextAlarm(long nativeData, int type); 4180 4181 @GuardedBy("mLock") triggerAlarmsLocked(ArrayList<Alarm> triggerList, final long nowELAPSED)4182 int triggerAlarmsLocked(ArrayList<Alarm> triggerList, final long nowELAPSED) { 4183 int wakeUps = 0; 4184 final ArrayList<Alarm> pendingAlarms = mAlarmStore.removePendingAlarms(nowELAPSED); 4185 for (final Alarm alarm : pendingAlarms) { 4186 if (isBackgroundRestricted(alarm)) { 4187 // Alarms with FLAG_WAKE_FROM_IDLE or mPendingIdleUntil alarm are not deferred 4188 if (DEBUG_BG_LIMIT) { 4189 Slog.d(TAG, "Deferring alarm " + alarm + " due to user forced app standby"); 4190 } 4191 ArrayList<Alarm> alarmsForUid = mPendingBackgroundAlarms.get(alarm.creatorUid); 4192 if (alarmsForUid == null) { 4193 alarmsForUid = new ArrayList<>(); 4194 mPendingBackgroundAlarms.put(alarm.creatorUid, alarmsForUid); 4195 } 4196 alarmsForUid.add(alarm); 4197 continue; 4198 } 4199 4200 alarm.count = 1; 4201 triggerList.add(alarm); 4202 if ((alarm.flags & FLAG_WAKE_FROM_IDLE) != 0) { 4203 EventLogTags.writeDeviceIdleWakeFromIdle(mPendingIdleUntil != null ? 1 : 0, 4204 alarm.statsTag); 4205 } 4206 if (mPendingIdleUntil == alarm) { 4207 mPendingIdleUntil = null; 4208 mAlarmStore.updateAlarmDeliveries(a -> adjustDeliveryTimeBasedOnDeviceIdle(a)); 4209 if (RECORD_DEVICE_IDLE_ALARMS) { 4210 IdleDispatchEntry ent = new IdleDispatchEntry(); 4211 ent.uid = alarm.uid; 4212 ent.pkg = alarm.sourcePackage; 4213 ent.tag = alarm.statsTag; 4214 ent.op = "END IDLE"; 4215 ent.elapsedRealtime = mInjector.getElapsedRealtimeMillis(); 4216 ent.argRealtime = alarm.getWhenElapsed(); 4217 mAllowWhileIdleDispatches.add(ent); 4218 } 4219 } 4220 if (mNextWakeFromIdle == alarm) { 4221 mNextWakeFromIdle = mAlarmStore.getNextWakeFromIdleAlarm(); 4222 // Note that we don't need to update mPendingIdleUntil because it should already 4223 // be removed from the alarm store. 4224 } 4225 4226 // Recurring alarms may have passed several alarm intervals while the 4227 // phone was asleep or off, so pass a trigger count when sending them. 4228 if (alarm.repeatInterval > 0) { 4229 // this adjustment will be zero if we're late by 4230 // less than one full repeat interval 4231 alarm.count += (nowELAPSED - alarm.getRequestedElapsed()) / alarm.repeatInterval; 4232 // Also schedule its next recurrence 4233 final long delta = alarm.count * alarm.repeatInterval; 4234 final long nextElapsed = alarm.getRequestedElapsed() + delta; 4235 final long nextMaxElapsed = maxTriggerTime(nowELAPSED, nextElapsed, 4236 alarm.repeatInterval); 4237 setImplLocked(alarm.type, alarm.origWhen + delta, nextElapsed, 4238 nextMaxElapsed - nextElapsed, alarm.repeatInterval, alarm.operation, null, 4239 null, alarm.flags, alarm.workSource, alarm.alarmClock, alarm.uid, 4240 alarm.packageName, null, EXACT_ALLOW_REASON_NOT_APPLICABLE); 4241 } 4242 4243 if (alarm.wakeup) { 4244 wakeUps++; 4245 } 4246 4247 // We removed an alarm clock. Let the caller recompute the next alarm clock. 4248 if (alarm.alarmClock != null) { 4249 mNextAlarmClockMayChange = true; 4250 } 4251 } 4252 4253 calculateDeliveryPriorities(triggerList); 4254 Collections.sort(triggerList, mAlarmDispatchComparator); 4255 4256 if (localLOGV) { 4257 for (int i = 0; i < triggerList.size(); i++) { 4258 Slog.v(TAG, "Triggering alarm #" + i + ": " + triggerList.get(i)); 4259 } 4260 } 4261 4262 return wakeUps; 4263 } 4264 currentNonWakeupFuzzLocked(long nowELAPSED)4265 long currentNonWakeupFuzzLocked(long nowELAPSED) { 4266 long timeSinceOn = nowELAPSED - mNonInteractiveStartTime; 4267 if (timeSinceOn < 5 * 60 * 1000) { 4268 // If the screen has been off for 5 minutes, only delay by at most two minutes. 4269 return 2 * 60 * 1000; 4270 } else if (timeSinceOn < 30 * 60 * 1000) { 4271 // If the screen has been off for 30 minutes, only delay by at most 15 minutes. 4272 return 15 * 60 * 1000; 4273 } else { 4274 // Otherwise, we will delay by at most an hour. 4275 return 60 * 60 * 1000; 4276 } 4277 } 4278 4279 @GuardedBy("mLock") checkAllowNonWakeupDelayLocked(long nowELAPSED)4280 boolean checkAllowNonWakeupDelayLocked(long nowELAPSED) { 4281 if (!mConstants.DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF) { 4282 return false; 4283 } 4284 if (mInteractive) { 4285 return false; 4286 } 4287 if (mLastAlarmDeliveryTime <= 0) { 4288 return false; 4289 } 4290 if (mPendingNonWakeupAlarms.size() > 0 && mNextNonWakeupDeliveryTime < nowELAPSED) { 4291 // This is just a little paranoia, if somehow we have pending non-wakeup alarms 4292 // and the next delivery time is in the past, then just deliver them all. This 4293 // avoids bugs where we get stuck in a loop trying to poll for alarms. 4294 return false; 4295 } 4296 long timeSinceLast = nowELAPSED - mLastAlarmDeliveryTime; 4297 return timeSinceLast <= currentNonWakeupFuzzLocked(nowELAPSED); 4298 } 4299 4300 @GuardedBy("mLock") deliverAlarmsLocked(ArrayList<Alarm> triggerList, long nowELAPSED)4301 void deliverAlarmsLocked(ArrayList<Alarm> triggerList, long nowELAPSED) { 4302 mLastAlarmDeliveryTime = nowELAPSED; 4303 for (int i = 0; i < triggerList.size(); i++) { 4304 Alarm alarm = triggerList.get(i); 4305 if (alarm.wakeup) { 4306 Trace.traceBegin(Trace.TRACE_TAG_POWER, 4307 "Dispatch wakeup alarm to " + alarm.packageName); 4308 } else { 4309 Trace.traceBegin(Trace.TRACE_TAG_POWER, 4310 "Dispatch non-wakeup alarm to " + alarm.packageName); 4311 } 4312 try { 4313 if (localLOGV) { 4314 Slog.v(TAG, "sending alarm " + alarm); 4315 } 4316 if (RECORD_ALARMS_IN_HISTORY) { 4317 mActivityManagerInternal.noteAlarmStart(alarm.operation, alarm.workSource, 4318 alarm.uid, alarm.statsTag); 4319 } 4320 mDeliveryTracker.deliverLocked(alarm, nowELAPSED); 4321 } catch (RuntimeException e) { 4322 Slog.w(TAG, "Failure sending alarm.", e); 4323 } 4324 Trace.traceEnd(Trace.TRACE_TAG_POWER); 4325 decrementAlarmCount(alarm.uid, 1); 4326 } 4327 } 4328 4329 @VisibleForTesting isExemptFromAppStandby(Alarm a)4330 static boolean isExemptFromAppStandby(Alarm a) { 4331 return a.alarmClock != null || UserHandle.isCore(a.creatorUid) 4332 || (a.flags & (FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED | FLAG_ALLOW_WHILE_IDLE)) != 0; 4333 } 4334 4335 @VisibleForTesting 4336 static class Injector { 4337 private long mNativeData; 4338 private Context mContext; 4339 Injector(Context context)4340 Injector(Context context) { 4341 mContext = context; 4342 } 4343 init()4344 void init() { 4345 System.loadLibrary("alarm_jni"); 4346 mNativeData = AlarmManagerService.init(); 4347 } 4348 waitForAlarm()4349 int waitForAlarm() { 4350 return AlarmManagerService.waitForAlarm(mNativeData); 4351 } 4352 isAlarmDriverPresent()4353 boolean isAlarmDriverPresent() { 4354 return mNativeData != 0; 4355 } 4356 setAlarm(int type, long millis)4357 void setAlarm(int type, long millis) { 4358 // The kernel never triggers alarms with negative wakeup times 4359 // so we ensure they are positive. 4360 final long alarmSeconds, alarmNanoseconds; 4361 if (millis < 0) { 4362 alarmSeconds = 0; 4363 alarmNanoseconds = 0; 4364 } else { 4365 alarmSeconds = millis / 1000; 4366 alarmNanoseconds = (millis % 1000) * 1000 * 1000; 4367 } 4368 4369 final int result = AlarmManagerService.set(mNativeData, type, alarmSeconds, 4370 alarmNanoseconds); 4371 if (result != 0) { 4372 final long nowElapsed = SystemClock.elapsedRealtime(); 4373 Slog.wtf(TAG, "Unable to set kernel alarm, now=" + nowElapsed 4374 + " type=" + type + " @ (" + alarmSeconds + "," + alarmNanoseconds 4375 + "), ret = " + result + " = " + Os.strerror(result)); 4376 } 4377 } 4378 getCallingUid()4379 int getCallingUid() { 4380 return Binder.getCallingUid(); 4381 } 4382 getNextAlarm(int type)4383 long getNextAlarm(int type) { 4384 return AlarmManagerService.getNextAlarm(mNativeData, type); 4385 } 4386 initializeTimeIfRequired()4387 void initializeTimeIfRequired() { 4388 SystemClockTime.initializeIfRequired(); 4389 } 4390 setCurrentTimeMillis( @urrentTimeMillisLong long unixEpochMillis, @TimeConfidence int confidence, @NonNull String logMsg)4391 void setCurrentTimeMillis( 4392 @CurrentTimeMillisLong long unixEpochMillis, 4393 @TimeConfidence int confidence, 4394 @NonNull String logMsg) { 4395 SystemClockTime.setTimeAndConfidence(unixEpochMillis, confidence, logMsg); 4396 } 4397 close()4398 void close() { 4399 AlarmManagerService.close(mNativeData); 4400 } 4401 4402 @ElapsedRealtimeLong getElapsedRealtimeMillis()4403 long getElapsedRealtimeMillis() { 4404 return SystemClock.elapsedRealtime(); 4405 } 4406 4407 @CurrentTimeMillisLong getCurrentTimeMillis()4408 long getCurrentTimeMillis() { 4409 return System.currentTimeMillis(); 4410 } 4411 getAlarmWakeLock()4412 PowerManager.WakeLock getAlarmWakeLock() { 4413 final PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 4414 return pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*alarm*"); 4415 } 4416 getSystemUiUid(PackageManagerInternal pm)4417 int getSystemUiUid(PackageManagerInternal pm) { 4418 return pm.getPackageUid(pm.getSystemUiServiceComponent().getPackageName(), 4419 MATCH_SYSTEM_ONLY, USER_SYSTEM); 4420 } 4421 getAppOpsService()4422 IAppOpsService getAppOpsService() { 4423 return IAppOpsService.Stub.asInterface( 4424 ServiceManager.getService(Context.APP_OPS_SERVICE)); 4425 } 4426 getClockReceiver(AlarmManagerService service)4427 ClockReceiver getClockReceiver(AlarmManagerService service) { 4428 return service.new ClockReceiver(); 4429 } 4430 registerDeviceConfigListener(DeviceConfig.OnPropertiesChangedListener listener)4431 void registerDeviceConfigListener(DeviceConfig.OnPropertiesChangedListener listener) { 4432 DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_ALARM_MANAGER, 4433 AppSchedulingModuleThread.getExecutor(), listener); 4434 } 4435 } 4436 4437 private class AlarmThread extends Thread { 4438 private int mFalseWakeups; 4439 private int mWtfThreshold; 4440 AlarmThread()4441 AlarmThread() { 4442 super("AlarmManager"); 4443 mFalseWakeups = 0; 4444 mWtfThreshold = 100; 4445 } 4446 run()4447 public void run() { 4448 ArrayList<Alarm> triggerList = new ArrayList<Alarm>(); 4449 4450 while (true) { 4451 int result = mInjector.waitForAlarm(); 4452 final long nowRTC = mInjector.getCurrentTimeMillis(); 4453 final long nowELAPSED = mInjector.getElapsedRealtimeMillis(); 4454 synchronized (mLock) { 4455 mLastWakeup = nowELAPSED; 4456 } 4457 if (result == 0) { 4458 Slog.wtf(TAG, "waitForAlarm returned 0, nowRTC = " + nowRTC 4459 + ", nowElapsed = " + nowELAPSED); 4460 } 4461 triggerList.clear(); 4462 4463 if ((result & TIME_CHANGED_MASK) != 0) { 4464 // The kernel can give us spurious time change notifications due to 4465 // small adjustments it makes internally; we want to filter those out. 4466 final long lastTimeChangeClockTime; 4467 final long expectedClockTime; 4468 synchronized (mLock) { 4469 lastTimeChangeClockTime = mLastTimeChangeClockTime; 4470 expectedClockTime = lastTimeChangeClockTime 4471 + (nowELAPSED - mLastTimeChangeRealtime); 4472 } 4473 if (lastTimeChangeClockTime == 0 || nowRTC < (expectedClockTime - 1000) 4474 || nowRTC > (expectedClockTime + 1000)) { 4475 // The change is by at least +/- 1000 ms (or this is the first change), 4476 // let's do it! 4477 if (DEBUG_BATCH) { 4478 Slog.v(TAG, "Time changed notification from kernel; rebatching"); 4479 } 4480 // StatsLog requires currentTimeMillis(), which == nowRTC to within usecs. 4481 FrameworkStatsLog.write(FrameworkStatsLog.WALL_CLOCK_TIME_SHIFTED, nowRTC); 4482 removeImpl(null, mTimeTickTrigger); 4483 removeImpl(mDateChangeSender, null); 4484 reevaluateRtcAlarms(); 4485 mClockReceiver.scheduleTimeTickEvent(); 4486 mClockReceiver.scheduleDateChangedEvent(); 4487 synchronized (mLock) { 4488 mNumTimeChanged++; 4489 mLastTimeChangeClockTime = nowRTC; 4490 mLastTimeChangeRealtime = nowELAPSED; 4491 } 4492 Intent intent = new Intent(Intent.ACTION_TIME_CHANGED); 4493 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING 4494 | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT 4495 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND 4496 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); 4497 mOptsTimeBroadcast.setTemporaryAppAllowlist( 4498 mActivityManagerInternal.getBootTimeTempAllowListDuration(), 4499 TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED, 4500 PowerExemptionManager.REASON_TIME_CHANGED, ""); 4501 mOptsTimeBroadcast.setDeliveryGroupPolicy( 4502 BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT); 4503 getContext().sendBroadcastAsUser(intent, UserHandle.ALL, 4504 null /* receiverPermission */, mOptsTimeBroadcast.toBundle()); 4505 // The world has changed on us, so we need to re-evaluate alarms 4506 // regardless of whether the kernel has told us one went off. 4507 result |= IS_WAKEUP_MASK; 4508 } 4509 } 4510 4511 if (result != TIME_CHANGED_MASK) { 4512 // If this was anything besides just a time change, then figure what if 4513 // anything to do about alarms. 4514 synchronized (mLock) { 4515 if (localLOGV) { 4516 Slog.v(TAG, "Checking for alarms... rtc=" + nowRTC 4517 + ", elapsed=" + nowELAPSED); 4518 } 4519 4520 if (mStartUserBeforeScheduledAlarms) { 4521 final int[] userIds = 4522 mUserWakeupStore.getUserIdsToWakeup(nowELAPSED); 4523 for (int i = 0; i < userIds.length; i++) { 4524 if (!mActivityManagerInternal.startUserInBackground( 4525 userIds[i])) { 4526 mUserWakeupStore.removeUserWakeup(userIds[i]); 4527 } 4528 } 4529 } 4530 mLastTrigger = nowELAPSED; 4531 final int wakeUps = triggerAlarmsLocked(triggerList, nowELAPSED); 4532 if (wakeUps == 0 && checkAllowNonWakeupDelayLocked(nowELAPSED)) { 4533 // if there are no wakeup alarms and the screen is off, we can 4534 // delay what we have so far until the future. 4535 if (mPendingNonWakeupAlarms.size() == 0) { 4536 mStartCurrentDelayTime = nowELAPSED; 4537 mNextNonWakeupDeliveryTime = nowELAPSED 4538 + ((currentNonWakeupFuzzLocked(nowELAPSED) * 3) / 2); 4539 } 4540 mPendingNonWakeupAlarms.addAll(triggerList); 4541 mNumDelayedAlarms += triggerList.size(); 4542 rescheduleKernelAlarmsLocked(); 4543 updateNextAlarmClockLocked(); 4544 } else { 4545 // now deliver the alarm intents; if there are pending non-wakeup 4546 // alarms, we need to merge them in to the list. note we don't 4547 // just deliver them first because we generally want non-wakeup 4548 // alarms delivered after wakeup alarms. 4549 if (mPendingNonWakeupAlarms.size() > 0) { 4550 calculateDeliveryPriorities(mPendingNonWakeupAlarms); 4551 triggerList.addAll(mPendingNonWakeupAlarms); 4552 Collections.sort(triggerList, mAlarmDispatchComparator); 4553 final long thisDelayTime = nowELAPSED - mStartCurrentDelayTime; 4554 mTotalDelayTime += thisDelayTime; 4555 if (mMaxDelayTime < thisDelayTime) { 4556 mMaxDelayTime = thisDelayTime; 4557 } 4558 mPendingNonWakeupAlarms.clear(); 4559 } 4560 if (mLastTimeChangeRealtime != nowELAPSED && triggerList.isEmpty()) { 4561 if (++mFalseWakeups >= mWtfThreshold) { 4562 Slog.wtf(TAG, "Too many (" + mFalseWakeups 4563 + ") false wakeups, nowElapsed=" + nowELAPSED); 4564 if (mWtfThreshold < 100_000) { 4565 mWtfThreshold *= 10; 4566 } else { 4567 mFalseWakeups = 0; 4568 } 4569 } 4570 } 4571 final ArraySet<UserPackage> triggerPackages = new ArraySet<>(); 4572 final IntArray wakeupUids = new IntArray(); 4573 final SparseIntArray countsPerUid = new SparseIntArray(); 4574 final SparseIntArray wakeupCountsPerUid = new SparseIntArray(); 4575 for (int i = 0; i < triggerList.size(); i++) { 4576 final Alarm a = triggerList.get(i); 4577 increment(countsPerUid, a.uid); 4578 if (a.wakeup) { 4579 wakeupUids.add(a.uid); 4580 increment(wakeupCountsPerUid, a.uid); 4581 } 4582 if (!isExemptFromAppStandby(a)) { 4583 triggerPackages.add(UserPackage.of( 4584 UserHandle.getUserId(a.creatorUid), a.sourcePackage)); 4585 } 4586 } 4587 if (wakeupUids.size() > 0 && mBatteryStatsInternal != null) { 4588 mBatteryStatsInternal.noteWakingAlarmBatch(nowELAPSED, 4589 wakeupUids.toArray()); 4590 } 4591 deliverAlarmsLocked(triggerList, nowELAPSED); 4592 mTemporaryQuotaReserve.cleanUpExpiredQuotas(nowELAPSED); 4593 reorderAlarmsBasedOnStandbyBuckets(triggerPackages); 4594 rescheduleKernelAlarmsLocked(); 4595 updateNextAlarmClockLocked(); 4596 logAlarmBatchDelivered( 4597 triggerList.size(), wakeUps, countsPerUid, wakeupCountsPerUid); 4598 } 4599 } 4600 4601 } else { 4602 // Just in case -- even though no wakeup flag was set, make sure 4603 // we have updated the kernel to the next alarm time. 4604 synchronized (mLock) { 4605 rescheduleKernelAlarmsLocked(); 4606 } 4607 } 4608 } 4609 } 4610 } 4611 increment(SparseIntArray array, int key)4612 private static void increment(SparseIntArray array, int key) { 4613 final int index = array.indexOfKey(key); 4614 if (index >= 0) { 4615 array.setValueAt(index, array.valueAt(index) + 1); 4616 } else { 4617 array.put(key, 1); 4618 } 4619 } 4620 logAlarmBatchDelivered( int alarms, int wakeups, SparseIntArray countsPerUid, SparseIntArray wakeupCountsPerUid)4621 private void logAlarmBatchDelivered( 4622 int alarms, 4623 int wakeups, 4624 SparseIntArray countsPerUid, 4625 SparseIntArray wakeupCountsPerUid) { 4626 final int[] uids = new int[countsPerUid.size()]; 4627 final int[] countsArray = new int[countsPerUid.size()]; 4628 final int[] wakeupCountsArray = new int[countsPerUid.size()]; 4629 for (int i = 0; i < countsPerUid.size(); i++) { 4630 uids[i] = countsPerUid.keyAt(i); 4631 countsArray[i] = countsPerUid.valueAt(i); 4632 wakeupCountsArray[i] = wakeupCountsPerUid.get(uids[i], 0); 4633 } 4634 MetricsHelper.pushAlarmBatchDelivered( 4635 alarms, wakeups, uids, countsArray, wakeupCountsArray); 4636 } 4637 4638 /** 4639 * Attribute blame for a WakeLock. 4640 * 4641 * @param ws WorkSource to attribute blame. 4642 * @param knownUid attribution uid; < 0 values are ignored. 4643 */ setWakelockWorkSource(WorkSource ws, int knownUid, String tag, boolean first)4644 void setWakelockWorkSource(WorkSource ws, int knownUid, String tag, boolean first) { 4645 try { 4646 mWakeLock.setHistoryTag(first ? tag : null); 4647 4648 if (ws != null) { 4649 mWakeLock.setWorkSource(ws); 4650 return; 4651 } 4652 4653 if (knownUid >= 0) { 4654 mWakeLock.setWorkSource(new WorkSource(knownUid)); 4655 return; 4656 } 4657 } catch (Exception e) { 4658 } 4659 4660 // Something went wrong; fall back to attributing the lock to the OS 4661 mWakeLock.setWorkSource(null); 4662 } 4663 getAlarmAttributionUid(Alarm alarm)4664 private static int getAlarmAttributionUid(Alarm alarm) { 4665 if (alarm.workSource != null && !alarm.workSource.isEmpty()) { 4666 return alarm.workSource.getAttributionUid(); 4667 } 4668 4669 return alarm.creatorUid; 4670 } 4671 getAlarmOperationBundle(Alarm alarm)4672 private Bundle getAlarmOperationBundle(Alarm alarm) { 4673 if (alarm.mIdleOptions != null) { 4674 return alarm.mIdleOptions; 4675 } else { 4676 if (alarm.operation.isActivity()) { 4677 return mActivityOptsRestrictBal.toBundle(); 4678 } else { 4679 return mBroadcastOptsRestrictBal.toBundle(); 4680 } 4681 } 4682 } 4683 4684 @VisibleForTesting 4685 class AlarmHandler extends Handler { 4686 public static final int ALARM_EVENT = 1; 4687 public static final int SEND_NEXT_ALARM_CLOCK_CHANGED = 2; 4688 public static final int LISTENER_TIMEOUT = 3; 4689 public static final int REPORT_ALARMS_ACTIVE = 4; 4690 public static final int APP_STANDBY_BUCKET_CHANGED = 5; 4691 public static final int CHARGING_STATUS_CHANGED = 6; 4692 public static final int REMOVE_FOR_CANCELED = 7; 4693 public static final int REMOVE_EXACT_ALARMS = 8; 4694 // Unused id 9 4695 // Unused id 10 4696 public static final int REFRESH_EXACT_ALARM_CANDIDATES = 11; 4697 public static final int CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE = 13; 4698 public static final int TEMPORARY_QUOTA_CHANGED = 14; 4699 public static final int REMOVE_EXACT_LISTENER_ALARMS_ON_CACHED = 15; 4700 AlarmHandler()4701 AlarmHandler() { 4702 super(Looper.myLooper()); 4703 } 4704 4705 @Override handleMessage(Message msg)4706 public void handleMessage(Message msg) { 4707 switch (msg.what) { 4708 case ALARM_EVENT: { 4709 // This code is used when the kernel timer driver is not available, which 4710 // shouldn't happen. Here, we try our best to simulate it, which may be useful 4711 // when porting Android to a new device. Note that we can't wake up a device 4712 // this way, so WAKE_UP alarms will be delivered only when the device is awake. 4713 ArrayList<Alarm> triggerList = new ArrayList<Alarm>(); 4714 synchronized (mLock) { 4715 final long nowELAPSED = mInjector.getElapsedRealtimeMillis(); 4716 triggerAlarmsLocked(triggerList, nowELAPSED); 4717 updateNextAlarmClockLocked(); 4718 } 4719 4720 // now trigger the alarms without the lock held 4721 for (int i = 0; i < triggerList.size(); i++) { 4722 Alarm alarm = triggerList.get(i); 4723 try { 4724 // Disallow AlarmManager to start random background activity. 4725 final Bundle bundle = getAlarmOperationBundle(alarm); 4726 alarm.operation.send(/* context */ null, /* code */0, /* intent */ 4727 null, /* onFinished */null, /* handler */ 4728 null, /* requiredPermission */ null, bundle); 4729 } catch (PendingIntent.CanceledException e) { 4730 if (alarm.repeatInterval > 0) { 4731 // This IntentSender is no longer valid, but this 4732 // is a repeating alarm, so toss the hoser. 4733 removeImpl(alarm.operation, null); 4734 } 4735 } 4736 decrementAlarmCount(alarm.uid, 1); 4737 } 4738 break; 4739 } 4740 4741 case SEND_NEXT_ALARM_CLOCK_CHANGED: 4742 sendNextAlarmClockChanged(); 4743 break; 4744 4745 case LISTENER_TIMEOUT: 4746 mDeliveryTracker.alarmTimedOut((IBinder) msg.obj); 4747 break; 4748 4749 case REPORT_ALARMS_ACTIVE: 4750 if (mLocalDeviceIdleController != null) { 4751 mLocalDeviceIdleController.setAlarmsActive(msg.arg1 != 0); 4752 } 4753 break; 4754 4755 case CHARGING_STATUS_CHANGED: 4756 synchronized (mLock) { 4757 mAppStandbyParole = (Boolean) msg.obj; 4758 if (reorderAlarmsBasedOnStandbyBuckets(null)) { 4759 rescheduleKernelAlarmsLocked(); 4760 updateNextAlarmClockLocked(); 4761 } 4762 } 4763 break; 4764 4765 case TEMPORARY_QUOTA_CHANGED: 4766 case APP_STANDBY_BUCKET_CHANGED: 4767 synchronized (mLock) { 4768 final ArraySet<UserPackage> filterPackages = new ArraySet<>(); 4769 filterPackages.add(UserPackage.of(msg.arg1, (String) msg.obj)); 4770 if (reorderAlarmsBasedOnStandbyBuckets(filterPackages)) { 4771 rescheduleKernelAlarmsLocked(); 4772 updateNextAlarmClockLocked(); 4773 } 4774 } 4775 break; 4776 4777 case REMOVE_FOR_CANCELED: 4778 final PendingIntent operation = (PendingIntent) msg.obj; 4779 synchronized (mLock) { 4780 removeLocked(operation, null, REMOVE_REASON_PI_CANCELLED); 4781 } 4782 break; 4783 4784 case REMOVE_EXACT_ALARMS: 4785 int uid = msg.arg1; 4786 String packageName = (String) msg.obj; 4787 removeExactAlarmsOnPermissionRevoked(uid, packageName, /*killUid = */true); 4788 break; 4789 case REFRESH_EXACT_ALARM_CANDIDATES: 4790 refreshExactAlarmCandidates(); 4791 break; 4792 case CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE: 4793 packageName = (String) msg.obj; 4794 uid = msg.arg1; 4795 if (!hasScheduleExactAlarmInternal(packageName, uid) 4796 && !hasUseExactAlarmInternal(packageName, uid)) { 4797 removeExactAlarmsOnPermissionRevoked(uid, packageName, /*killUid = */false); 4798 } 4799 break; 4800 case REMOVE_EXACT_LISTENER_ALARMS_ON_CACHED: 4801 uid = (Integer) msg.obj; 4802 removeExactListenerAlarms(uid); 4803 break; 4804 default: 4805 // nope, just ignore it 4806 break; 4807 } 4808 } 4809 } 4810 4811 @VisibleForTesting 4812 class ChargingReceiver extends BroadcastReceiver { ChargingReceiver()4813 ChargingReceiver() { 4814 IntentFilter filter = new IntentFilter(); 4815 filter.addAction(BatteryManager.ACTION_CHARGING); 4816 filter.addAction(BatteryManager.ACTION_DISCHARGING); 4817 getContext().registerReceiver(this, filter); 4818 } 4819 4820 @Override onReceive(Context context, Intent intent)4821 public void onReceive(Context context, Intent intent) { 4822 final String action = intent.getAction(); 4823 final boolean charging; 4824 if (BatteryManager.ACTION_CHARGING.equals(action)) { 4825 if (DEBUG_STANDBY) { 4826 Slog.d(TAG, "Device is charging."); 4827 } 4828 charging = true; 4829 } else { 4830 if (DEBUG_STANDBY) { 4831 Slog.d(TAG, "Disconnected from power."); 4832 } 4833 charging = false; 4834 } 4835 mHandler.removeMessages(AlarmHandler.CHARGING_STATUS_CHANGED); 4836 mHandler.obtainMessage(AlarmHandler.CHARGING_STATUS_CHANGED, charging) 4837 .sendToTarget(); 4838 } 4839 } 4840 4841 @VisibleForTesting 4842 class ClockReceiver extends BroadcastReceiver { ClockReceiver()4843 public ClockReceiver() { 4844 IntentFilter filter = new IntentFilter(); 4845 filter.addAction(Intent.ACTION_DATE_CHANGED); 4846 getContext().registerReceiver(this, filter); 4847 } 4848 4849 @Override onReceive(Context context, Intent intent)4850 public void onReceive(Context context, Intent intent) { 4851 if (intent.getAction().equals(Intent.ACTION_DATE_CHANGED)) { 4852 scheduleDateChangedEvent(); 4853 } 4854 } 4855 scheduleTimeTickEvent()4856 public void scheduleTimeTickEvent() { 4857 final long currentTime = mInjector.getCurrentTimeMillis(); 4858 final long nextTime = 60000 * ((currentTime / 60000) + 1); 4859 4860 // Schedule this event for the amount of time that it would take to get to 4861 // the top of the next minute. 4862 final long tickEventDelay = nextTime - currentTime; 4863 4864 final WorkSource workSource = null; // Let system take blame for time tick events. 4865 4866 int flags = AlarmManager.FLAG_STANDALONE; 4867 flags |= mConstants.TIME_TICK_ALLOWED_WHILE_IDLE ? FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED 4868 : 0; 4869 4870 setImpl(ELAPSED_REALTIME, mInjector.getElapsedRealtimeMillis() + tickEventDelay, 0, 4871 0, null, mTimeTickTrigger, TIME_TICK_TAG, flags, workSource, null, 4872 Process.myUid(), "android", null, EXACT_ALLOW_REASON_ALLOW_LIST); 4873 4874 // Finally, remember when we set the tick alarm 4875 synchronized (mLock) { 4876 mLastTickSet = currentTime; 4877 } 4878 } 4879 scheduleDateChangedEvent()4880 public void scheduleDateChangedEvent() { 4881 Calendar calendar = Calendar.getInstance(); 4882 calendar.setTimeInMillis(mInjector.getCurrentTimeMillis()); 4883 calendar.set(Calendar.HOUR_OF_DAY, 0); 4884 calendar.set(Calendar.MINUTE, 0); 4885 calendar.set(Calendar.SECOND, 0); 4886 calendar.set(Calendar.MILLISECOND, 0); 4887 calendar.add(Calendar.DAY_OF_MONTH, 1); 4888 4889 final WorkSource workSource = null; // Let system take blame for date change events. 4890 setImpl(RTC, calendar.getTimeInMillis(), 0, 0, mDateChangeSender, null, null, 4891 AlarmManager.FLAG_STANDALONE, workSource, null, 4892 Process.myUid(), "android", null, EXACT_ALLOW_REASON_ALLOW_LIST); 4893 } 4894 } 4895 4896 class InteractiveStateReceiver extends BroadcastReceiver { InteractiveStateReceiver()4897 public InteractiveStateReceiver() { 4898 IntentFilter filter = new IntentFilter(); 4899 filter.addAction(Intent.ACTION_SCREEN_OFF); 4900 filter.addAction(Intent.ACTION_SCREEN_ON); 4901 filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); 4902 getContext().registerReceiver(this, filter); 4903 } 4904 4905 @Override onReceive(Context context, Intent intent)4906 public void onReceive(Context context, Intent intent) { 4907 synchronized (mLock) { 4908 interactiveStateChangedLocked(Intent.ACTION_SCREEN_ON.equals(intent.getAction())); 4909 } 4910 } 4911 } 4912 4913 class UninstallReceiver extends BroadcastReceiver { UninstallReceiver()4914 public UninstallReceiver() { 4915 IntentFilter filter = new IntentFilter(); 4916 filter.addAction(Intent.ACTION_PACKAGE_REMOVED); 4917 filter.addAction(Intent.ACTION_PACKAGE_ADDED); 4918 filter.addAction(Intent.ACTION_PACKAGE_RESTARTED); 4919 filter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4920 filter.addDataScheme(IntentFilter.SCHEME_PACKAGE); 4921 getContext().registerReceiverForAllUsers(this, filter, 4922 /* broadcastPermission */ null, /* scheduler */ null); 4923 // Register for events related to sdcard installation. 4924 IntentFilter sdFilter = new IntentFilter(); 4925 sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); 4926 sdFilter.addAction(Intent.ACTION_USER_STOPPED); 4927 if (mStartUserBeforeScheduledAlarms) { 4928 sdFilter.addAction(Intent.ACTION_LOCKED_BOOT_COMPLETED); 4929 sdFilter.addAction(Intent.ACTION_USER_REMOVED); 4930 } 4931 sdFilter.addAction(Intent.ACTION_UID_REMOVED); 4932 getContext().registerReceiverForAllUsers(this, sdFilter, 4933 /* broadcastPermission */ null, /* scheduler */ null); 4934 } 4935 4936 @Override onReceive(Context context, Intent intent)4937 public void onReceive(Context context, Intent intent) { 4938 final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 4939 synchronized (mLock) { 4940 String pkgList[] = null; 4941 switch (intent.getAction()) { 4942 case Intent.ACTION_QUERY_PACKAGE_RESTART: 4943 pkgList = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4944 for (String packageName : pkgList) { 4945 if (lookForPackageLocked(packageName, uid)) { 4946 setResultCode(Activity.RESULT_OK); 4947 return; 4948 } 4949 } 4950 return; 4951 case Intent.ACTION_USER_STOPPED: 4952 final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 4953 if (userHandle >= 0) { 4954 removeUserLocked(userHandle); 4955 mAppWakeupHistory.removeForUser(userHandle); 4956 mAllowWhileIdleHistory.removeForUser(userHandle); 4957 mAllowWhileIdleCompatHistory.removeForUser(userHandle); 4958 mTemporaryQuotaReserve.removeForUser(userHandle); 4959 } 4960 return; 4961 case Intent.ACTION_LOCKED_BOOT_COMPLETED: 4962 final int handle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 4963 if (handle >= 0) { 4964 if (mStartUserBeforeScheduledAlarms) { 4965 mUserWakeupStore.onUserStarted(handle); 4966 } 4967 } 4968 return; 4969 case Intent.ACTION_USER_REMOVED: 4970 final int user = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 4971 if (user >= 0) { 4972 if (mStartUserBeforeScheduledAlarms) { 4973 mUserWakeupStore.onUserRemoved(user); 4974 } 4975 } 4976 return; 4977 case Intent.ACTION_UID_REMOVED: 4978 mLastPriorityAlarmDispatch.delete(uid); 4979 mRemovalHistory.delete(uid); 4980 mLastOpScheduleExactAlarm.delete(uid); 4981 return; 4982 case Intent.ACTION_PACKAGE_ADDED: 4983 mHandler.sendEmptyMessage(AlarmHandler.REFRESH_EXACT_ALARM_CANDIDATES); 4984 if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 4985 // Some apps may lose permission to set exact alarms on update. 4986 // We need to remove their exact alarms. 4987 final String packageUpdated = intent.getData().getSchemeSpecificPart(); 4988 mHandler.obtainMessage( 4989 AlarmHandler.CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE, uid, -1, 4990 packageUpdated).sendToTarget(); 4991 } 4992 return; 4993 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 4994 pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 4995 break; 4996 case Intent.ACTION_PACKAGE_REMOVED: 4997 if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 4998 // This package is being updated; don't kill its alarms. 4999 // We will refresh the exact alarm candidates on subsequent receipt of 5000 // PACKAGE_ADDED. 5001 return; 5002 } 5003 mHandler.sendEmptyMessage(AlarmHandler.REFRESH_EXACT_ALARM_CANDIDATES); 5004 // Intentional fall-through. 5005 case Intent.ACTION_PACKAGE_RESTARTED: 5006 final Uri data = intent.getData(); 5007 if (data != null) { 5008 final String pkg = data.getSchemeSpecificPart(); 5009 if (pkg != null) { 5010 pkgList = new String[]{pkg}; 5011 } 5012 } 5013 break; 5014 } 5015 if (pkgList != null && (pkgList.length > 0)) { 5016 for (String pkg : pkgList) { 5017 if (uid >= 0) { 5018 // package-removed and package-restarted case 5019 mAppWakeupHistory.removeForPackage(pkg, UserHandle.getUserId(uid)); 5020 mAllowWhileIdleHistory.removeForPackage(pkg, UserHandle.getUserId(uid)); 5021 mAllowWhileIdleCompatHistory.removeForPackage(pkg, 5022 UserHandle.getUserId(uid)); 5023 mTemporaryQuotaReserve.removeForPackage(pkg, UserHandle.getUserId(uid)); 5024 removeLocked(uid, REMOVE_REASON_UNDEFINED); 5025 } else { 5026 // external-applications-unavailable case 5027 removeLocked(pkg, REMOVE_REASON_UNDEFINED); 5028 } 5029 for (int i = mBroadcastStats.size() - 1; i >= 0; i--) { 5030 ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(i); 5031 if (uidStats.remove(pkg) != null) { 5032 if (uidStats.size() <= 0) { 5033 mBroadcastStats.removeAt(i); 5034 } 5035 } 5036 } 5037 } 5038 } 5039 } 5040 } 5041 } 5042 5043 /** 5044 * Tracking of app assignments to standby buckets 5045 */ 5046 private final class AppStandbyTracker extends AppIdleStateChangeListener { 5047 @Override onAppIdleStateChanged(final String packageName, final @UserIdInt int userId, boolean idle, int bucket, int reason)5048 public void onAppIdleStateChanged(final String packageName, final @UserIdInt int userId, 5049 boolean idle, int bucket, int reason) { 5050 if (DEBUG_STANDBY) { 5051 Slog.d(TAG, "Package " + packageName + " for user " + userId + " now in bucket " + 5052 bucket); 5053 } 5054 mHandler.obtainMessage(AlarmHandler.APP_STANDBY_BUCKET_CHANGED, userId, -1, packageName) 5055 .sendToTarget(); 5056 } 5057 5058 @Override triggerTemporaryQuotaBump(String packageName, int userId)5059 public void triggerTemporaryQuotaBump(String packageName, int userId) { 5060 final int quotaBump; 5061 synchronized (mLock) { 5062 quotaBump = mConstants.TEMPORARY_QUOTA_BUMP; 5063 } 5064 if (quotaBump <= 0) { 5065 return; 5066 } 5067 final int uid = mPackageManagerInternal.getPackageUid(packageName, 0, userId); 5068 if (uid < 0 || UserHandle.isCore(uid)) { 5069 return; 5070 } 5071 if (DEBUG_STANDBY) { 5072 Slog.d(TAG, "Bumping quota temporarily for " + packageName + " for user " + userId); 5073 } 5074 synchronized (mLock) { 5075 mTemporaryQuotaReserve.replenishQuota(packageName, userId, quotaBump, 5076 mInjector.getElapsedRealtimeMillis()); 5077 } 5078 mHandler.obtainMessage(AlarmHandler.TEMPORARY_QUOTA_CHANGED, userId, -1, 5079 packageName).sendToTarget(); 5080 } 5081 } 5082 5083 private final Listener mForceAppStandbyListener = new Listener() { 5084 5085 @Override 5086 public void updateAllAlarms() { 5087 // Called when: 5088 // 1. Power exemption list changes, 5089 // 2. Battery saver state is toggled, 5090 // 3. Any package is moved into or out of the EXEMPTED bucket. 5091 synchronized (mLock) { 5092 if (mAlarmStore.updateAlarmDeliveries( 5093 a -> adjustDeliveryTimeBasedOnBatterySaver(a))) { 5094 rescheduleKernelAlarmsLocked(); 5095 } 5096 } 5097 } 5098 5099 @Override 5100 public void updateAlarmsForUid(int uid) { 5101 // Called when the given uid's state switches b/w active and idle. 5102 synchronized (mLock) { 5103 if (mAlarmStore.updateAlarmDeliveries(a -> { 5104 if (a.creatorUid != uid) { 5105 return false; 5106 } 5107 return adjustDeliveryTimeBasedOnBatterySaver(a); 5108 })) { 5109 rescheduleKernelAlarmsLocked(); 5110 } 5111 } 5112 } 5113 5114 @Override 5115 public void unblockAllUnrestrictedAlarms() { 5116 // Called when the power exemption list changes. 5117 synchronized (mLock) { 5118 sendAllUnrestrictedPendingBackgroundAlarmsLocked(); 5119 } 5120 } 5121 5122 @Override 5123 public void unblockAlarmsForUid(int uid) { 5124 synchronized (mLock) { 5125 // Called when the given uid becomes active. 5126 sendPendingBackgroundAlarmsLocked(uid, null); 5127 } 5128 } 5129 5130 @Override 5131 public void unblockAlarmsForUidPackage(int uid, String packageName) { 5132 // Called when user turns off FAS for this (uid, package). 5133 synchronized (mLock) { 5134 sendPendingBackgroundAlarmsLocked(uid, packageName); 5135 } 5136 } 5137 5138 @Override 5139 public void removeAlarmsForUid(int uid) { 5140 synchronized (mLock) { 5141 removeForStoppedLocked(uid); 5142 } 5143 } 5144 5145 @Override 5146 public void handleUidCachedChanged(int uid, boolean cached) { 5147 if (mUseFrozenStateToDropListenerAlarms) { 5148 // Use ActivityManager#UidFrozenStateChangedCallback instead. 5149 return; 5150 } 5151 if (!CompatChanges.isChangeEnabled(EXACT_LISTENER_ALARMS_DROPPED_ON_CACHED, uid)) { 5152 return; 5153 } 5154 // Apps can quickly get frozen after being cached, breaking the exactness guarantee on 5155 // listener alarms. So going forward, the contract of exact listener alarms explicitly 5156 // states that they will be removed as soon as the app goes out of lifecycle. We still 5157 // allow a short grace period for quick shuffling of proc-states that may happen 5158 // unexpectedly when switching between different lifecycles and is generally hard for 5159 // apps to avoid. 5160 5161 final long delay; 5162 synchronized (mLock) { 5163 delay = mConstants.CACHED_LISTENER_REMOVAL_DELAY; 5164 } 5165 final Integer uidObj = uid; 5166 5167 if (cached && !mHandler.hasEqualMessages(REMOVE_EXACT_LISTENER_ALARMS_ON_CACHED, 5168 uidObj)) { 5169 mHandler.sendMessageDelayed( 5170 mHandler.obtainMessage(REMOVE_EXACT_LISTENER_ALARMS_ON_CACHED, uidObj), 5171 delay); 5172 } else { 5173 mHandler.removeEqualMessages(REMOVE_EXACT_LISTENER_ALARMS_ON_CACHED, uidObj); 5174 } 5175 } 5176 }; 5177 getStatsLocked(PendingIntent pi)5178 private final BroadcastStats getStatsLocked(PendingIntent pi) { 5179 String pkg = pi.getCreatorPackage(); 5180 int uid = pi.getCreatorUid(); 5181 return getStatsLocked(uid, pkg); 5182 } 5183 getStatsLocked(int uid, String pkgName)5184 private final BroadcastStats getStatsLocked(int uid, String pkgName) { 5185 ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.get(uid); 5186 if (uidStats == null) { 5187 uidStats = new ArrayMap<String, BroadcastStats>(); 5188 mBroadcastStats.put(uid, uidStats); 5189 } 5190 BroadcastStats bs = uidStats.get(pkgName); 5191 if (bs == null) { 5192 bs = new BroadcastStats(uid, pkgName); 5193 uidStats.put(pkgName, bs); 5194 } 5195 return bs; 5196 } 5197 5198 /** 5199 * Canonical count of (operation.send() - onSendFinished()) and 5200 * listener send/complete/timeout invocations. 5201 * Guarded by the usual lock. 5202 */ 5203 @GuardedBy("mLock") 5204 private int mSendCount = 0; 5205 @GuardedBy("mLock") 5206 private int mSendFinishCount = 0; 5207 @GuardedBy("mLock") 5208 private int mListenerCount = 0; 5209 @GuardedBy("mLock") 5210 private int mListenerFinishCount = 0; 5211 5212 class DeliveryTracker extends IAlarmCompleteListener.Stub implements PendingIntent.OnFinished { 5213 5214 @GuardedBy("mLock") removeLocked(PendingIntent pi, Intent intent)5215 private InFlight removeLocked(PendingIntent pi, Intent intent) { 5216 for (int i = 0; i < mInFlight.size(); i++) { 5217 final InFlight inflight = mInFlight.get(i); 5218 if (inflight.mPendingIntent == pi) { 5219 if (pi.isBroadcast()) { 5220 notifyBroadcastAlarmCompleteLocked(inflight.mUid); 5221 } 5222 return mInFlight.remove(i); 5223 } 5224 } 5225 mLog.w("No in-flight alarm for " + pi + " " + intent); 5226 return null; 5227 } 5228 5229 @GuardedBy("mLock") removeLocked(IBinder listener)5230 private InFlight removeLocked(IBinder listener) { 5231 for (int i = 0; i < mInFlight.size(); i++) { 5232 if (mInFlight.get(i).mListener == listener) { 5233 return mInFlight.remove(i); 5234 } 5235 } 5236 mLog.w("No in-flight alarm for listener " + listener); 5237 return null; 5238 } 5239 updateStatsLocked(InFlight inflight)5240 private void updateStatsLocked(InFlight inflight) { 5241 final long nowELAPSED = mInjector.getElapsedRealtimeMillis(); 5242 BroadcastStats bs = inflight.mBroadcastStats; 5243 bs.nesting--; 5244 if (bs.nesting <= 0) { 5245 bs.nesting = 0; 5246 bs.aggregateTime += nowELAPSED - bs.startTime; 5247 } 5248 FilterStats fs = inflight.mFilterStats; 5249 fs.nesting--; 5250 if (fs.nesting <= 0) { 5251 fs.nesting = 0; 5252 fs.aggregateTime += nowELAPSED - fs.startTime; 5253 } 5254 if (RECORD_ALARMS_IN_HISTORY) { 5255 mActivityManagerInternal.noteAlarmFinish(inflight.mPendingIntent, 5256 inflight.mWorkSource, inflight.mUid, inflight.mTag); 5257 } 5258 } 5259 updateTrackingLocked(InFlight inflight)5260 private void updateTrackingLocked(InFlight inflight) { 5261 if (inflight != null) { 5262 updateStatsLocked(inflight); 5263 } 5264 mBroadcastRefCount--; 5265 if (DEBUG_WAKELOCK) { 5266 Slog.d(TAG, "mBroadcastRefCount -> " + mBroadcastRefCount); 5267 } 5268 if (mBroadcastRefCount == 0) { 5269 mHandler.obtainMessage(AlarmHandler.REPORT_ALARMS_ACTIVE, 0, 0).sendToTarget(); 5270 mWakeLock.release(); 5271 if (mInFlight.size() > 0) { 5272 mLog.w("Finished all dispatches with " + mInFlight.size() 5273 + " remaining inflights"); 5274 for (int i = 0; i < mInFlight.size(); i++) { 5275 mLog.w(" Remaining #" + i + ": " + mInFlight.get(i)); 5276 } 5277 mInFlight.clear(); 5278 } 5279 } else { 5280 // the next of our alarms is now in flight. reattribute the wakelock. 5281 if (mInFlight.size() > 0) { 5282 InFlight inFlight = mInFlight.get(0); 5283 setWakelockWorkSource(inFlight.mWorkSource, inFlight.mCreatorUid, inFlight.mTag, 5284 false); 5285 } else { 5286 // should never happen 5287 mLog.w("Alarm wakelock still held but sent queue empty"); 5288 mWakeLock.setWorkSource(null); 5289 } 5290 } 5291 } 5292 5293 /** 5294 * Callback that arrives when a direct-call alarm reports that delivery has finished 5295 */ 5296 @Override alarmComplete(IBinder who)5297 public void alarmComplete(IBinder who) { 5298 if (who == null) { 5299 mLog.w("Invalid alarmComplete: uid=" + Binder.getCallingUid() 5300 + " pid=" + Binder.getCallingPid()); 5301 return; 5302 } 5303 5304 final long ident = Binder.clearCallingIdentity(); 5305 try { 5306 synchronized (mLock) { 5307 mHandler.removeMessages(AlarmHandler.LISTENER_TIMEOUT, who); 5308 InFlight inflight = removeLocked(who); 5309 if (inflight != null) { 5310 if (DEBUG_LISTENER_CALLBACK) { 5311 Slog.i(TAG, "alarmComplete() from " + who); 5312 } 5313 updateTrackingLocked(inflight); 5314 mListenerFinishCount++; 5315 } else { 5316 // Delivery timed out, and the timeout handling already took care of 5317 // updating our tracking here, so we needn't do anything further. 5318 if (DEBUG_LISTENER_CALLBACK) { 5319 Slog.i(TAG, "Late alarmComplete() from " + who); 5320 } 5321 } 5322 } 5323 } finally { 5324 Binder.restoreCallingIdentity(ident); 5325 } 5326 } 5327 5328 /** 5329 * Callback that arrives when a PendingIntent alarm has finished delivery 5330 */ 5331 @Override onSendFinished(PendingIntent pi, Intent intent, int resultCode, String resultData, Bundle resultExtras)5332 public void onSendFinished(PendingIntent pi, Intent intent, int resultCode, 5333 String resultData, Bundle resultExtras) { 5334 synchronized (mLock) { 5335 mSendFinishCount++; 5336 updateTrackingLocked(removeLocked(pi, intent)); 5337 } 5338 } 5339 5340 /** 5341 * Timeout of a direct-call alarm delivery 5342 */ alarmTimedOut(IBinder who)5343 public void alarmTimedOut(IBinder who) { 5344 synchronized (mLock) { 5345 InFlight inflight = removeLocked(who); 5346 if (inflight != null) { 5347 // TODO: implement ANR policy for the target 5348 if (DEBUG_LISTENER_CALLBACK) { 5349 Slog.i(TAG, "Alarm listener " + who + " timed out in delivery"); 5350 } 5351 updateTrackingLocked(inflight); 5352 mListenerFinishCount++; 5353 } else { 5354 if (DEBUG_LISTENER_CALLBACK) { 5355 Slog.i(TAG, "Spurious timeout of listener " + who); 5356 } 5357 mLog.w("Spurious timeout of listener " + who); 5358 } 5359 } 5360 } 5361 5362 /** 5363 * Deliver an alarm and set up the post-delivery handling appropriately 5364 */ 5365 @GuardedBy("mLock") deliverLocked(Alarm alarm, long nowELAPSED)5366 public void deliverLocked(Alarm alarm, long nowELAPSED) { 5367 final long workSourceToken = ThreadLocalWorkSource.setUid( 5368 getAlarmAttributionUid(alarm)); 5369 try { 5370 if (alarm.operation != null) { 5371 // PendingIntent alarm 5372 mSendCount++; 5373 5374 try { 5375 final Bundle bundle = getAlarmOperationBundle(alarm); 5376 alarm.operation.send(getContext(), 0, 5377 mBackgroundIntent.putExtra(Intent.EXTRA_ALARM_COUNT, alarm.count), 5378 mDeliveryTracker, mHandler, null, bundle); 5379 } catch (PendingIntent.CanceledException e) { 5380 if (alarm.repeatInterval > 0) { 5381 // This IntentSender is no longer valid, but this 5382 // is a repeating alarm, so toss it 5383 removeImpl(alarm.operation, null); 5384 } 5385 // No actual delivery was possible, so the delivery tracker's 5386 // 'finished' callback won't be invoked. We also don't need 5387 // to do any wakelock or stats tracking, so we have nothing 5388 // left to do here but go on to the next thing. 5389 mSendFinishCount++; 5390 return; 5391 } 5392 } else { 5393 // Direct listener callback alarm 5394 mListenerCount++; 5395 5396 alarm.listener.asBinder().unlinkToDeath(mListenerDeathRecipient, 0); 5397 5398 if (RECORD_ALARMS_IN_HISTORY) { 5399 if (alarm.listener == mTimeTickTrigger) { 5400 mTickHistory[mNextTickHistory++] = nowELAPSED; 5401 if (mNextTickHistory >= TICK_HISTORY_DEPTH) { 5402 mNextTickHistory = 0; 5403 } 5404 } 5405 } 5406 5407 try { 5408 if (DEBUG_LISTENER_CALLBACK) { 5409 Slog.v(TAG, "Alarm to uid=" + alarm.uid 5410 + " listener=" + alarm.listener.asBinder()); 5411 } 5412 alarm.listener.doAlarm(this); 5413 mHandler.sendMessageDelayed( 5414 mHandler.obtainMessage(AlarmHandler.LISTENER_TIMEOUT, 5415 alarm.listener.asBinder()), 5416 mConstants.LISTENER_TIMEOUT); 5417 } catch (Exception e) { 5418 if (DEBUG_LISTENER_CALLBACK) { 5419 Slog.i(TAG, "Alarm undeliverable to listener " 5420 + alarm.listener.asBinder(), e); 5421 } 5422 // As in the PendingIntent.CanceledException case, delivery of the 5423 // alarm was not possible, so we have no wakelock or timeout or 5424 // stats management to do. It threw before we posted the delayed 5425 // timeout message, so we're done here. 5426 mListenerFinishCount++; 5427 return; 5428 } 5429 } 5430 } finally { 5431 ThreadLocalWorkSource.restore(workSourceToken); 5432 } 5433 5434 // The alarm is now in flight; now arrange wakelock and stats tracking 5435 if (DEBUG_WAKELOCK) { 5436 Slog.d(TAG, "mBroadcastRefCount -> " + (mBroadcastRefCount + 1)); 5437 } 5438 if (mBroadcastRefCount == 0) { 5439 setWakelockWorkSource(alarm.workSource, alarm.creatorUid, alarm.statsTag, true); 5440 mWakeLock.acquire(); 5441 mHandler.obtainMessage(AlarmHandler.REPORT_ALARMS_ACTIVE, 1, 0).sendToTarget(); 5442 } 5443 final InFlight inflight = new InFlight(AlarmManagerService.this, alarm, nowELAPSED); 5444 mInFlight.add(inflight); 5445 mBroadcastRefCount++; 5446 if (inflight.isBroadcast()) { 5447 notifyBroadcastAlarmPendingLocked(alarm.uid); 5448 } 5449 final boolean doze = (mPendingIdleUntil != null); 5450 final boolean batterySaver = (mAppStateTracker != null 5451 && mAppStateTracker.isForceAllAppsStandbyEnabled()); 5452 if (doze || batterySaver) { 5453 if (isAllowedWhileIdleRestricted(alarm)) { 5454 // Record the last time this uid handled an ALLOW_WHILE_IDLE alarm while the 5455 // device was in doze or battery saver. 5456 final AppWakeupHistory history = ((alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0) 5457 ? mAllowWhileIdleHistory 5458 : mAllowWhileIdleCompatHistory; 5459 history.recordAlarmForPackage(alarm.sourcePackage, 5460 UserHandle.getUserId(alarm.creatorUid), nowELAPSED); 5461 mAlarmStore.updateAlarmDeliveries(a -> { 5462 if (a.creatorUid != alarm.creatorUid || !isAllowedWhileIdleRestricted(a)) { 5463 return false; 5464 } 5465 final boolean dozeAdjusted = doze && adjustDeliveryTimeBasedOnDeviceIdle(a); 5466 final boolean batterySaverAdjusted = 5467 batterySaver && adjustDeliveryTimeBasedOnBatterySaver(a); 5468 return dozeAdjusted || batterySaverAdjusted; 5469 }); 5470 } else if ((alarm.flags & FLAG_PRIORITIZE) != 0) { 5471 mLastPriorityAlarmDispatch.put(alarm.creatorUid, nowELAPSED); 5472 mAlarmStore.updateAlarmDeliveries(a -> { 5473 if (a.creatorUid != alarm.creatorUid 5474 || (alarm.flags & FLAG_PRIORITIZE) == 0) { 5475 return false; 5476 } 5477 final boolean dozeAdjusted = doze && adjustDeliveryTimeBasedOnDeviceIdle(a); 5478 final boolean batterySaverAdjusted = 5479 batterySaver && adjustDeliveryTimeBasedOnBatterySaver(a); 5480 return dozeAdjusted || batterySaverAdjusted; 5481 }); 5482 } 5483 if (RECORD_DEVICE_IDLE_ALARMS) { 5484 IdleDispatchEntry ent = new IdleDispatchEntry(); 5485 ent.uid = alarm.uid; 5486 ent.pkg = alarm.packageName; 5487 ent.tag = alarm.statsTag; 5488 ent.op = "DELIVER"; 5489 ent.elapsedRealtime = nowELAPSED; 5490 mAllowWhileIdleDispatches.add(ent); 5491 } 5492 } 5493 if (!isExemptFromAppStandby(alarm)) { 5494 final int userId = UserHandle.getUserId(alarm.creatorUid); 5495 if (alarm.mUsingReserveQuota) { 5496 mTemporaryQuotaReserve.recordUsage(alarm.sourcePackage, userId, nowELAPSED); 5497 } else { 5498 mAppWakeupHistory.recordAlarmForPackage(alarm.sourcePackage, userId, 5499 nowELAPSED); 5500 } 5501 } 5502 final BroadcastStats bs = inflight.mBroadcastStats; 5503 bs.count++; 5504 if (bs.nesting == 0) { 5505 bs.nesting = 1; 5506 bs.startTime = nowELAPSED; 5507 } else { 5508 bs.nesting++; 5509 } 5510 final FilterStats fs = inflight.mFilterStats; 5511 fs.count++; 5512 if (fs.nesting == 0) { 5513 fs.nesting = 1; 5514 fs.startTime = nowELAPSED; 5515 } else { 5516 fs.nesting++; 5517 } 5518 if (alarm.type == ELAPSED_REALTIME_WAKEUP 5519 || alarm.type == RTC_WAKEUP) { 5520 bs.numWakeup++; 5521 fs.numWakeup++; 5522 mActivityManagerInternal.noteWakeupAlarm( 5523 alarm.operation, alarm.workSource, alarm.uid, alarm.packageName, 5524 alarm.statsTag); 5525 } 5526 } 5527 } 5528 incrementAlarmCount(int uid)5529 private void incrementAlarmCount(int uid) { 5530 increment(mAlarmsPerUid, uid); 5531 } 5532 5533 /** 5534 * Send {@link AlarmManager#ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED} to 5535 * the app that is just granted the permission. 5536 */ sendScheduleExactAlarmPermissionStateChangedBroadcast( String packageName, int userId)5537 private void sendScheduleExactAlarmPermissionStateChangedBroadcast( 5538 String packageName, int userId) { 5539 final Intent i = new Intent( 5540 AlarmManager.ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED); 5541 i.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING 5542 | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT 5543 | Intent.FLAG_RECEIVER_FOREGROUND); 5544 i.setPackage(packageName); 5545 5546 // We need to allow the app to start a foreground service. 5547 // This broadcast is very rare, so we do not cache the BroadcastOptions. 5548 final BroadcastOptions opts = BroadcastOptions.makeBasic(); 5549 opts.setTemporaryAppAllowlist( 5550 mActivityManagerInternal.getBootTimeTempAllowListDuration(), 5551 TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, 5552 REASON_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED, ""); 5553 getContext().sendBroadcastAsUser(i, UserHandle.of(userId), /*permission*/ null, 5554 opts.toBundle()); 5555 } 5556 decrementAlarmCount(int uid, int decrement)5557 private void decrementAlarmCount(int uid, int decrement) { 5558 int oldCount = 0; 5559 final int uidIndex = mAlarmsPerUid.indexOfKey(uid); 5560 if (uidIndex >= 0) { 5561 oldCount = mAlarmsPerUid.valueAt(uidIndex); 5562 if (oldCount > decrement) { 5563 mAlarmsPerUid.setValueAt(uidIndex, oldCount - decrement); 5564 } else { 5565 mAlarmsPerUid.removeAt(uidIndex); 5566 } 5567 } 5568 if (oldCount < decrement) { 5569 Slog.wtf(TAG, "Attempt to decrement existing alarm count " + oldCount + " by " 5570 + decrement + " for uid " + uid); 5571 } 5572 } 5573 5574 private class ShellCmd extends ShellCommand { 5575 getBinderService()5576 IAlarmManager getBinderService() { 5577 return IAlarmManager.Stub.asInterface(mService); 5578 } 5579 5580 @Override onCommand(String cmd)5581 public int onCommand(String cmd) { 5582 if (cmd == null) { 5583 return handleDefaultCommands(cmd); 5584 } 5585 5586 final PrintWriter pw = getOutPrintWriter(); 5587 try { 5588 switch (cmd) { 5589 case "set-time": 5590 final long millis = Long.parseLong(getNextArgRequired()); 5591 return (getBinderService().setTime(millis)) ? 0 : -1; 5592 case "set-timezone": 5593 final String tz = getNextArgRequired(); 5594 getBinderService().setTimeZone(tz); 5595 return 0; 5596 case "get-config-version": 5597 final int version = getBinderService().getConfigVersion(); 5598 pw.println(version); 5599 return 0; 5600 default: 5601 return handleDefaultCommands(cmd); 5602 } 5603 } catch (Exception e) { 5604 pw.println(e); 5605 } 5606 return -1; 5607 } 5608 5609 @Override onHelp()5610 public void onHelp() { 5611 PrintWriter pw = getOutPrintWriter(); 5612 pw.println("Alarm manager service (alarm) commands:"); 5613 pw.println(" help"); 5614 pw.println(" Print this help text."); 5615 pw.println(" set-time TIME"); 5616 pw.println(" Set the system clock time to TIME where TIME is milliseconds"); 5617 pw.println(" since the Epoch."); 5618 pw.println(" set-timezone TZ"); 5619 pw.println(" Set the system timezone to TZ where TZ is an Olson id."); 5620 pw.println(" get-config-version"); 5621 pw.println(" Returns an integer denoting the version of device_config keys the" 5622 + " service is sync'ed to. As long as this returns the same version, the values" 5623 + " of the config are guaranteed to remain the same."); 5624 } 5625 } 5626 } 5627