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