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