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