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; 18 19 import static android.app.AlarmManager.ELAPSED_REALTIME; 20 import static android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP; 21 import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE; 22 import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED; 23 import static android.app.AlarmManager.RTC; 24 import static android.app.AlarmManager.RTC_WAKEUP; 25 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; 26 import static android.os.UserHandle.USER_SYSTEM; 27 28 import android.annotation.UserIdInt; 29 import android.app.Activity; 30 import android.app.ActivityManager; 31 import android.app.AlarmManager; 32 import android.app.AppOpsManager; 33 import android.app.BroadcastOptions; 34 import android.app.IAlarmCompleteListener; 35 import android.app.IAlarmListener; 36 import android.app.IAlarmManager; 37 import android.app.IUidObserver; 38 import android.app.PendingIntent; 39 import android.app.usage.UsageStatsManager; 40 import android.app.usage.UsageStatsManagerInternal; 41 import android.content.BroadcastReceiver; 42 import android.content.ContentResolver; 43 import android.content.Context; 44 import android.content.Intent; 45 import android.content.IntentFilter; 46 import android.content.pm.PackageManagerInternal; 47 import android.database.ContentObserver; 48 import android.net.Uri; 49 import android.os.BatteryManager; 50 import android.os.Binder; 51 import android.os.Build; 52 import android.os.Bundle; 53 import android.os.Environment; 54 import android.os.Handler; 55 import android.os.IBinder; 56 import android.os.Looper; 57 import android.os.Message; 58 import android.os.ParcelableException; 59 import android.os.PowerManager; 60 import android.os.Process; 61 import android.os.RemoteException; 62 import android.os.ResultReceiver; 63 import android.os.ShellCallback; 64 import android.os.ShellCommand; 65 import android.os.SystemClock; 66 import android.os.SystemProperties; 67 import android.os.ThreadLocalWorkSource; 68 import android.os.Trace; 69 import android.os.UserHandle; 70 import android.os.WorkSource; 71 import android.provider.Settings; 72 import android.system.Os; 73 import android.text.TextUtils; 74 import android.text.format.DateFormat; 75 import android.text.format.DateUtils; 76 import android.util.ArrayMap; 77 import android.util.ArraySet; 78 import android.util.KeyValueListParser; 79 import android.util.Log; 80 import android.util.LongArrayQueue; 81 import android.util.MutableBoolean; 82 import android.util.NtpTrustedTime; 83 import android.util.Pair; 84 import android.util.Slog; 85 import android.util.SparseArray; 86 import android.util.SparseBooleanArray; 87 import android.util.SparseIntArray; 88 import android.util.SparseLongArray; 89 import android.util.TimeUtils; 90 import android.util.proto.ProtoOutputStream; 91 92 import com.android.internal.annotations.GuardedBy; 93 import com.android.internal.annotations.VisibleForTesting; 94 import com.android.internal.util.ArrayUtils; 95 import com.android.internal.util.DumpUtils; 96 import com.android.internal.util.FrameworkStatsLog; 97 import com.android.internal.util.IndentingPrintWriter; 98 import com.android.internal.util.LocalLog; 99 import com.android.internal.util.StatLogger; 100 import com.android.server.AppStateTracker.Listener; 101 import com.android.server.usage.AppStandbyInternal; 102 import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener; 103 104 import java.io.ByteArrayOutputStream; 105 import java.io.FileDescriptor; 106 import java.io.PrintWriter; 107 import java.io.StringWriter; 108 import java.text.SimpleDateFormat; 109 import java.time.DateTimeException; 110 import java.util.ArrayList; 111 import java.util.Arrays; 112 import java.util.Calendar; 113 import java.util.Collections; 114 import java.util.Comparator; 115 import java.util.Date; 116 import java.util.HashMap; 117 import java.util.LinkedList; 118 import java.util.Locale; 119 import java.util.Random; 120 import java.util.TimeZone; 121 import java.util.TreeSet; 122 import java.util.function.Predicate; 123 124 /** 125 * Alarm manager implementation. 126 * 127 * Unit test: 128 atest $ANDROID_BUILD_TOP/frameworks/base/services/tests/servicestests/src/com/android/server/AlarmManagerServiceTest.java 129 */ 130 class AlarmManagerService extends SystemService { 131 private static final int RTC_WAKEUP_MASK = 1 << RTC_WAKEUP; 132 private static final int RTC_MASK = 1 << RTC; 133 private static final int ELAPSED_REALTIME_WAKEUP_MASK = 1 << ELAPSED_REALTIME_WAKEUP; 134 private static final int ELAPSED_REALTIME_MASK = 1 << ELAPSED_REALTIME; 135 static final int TIME_CHANGED_MASK = 1 << 16; 136 static final int IS_WAKEUP_MASK = RTC_WAKEUP_MASK|ELAPSED_REALTIME_WAKEUP_MASK; 137 138 // Mask for testing whether a given alarm type is wakeup vs non-wakeup 139 static final int TYPE_NONWAKEUP_MASK = 0x1; // low bit => non-wakeup 140 141 static final String TAG = "AlarmManager"; 142 static final boolean localLOGV = false; 143 static final boolean DEBUG_BATCH = localLOGV || false; 144 static final boolean DEBUG_VALIDATE = localLOGV || false; 145 static final boolean DEBUG_ALARM_CLOCK = localLOGV || false; 146 static final boolean DEBUG_LISTENER_CALLBACK = localLOGV || false; 147 static final boolean DEBUG_WAKELOCK = localLOGV || false; 148 static final boolean DEBUG_BG_LIMIT = localLOGV || false; 149 static final boolean DEBUG_STANDBY = localLOGV || false; 150 151 // TODO (b/157782538): Turn off once bug is fixed. 152 static final boolean DEBUG_PER_UID_LIMIT = true; 153 154 static final boolean RECORD_ALARMS_IN_HISTORY = true; 155 static final boolean RECORD_DEVICE_IDLE_ALARMS = false; 156 static final String TIMEZONE_PROPERTY = "persist.sys.timezone"; 157 158 static final int TICK_HISTORY_DEPTH = 10; 159 static final long MILLIS_IN_DAY = 24 * 60 * 60 * 1000; 160 161 // Indices into the KEYS_APP_STANDBY_QUOTAS array. 162 static final int ACTIVE_INDEX = 0; 163 static final int WORKING_INDEX = 1; 164 static final int FREQUENT_INDEX = 2; 165 static final int RARE_INDEX = 3; 166 static final int NEVER_INDEX = 4; 167 168 private final Intent mBackgroundIntent 169 = new Intent().addFlags(Intent.FLAG_FROM_BACKGROUND); 170 static final IncreasingTimeOrder sIncreasingTimeOrder = new IncreasingTimeOrder(); 171 172 static final boolean WAKEUP_STATS = false; 173 174 private static final Intent NEXT_ALARM_CLOCK_CHANGED_INTENT = 175 new Intent(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED) 176 .addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING 177 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); 178 179 final LocalLog mLog = new LocalLog(TAG); 180 181 AppOpsManager mAppOps; 182 DeviceIdleInternal mLocalDeviceIdleController; 183 private UsageStatsManagerInternal mUsageStatsManagerInternal; 184 185 final Object mLock = new Object(); 186 187 // List of alarms per uid deferred due to user applied background restrictions on the source app 188 SparseArray<ArrayList<Alarm>> mPendingBackgroundAlarms = new SparseArray<>(); 189 private long mNextWakeup; 190 private long mNextNonWakeup; 191 private long mNextWakeUpSetAt; 192 private long mNextNonWakeUpSetAt; 193 private long mLastWakeup; 194 private long mLastTrigger; 195 196 private long mLastTickSet; 197 private long mLastTickReceived; 198 private long mLastTickAdded; 199 private long mLastTickRemoved; 200 // ring buffer of recent TIME_TICK issuance, in the elapsed timebase 201 private final long[] mTickHistory = new long[TICK_HISTORY_DEPTH]; 202 private int mNextTickHistory; 203 204 private final Injector mInjector; 205 int mBroadcastRefCount = 0; 206 PowerManager.WakeLock mWakeLock; 207 SparseIntArray mAlarmsPerUid = new SparseIntArray(); 208 ArrayList<Alarm> mPendingNonWakeupAlarms = new ArrayList<>(); 209 ArrayList<InFlight> mInFlight = new ArrayList<>(); 210 private final ArrayList<AlarmManagerInternal.InFlightListener> mInFlightListeners = 211 new ArrayList<>(); 212 AlarmHandler mHandler; 213 AppWakeupHistory mAppWakeupHistory; 214 ClockReceiver mClockReceiver; 215 final DeliveryTracker mDeliveryTracker = new DeliveryTracker(); 216 IBinder.DeathRecipient mListenerDeathRecipient; 217 Intent mTimeTickIntent; 218 IAlarmListener mTimeTickTrigger; 219 PendingIntent mDateChangeSender; 220 Random mRandom; 221 boolean mInteractive = true; 222 long mNonInteractiveStartTime; 223 long mNonInteractiveTime; 224 long mLastAlarmDeliveryTime; 225 long mStartCurrentDelayTime; 226 long mNextNonWakeupDeliveryTime; 227 long mLastTimeChangeClockTime; 228 long mLastTimeChangeRealtime; 229 int mNumTimeChanged; 230 231 /** 232 * At boot we use SYSTEM_UI_SELF_PERMISSION to look up the definer's uid. 233 */ 234 int mSystemUiUid; 235 236 /** 237 * For each uid, this is the last time we dispatched an "allow while idle" alarm, 238 * used to determine the earliest we can dispatch the next such alarm. Times are in the 239 * 'elapsed' timebase. 240 */ 241 final SparseLongArray mLastAllowWhileIdleDispatch = new SparseLongArray(); 242 243 /** 244 * For each uid, we store whether the last allow-while-idle alarm was dispatched while 245 * the uid was in foreground or not. We will use the allow_while_idle_short_time in such cases. 246 */ 247 final SparseBooleanArray mUseAllowWhileIdleShortTime = new SparseBooleanArray(); 248 249 final static class IdleDispatchEntry { 250 int uid; 251 String pkg; 252 String tag; 253 String op; 254 long elapsedRealtime; 255 long argRealtime; 256 } 257 final ArrayList<IdleDispatchEntry> mAllowWhileIdleDispatches = new ArrayList(); 258 259 interface Stats { 260 int REBATCH_ALL_ALARMS = 0; 261 int REORDER_ALARMS_FOR_STANDBY = 1; 262 } 263 264 private final StatLogger mStatLogger = new StatLogger(new String[] { 265 "REBATCH_ALL_ALARMS", 266 "REORDER_ALARMS_FOR_STANDBY", 267 }); 268 269 /** 270 * Broadcast options to use for FLAG_ALLOW_WHILE_IDLE. 271 */ 272 Bundle mIdleOptions; 273 274 private final SparseArray<AlarmManager.AlarmClockInfo> mNextAlarmClockForUser = 275 new SparseArray<>(); 276 private final SparseArray<AlarmManager.AlarmClockInfo> mTmpSparseAlarmClockArray = 277 new SparseArray<>(); 278 private final SparseBooleanArray mPendingSendNextAlarmClockChangedForUser = 279 new SparseBooleanArray(); 280 private boolean mNextAlarmClockMayChange; 281 282 // May only use on mHandler's thread, locking not required. 283 private final SparseArray<AlarmManager.AlarmClockInfo> mHandlerSparseAlarmClockArray = 284 new SparseArray<>(); 285 286 private AppStateTracker mAppStateTracker; 287 private boolean mAppStandbyParole; 288 289 /** 290 * A rolling window history of previous times when an alarm was sent to a package. 291 */ 292 private static class AppWakeupHistory { 293 private ArrayMap<Pair<String, Integer>, LongArrayQueue> mPackageHistory = 294 new ArrayMap<>(); 295 private long mWindowSize; 296 AppWakeupHistory(long windowSize)297 AppWakeupHistory(long windowSize) { 298 mWindowSize = windowSize; 299 } 300 recordAlarmForPackage(String packageName, int userId, long nowElapsed)301 void recordAlarmForPackage(String packageName, int userId, long nowElapsed) { 302 final Pair<String, Integer> packageUser = Pair.create(packageName, userId); 303 LongArrayQueue history = mPackageHistory.get(packageUser); 304 if (history == null) { 305 history = new LongArrayQueue(); 306 mPackageHistory.put(packageUser, history); 307 } 308 if (history.size() == 0 || history.peekLast() < nowElapsed) { 309 history.addLast(nowElapsed); 310 } 311 snapToWindow(history); 312 } 313 removeForUser(int userId)314 void removeForUser(int userId) { 315 for (int i = mPackageHistory.size() - 1; i >= 0; i--) { 316 final Pair<String, Integer> packageUserKey = mPackageHistory.keyAt(i); 317 if (packageUserKey.second == userId) { 318 mPackageHistory.removeAt(i); 319 } 320 } 321 } 322 removeForPackage(String packageName, int userId)323 void removeForPackage(String packageName, int userId) { 324 final Pair<String, Integer> packageUser = Pair.create(packageName, userId); 325 mPackageHistory.remove(packageUser); 326 } 327 snapToWindow(LongArrayQueue history)328 private void snapToWindow(LongArrayQueue history) { 329 while (history.peekFirst() + mWindowSize < history.peekLast()) { 330 history.removeFirst(); 331 } 332 } 333 getTotalWakeupsInWindow(String packageName, int userId)334 int getTotalWakeupsInWindow(String packageName, int userId) { 335 final LongArrayQueue history = mPackageHistory.get(Pair.create(packageName, userId)); 336 return (history == null) ? 0 : history.size(); 337 } 338 339 /** 340 * @param n The desired nth-last wakeup 341 * (1=1st-last=the ultimate wakeup and 2=2nd-last=the penultimate wakeup) 342 */ getNthLastWakeupForPackage(String packageName, int userId, int n)343 long getNthLastWakeupForPackage(String packageName, int userId, int n) { 344 final LongArrayQueue history = mPackageHistory.get(Pair.create(packageName, userId)); 345 if (history == null) { 346 return 0; 347 } 348 final int i = history.size() - n; 349 return (i < 0) ? 0 : history.get(i); 350 } 351 dump(PrintWriter pw, String prefix, long nowElapsed)352 void dump(PrintWriter pw, String prefix, long nowElapsed) { 353 dump(new IndentingPrintWriter(pw, " ").setIndent(prefix), nowElapsed); 354 } 355 dump(IndentingPrintWriter pw, long nowElapsed)356 void dump(IndentingPrintWriter pw, long nowElapsed) { 357 pw.println("App Alarm history:"); 358 pw.increaseIndent(); 359 for (int i = 0; i < mPackageHistory.size(); i++) { 360 final Pair<String, Integer> packageUser = mPackageHistory.keyAt(i); 361 final LongArrayQueue timestamps = mPackageHistory.valueAt(i); 362 pw.print(packageUser.first); 363 pw.print(", u"); 364 pw.print(packageUser.second); 365 pw.print(": "); 366 // limit dumping to a max of 100 values 367 final int lastIdx = Math.max(0, timestamps.size() - 100); 368 for (int j = timestamps.size() - 1; j >= lastIdx; j--) { 369 TimeUtils.formatDuration(timestamps.get(j), nowElapsed, pw); 370 pw.print(", "); 371 } 372 pw.println(); 373 } 374 pw.decreaseIndent(); 375 } 376 } 377 378 /** 379 * All times are in milliseconds. These constants are kept synchronized with the system 380 * global Settings. Any access to this class or its fields should be done while 381 * holding the AlarmManagerService.mLock lock. 382 */ 383 @VisibleForTesting 384 final class Constants extends ContentObserver { 385 // Key names stored in the settings value. 386 @VisibleForTesting 387 static final String KEY_MIN_FUTURITY = "min_futurity"; 388 @VisibleForTesting 389 static final String KEY_MIN_INTERVAL = "min_interval"; 390 @VisibleForTesting 391 static final String KEY_MAX_INTERVAL = "max_interval"; 392 @VisibleForTesting 393 static final String KEY_ALLOW_WHILE_IDLE_SHORT_TIME = "allow_while_idle_short_time"; 394 @VisibleForTesting 395 static final String KEY_ALLOW_WHILE_IDLE_LONG_TIME = "allow_while_idle_long_time"; 396 @VisibleForTesting 397 static final String KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION 398 = "allow_while_idle_whitelist_duration"; 399 @VisibleForTesting 400 static final String KEY_LISTENER_TIMEOUT = "listener_timeout"; 401 @VisibleForTesting 402 static final String KEY_MAX_ALARMS_PER_UID = "max_alarms_per_uid"; 403 private static final String KEY_APP_STANDBY_WINDOW = "app_standby_window"; 404 @VisibleForTesting 405 final String[] KEYS_APP_STANDBY_QUOTAS = { 406 "standby_active_quota", 407 "standby_working_quota", 408 "standby_frequent_quota", 409 "standby_rare_quota", 410 "standby_never_quota", 411 }; 412 // Not putting this in the KEYS_APP_STANDBY_QUOTAS array because this uses a different 413 // window size. 414 private static final String KEY_APP_STANDBY_RESTRICTED_QUOTA = "standby_restricted_quota"; 415 private static final String KEY_APP_STANDBY_RESTRICTED_WINDOW = 416 "app_standby_restricted_window"; 417 418 private static final long DEFAULT_MIN_FUTURITY = 5 * 1000; 419 private static final long DEFAULT_MIN_INTERVAL = 60 * 1000; 420 private static final long DEFAULT_MAX_INTERVAL = 365 * DateUtils.DAY_IN_MILLIS; 421 private static final long DEFAULT_ALLOW_WHILE_IDLE_SHORT_TIME = DEFAULT_MIN_FUTURITY; 422 private static final long DEFAULT_ALLOW_WHILE_IDLE_LONG_TIME = 9*60*1000; 423 private static final long DEFAULT_ALLOW_WHILE_IDLE_WHITELIST_DURATION = 10*1000; 424 private static final long DEFAULT_LISTENER_TIMEOUT = 5 * 1000; 425 private static final int DEFAULT_MAX_ALARMS_PER_UID = 500; 426 private static final long DEFAULT_APP_STANDBY_WINDOW = 60 * 60 * 1000; // 1 hr 427 /** 428 * Max number of times an app can receive alarms in {@link #APP_STANDBY_WINDOW} 429 */ 430 private final int[] DEFAULT_APP_STANDBY_QUOTAS = { 431 720, // Active 432 10, // Working 433 2, // Frequent 434 1, // Rare 435 0 // Never 436 }; 437 private static final int DEFAULT_APP_STANDBY_RESTRICTED_QUOTA = 1; 438 private static final long DEFAULT_APP_STANDBY_RESTRICTED_WINDOW = MILLIS_IN_DAY; 439 440 // Minimum futurity of a new alarm 441 public long MIN_FUTURITY = DEFAULT_MIN_FUTURITY; 442 443 // Minimum alarm recurrence interval 444 public long MIN_INTERVAL = DEFAULT_MIN_INTERVAL; 445 446 // Maximum alarm recurrence interval 447 public long MAX_INTERVAL = DEFAULT_MAX_INTERVAL; 448 449 // Minimum time between ALLOW_WHILE_IDLE alarms when system is not idle. 450 public long ALLOW_WHILE_IDLE_SHORT_TIME = DEFAULT_ALLOW_WHILE_IDLE_SHORT_TIME; 451 452 // Minimum time between ALLOW_WHILE_IDLE alarms when system is idling. 453 public long ALLOW_WHILE_IDLE_LONG_TIME = DEFAULT_ALLOW_WHILE_IDLE_LONG_TIME; 454 455 // BroadcastOptions.setTemporaryAppWhitelistDuration() to use for FLAG_ALLOW_WHILE_IDLE. 456 public long ALLOW_WHILE_IDLE_WHITELIST_DURATION 457 = DEFAULT_ALLOW_WHILE_IDLE_WHITELIST_DURATION; 458 459 // Direct alarm listener callback timeout 460 public long LISTENER_TIMEOUT = DEFAULT_LISTENER_TIMEOUT; 461 public int MAX_ALARMS_PER_UID = DEFAULT_MAX_ALARMS_PER_UID; 462 463 public long APP_STANDBY_WINDOW = DEFAULT_APP_STANDBY_WINDOW; 464 public int[] APP_STANDBY_QUOTAS = new int[DEFAULT_APP_STANDBY_QUOTAS.length]; 465 public int APP_STANDBY_RESTRICTED_QUOTA = DEFAULT_APP_STANDBY_RESTRICTED_QUOTA; 466 public long APP_STANDBY_RESTRICTED_WINDOW = DEFAULT_APP_STANDBY_RESTRICTED_WINDOW; 467 468 private ContentResolver mResolver; 469 private final KeyValueListParser mParser = new KeyValueListParser(','); 470 private long mLastAllowWhileIdleWhitelistDuration = -1; 471 Constants(Handler handler)472 public Constants(Handler handler) { 473 super(handler); 474 updateAllowWhileIdleWhitelistDurationLocked(); 475 } 476 start(ContentResolver resolver)477 public void start(ContentResolver resolver) { 478 mResolver = resolver; 479 mResolver.registerContentObserver(Settings.Global.getUriFor( 480 Settings.Global.ALARM_MANAGER_CONSTANTS), false, this); 481 updateConstants(); 482 } 483 updateAllowWhileIdleWhitelistDurationLocked()484 public void updateAllowWhileIdleWhitelistDurationLocked() { 485 if (mLastAllowWhileIdleWhitelistDuration != ALLOW_WHILE_IDLE_WHITELIST_DURATION) { 486 mLastAllowWhileIdleWhitelistDuration = ALLOW_WHILE_IDLE_WHITELIST_DURATION; 487 BroadcastOptions opts = BroadcastOptions.makeBasic(); 488 opts.setTemporaryAppWhitelistDuration(ALLOW_WHILE_IDLE_WHITELIST_DURATION); 489 mIdleOptions = opts.toBundle(); 490 } 491 } 492 493 @Override onChange(boolean selfChange, Uri uri)494 public void onChange(boolean selfChange, Uri uri) { 495 updateConstants(); 496 } 497 updateConstants()498 private void updateConstants() { 499 synchronized (mLock) { 500 try { 501 mParser.setString(Settings.Global.getString(mResolver, 502 Settings.Global.ALARM_MANAGER_CONSTANTS)); 503 } catch (IllegalArgumentException e) { 504 // Failed to parse the settings string, log this and move on 505 // with defaults. 506 Slog.e(TAG, "Bad alarm manager settings", e); 507 } 508 509 MIN_FUTURITY = mParser.getLong(KEY_MIN_FUTURITY, DEFAULT_MIN_FUTURITY); 510 MIN_INTERVAL = mParser.getLong(KEY_MIN_INTERVAL, DEFAULT_MIN_INTERVAL); 511 MAX_INTERVAL = mParser.getLong(KEY_MAX_INTERVAL, DEFAULT_MAX_INTERVAL); 512 ALLOW_WHILE_IDLE_SHORT_TIME = mParser.getLong(KEY_ALLOW_WHILE_IDLE_SHORT_TIME, 513 DEFAULT_ALLOW_WHILE_IDLE_SHORT_TIME); 514 ALLOW_WHILE_IDLE_LONG_TIME = mParser.getLong(KEY_ALLOW_WHILE_IDLE_LONG_TIME, 515 DEFAULT_ALLOW_WHILE_IDLE_LONG_TIME); 516 ALLOW_WHILE_IDLE_WHITELIST_DURATION = mParser.getLong( 517 KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION, 518 DEFAULT_ALLOW_WHILE_IDLE_WHITELIST_DURATION); 519 LISTENER_TIMEOUT = mParser.getLong(KEY_LISTENER_TIMEOUT, 520 DEFAULT_LISTENER_TIMEOUT); 521 522 APP_STANDBY_WINDOW = mParser.getLong(KEY_APP_STANDBY_WINDOW, 523 DEFAULT_APP_STANDBY_WINDOW); 524 if (APP_STANDBY_WINDOW > DEFAULT_APP_STANDBY_WINDOW) { 525 Slog.w(TAG, "Cannot exceed the app_standby_window size of " 526 + DEFAULT_APP_STANDBY_WINDOW); 527 APP_STANDBY_WINDOW = DEFAULT_APP_STANDBY_WINDOW; 528 } else if (APP_STANDBY_WINDOW < DEFAULT_APP_STANDBY_WINDOW) { 529 // Not recommended outside of testing. 530 Slog.w(TAG, "Using a non-default app_standby_window of " + APP_STANDBY_WINDOW); 531 } 532 533 APP_STANDBY_QUOTAS[ACTIVE_INDEX] = mParser.getInt( 534 KEYS_APP_STANDBY_QUOTAS[ACTIVE_INDEX], 535 DEFAULT_APP_STANDBY_QUOTAS[ACTIVE_INDEX]); 536 for (int i = WORKING_INDEX; i < KEYS_APP_STANDBY_QUOTAS.length; i++) { 537 APP_STANDBY_QUOTAS[i] = mParser.getInt(KEYS_APP_STANDBY_QUOTAS[i], 538 Math.min(APP_STANDBY_QUOTAS[i - 1], DEFAULT_APP_STANDBY_QUOTAS[i])); 539 } 540 541 APP_STANDBY_RESTRICTED_QUOTA = Math.max(1, 542 mParser.getInt(KEY_APP_STANDBY_RESTRICTED_QUOTA, 543 DEFAULT_APP_STANDBY_RESTRICTED_QUOTA)); 544 545 APP_STANDBY_RESTRICTED_WINDOW = Math.max(APP_STANDBY_WINDOW, 546 mParser.getLong(KEY_APP_STANDBY_RESTRICTED_WINDOW, 547 DEFAULT_APP_STANDBY_RESTRICTED_WINDOW)); 548 549 MAX_ALARMS_PER_UID = mParser.getInt(KEY_MAX_ALARMS_PER_UID, 550 DEFAULT_MAX_ALARMS_PER_UID); 551 if (MAX_ALARMS_PER_UID < DEFAULT_MAX_ALARMS_PER_UID) { 552 Slog.w(TAG, "Cannot set " + KEY_MAX_ALARMS_PER_UID + " lower than " 553 + DEFAULT_MAX_ALARMS_PER_UID); 554 MAX_ALARMS_PER_UID = DEFAULT_MAX_ALARMS_PER_UID; 555 } 556 557 updateAllowWhileIdleWhitelistDurationLocked(); 558 } 559 } 560 dump(PrintWriter pw, String prefix)561 void dump(PrintWriter pw, String prefix) { 562 dump(new IndentingPrintWriter(pw, " ").setIndent(prefix)); 563 } 564 dump(IndentingPrintWriter pw)565 void dump(IndentingPrintWriter pw) { 566 pw.println("Settings:"); 567 568 pw.increaseIndent(); 569 570 pw.print(KEY_MIN_FUTURITY); pw.print("="); 571 TimeUtils.formatDuration(MIN_FUTURITY, pw); 572 pw.println(); 573 574 pw.print(KEY_MIN_INTERVAL); pw.print("="); 575 TimeUtils.formatDuration(MIN_INTERVAL, pw); 576 pw.println(); 577 578 pw.print(KEY_MAX_INTERVAL); pw.print("="); 579 TimeUtils.formatDuration(MAX_INTERVAL, pw); 580 pw.println(); 581 582 pw.print(KEY_LISTENER_TIMEOUT); pw.print("="); 583 TimeUtils.formatDuration(LISTENER_TIMEOUT, pw); 584 pw.println(); 585 586 pw.print(KEY_ALLOW_WHILE_IDLE_SHORT_TIME); pw.print("="); 587 TimeUtils.formatDuration(ALLOW_WHILE_IDLE_SHORT_TIME, pw); 588 pw.println(); 589 590 pw.print(KEY_ALLOW_WHILE_IDLE_LONG_TIME); pw.print("="); 591 TimeUtils.formatDuration(ALLOW_WHILE_IDLE_LONG_TIME, pw); 592 pw.println(); 593 594 pw.print(KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION); pw.print("="); 595 TimeUtils.formatDuration(ALLOW_WHILE_IDLE_WHITELIST_DURATION, pw); 596 pw.println(); 597 598 pw.print(KEY_MAX_ALARMS_PER_UID); pw.print("="); 599 pw.println(MAX_ALARMS_PER_UID); 600 601 pw.print(KEY_APP_STANDBY_WINDOW); pw.print("="); 602 TimeUtils.formatDuration(APP_STANDBY_WINDOW, pw); 603 pw.println(); 604 605 for (int i = 0; i < KEYS_APP_STANDBY_QUOTAS.length; i++) { 606 pw.print(KEYS_APP_STANDBY_QUOTAS[i]); pw.print("="); 607 pw.println(APP_STANDBY_QUOTAS[i]); 608 } 609 610 pw.print(KEY_APP_STANDBY_RESTRICTED_QUOTA); pw.print("="); 611 pw.println(APP_STANDBY_RESTRICTED_QUOTA); 612 613 pw.print(KEY_APP_STANDBY_RESTRICTED_WINDOW); pw.print("="); 614 TimeUtils.formatDuration(APP_STANDBY_RESTRICTED_WINDOW, pw); 615 pw.println(); 616 617 pw.decreaseIndent(); 618 } 619 dumpProto(ProtoOutputStream proto, long fieldId)620 void dumpProto(ProtoOutputStream proto, long fieldId) { 621 final long token = proto.start(fieldId); 622 623 proto.write(ConstantsProto.MIN_FUTURITY_DURATION_MS, MIN_FUTURITY); 624 proto.write(ConstantsProto.MIN_INTERVAL_DURATION_MS, MIN_INTERVAL); 625 proto.write(ConstantsProto.MAX_INTERVAL_DURATION_MS, MAX_INTERVAL); 626 proto.write(ConstantsProto.LISTENER_TIMEOUT_DURATION_MS, LISTENER_TIMEOUT); 627 proto.write(ConstantsProto.ALLOW_WHILE_IDLE_SHORT_DURATION_MS, 628 ALLOW_WHILE_IDLE_SHORT_TIME); 629 proto.write(ConstantsProto.ALLOW_WHILE_IDLE_LONG_DURATION_MS, 630 ALLOW_WHILE_IDLE_LONG_TIME); 631 proto.write(ConstantsProto.ALLOW_WHILE_IDLE_WHITELIST_DURATION_MS, 632 ALLOW_WHILE_IDLE_WHITELIST_DURATION); 633 634 proto.end(token); 635 } 636 } 637 638 Constants mConstants; 639 640 // Alarm delivery ordering bookkeeping 641 static final int PRIO_TICK = 0; 642 static final int PRIO_WAKEUP = 1; 643 static final int PRIO_NORMAL = 2; 644 645 final class PriorityClass { 646 int seq; 647 int priority; 648 PriorityClass()649 PriorityClass() { 650 seq = mCurrentSeq - 1; 651 priority = PRIO_NORMAL; 652 } 653 } 654 655 final HashMap<String, PriorityClass> mPriorities = new HashMap<>(); 656 int mCurrentSeq = 0; 657 658 static final class WakeupEvent { 659 public long when; 660 public int uid; 661 public String action; 662 WakeupEvent(long theTime, int theUid, String theAction)663 public WakeupEvent(long theTime, int theUid, String theAction) { 664 when = theTime; 665 uid = theUid; 666 action = theAction; 667 } 668 } 669 670 final LinkedList<WakeupEvent> mRecentWakeups = new LinkedList<WakeupEvent>(); 671 final long RECENT_WAKEUP_PERIOD = 1000L * 60 * 60 * 24; // one day 672 673 final class Batch { 674 long start; // These endpoints are always in ELAPSED 675 long end; 676 int flags; // Flags for alarms, such as FLAG_STANDALONE. 677 678 final ArrayList<Alarm> alarms = new ArrayList<Alarm>(); 679 Batch(Alarm seed)680 Batch(Alarm seed) { 681 start = seed.whenElapsed; 682 end = clampPositive(seed.maxWhenElapsed); 683 flags = seed.flags; 684 alarms.add(seed); 685 if (seed.listener == mTimeTickTrigger) { 686 mLastTickAdded = mInjector.getCurrentTimeMillis(); 687 } 688 } 689 size()690 int size() { 691 return alarms.size(); 692 } 693 get(int index)694 Alarm get(int index) { 695 return alarms.get(index); 696 } 697 canHold(long whenElapsed, long maxWhen)698 boolean canHold(long whenElapsed, long maxWhen) { 699 return (end >= whenElapsed) && (start <= maxWhen); 700 } 701 add(Alarm alarm)702 boolean add(Alarm alarm) { 703 boolean newStart = false; 704 // narrows the batch if necessary; presumes that canHold(alarm) is true 705 int index = Collections.binarySearch(alarms, alarm, sIncreasingTimeOrder); 706 if (index < 0) { 707 index = 0 - index - 1; 708 } 709 alarms.add(index, alarm); 710 if (alarm.listener == mTimeTickTrigger) { 711 mLastTickAdded = mInjector.getCurrentTimeMillis(); 712 } 713 if (DEBUG_BATCH) { 714 Slog.v(TAG, "Adding " + alarm + " to " + this); 715 } 716 if (alarm.whenElapsed > start) { 717 start = alarm.whenElapsed; 718 newStart = true; 719 } 720 if (alarm.maxWhenElapsed < end) { 721 end = alarm.maxWhenElapsed; 722 } 723 flags |= alarm.flags; 724 725 if (DEBUG_BATCH) { 726 Slog.v(TAG, " => now " + this); 727 } 728 return newStart; 729 } 730 731 /** 732 * Remove an alarm from this batch. 733 * <p> <b> Should be used only while re-ordering the alarm within the service </b> as it 734 * does not update {@link #mAlarmsPerUid} 735 */ remove(Alarm alarm)736 boolean remove(Alarm alarm) { 737 return remove(a -> (a == alarm), true); 738 } 739 remove(Predicate<Alarm> predicate, boolean reOrdering)740 boolean remove(Predicate<Alarm> predicate, boolean reOrdering) { 741 boolean didRemove = false; 742 long newStart = 0; // recalculate endpoints as we go 743 long newEnd = Long.MAX_VALUE; 744 int newFlags = 0; 745 for (int i = 0; i < alarms.size(); ) { 746 Alarm alarm = alarms.get(i); 747 if (predicate.test(alarm)) { 748 alarms.remove(i); 749 if (!reOrdering) { 750 decrementAlarmCount(alarm.uid, 1); 751 } 752 didRemove = true; 753 if (alarm.alarmClock != null) { 754 mNextAlarmClockMayChange = true; 755 } 756 if (alarm.listener == mTimeTickTrigger) { 757 mLastTickRemoved = mInjector.getCurrentTimeMillis(); 758 } 759 } else { 760 if (alarm.whenElapsed > newStart) { 761 newStart = alarm.whenElapsed; 762 } 763 if (alarm.maxWhenElapsed < newEnd) { 764 newEnd = alarm.maxWhenElapsed; 765 } 766 newFlags |= alarm.flags; 767 i++; 768 } 769 } 770 if (didRemove) { 771 // commit the new batch bounds 772 start = newStart; 773 end = newEnd; 774 flags = newFlags; 775 } 776 return didRemove; 777 } 778 hasPackage(final String packageName)779 boolean hasPackage(final String packageName) { 780 final int N = alarms.size(); 781 for (int i = 0; i < N; i++) { 782 Alarm a = alarms.get(i); 783 if (a.matches(packageName)) { 784 return true; 785 } 786 } 787 return false; 788 } 789 hasWakeups()790 boolean hasWakeups() { 791 final int N = alarms.size(); 792 for (int i = 0; i < N; i++) { 793 Alarm a = alarms.get(i); 794 // non-wakeup alarms are types 1 and 3, i.e. have the low bit set 795 if ((a.type & TYPE_NONWAKEUP_MASK) == 0) { 796 return true; 797 } 798 } 799 return false; 800 } 801 802 @Override toString()803 public String toString() { 804 StringBuilder b = new StringBuilder(40); 805 b.append("Batch{"); b.append(Integer.toHexString(this.hashCode())); 806 b.append(" num="); b.append(size()); 807 b.append(" start="); b.append(start); 808 b.append(" end="); b.append(end); 809 if (flags != 0) { 810 b.append(" flgs=0x"); 811 b.append(Integer.toHexString(flags)); 812 } 813 b.append('}'); 814 return b.toString(); 815 } 816 dumpDebug(ProtoOutputStream proto, long fieldId, long nowElapsed, long nowRTC)817 public void dumpDebug(ProtoOutputStream proto, long fieldId, long nowElapsed, 818 long nowRTC) { 819 final long token = proto.start(fieldId); 820 821 proto.write(BatchProto.START_REALTIME, start); 822 proto.write(BatchProto.END_REALTIME, end); 823 proto.write(BatchProto.FLAGS, flags); 824 for (Alarm a : alarms) { 825 a.dumpDebug(proto, BatchProto.ALARMS, nowElapsed, nowRTC); 826 } 827 828 proto.end(token); 829 } 830 } 831 832 static class BatchTimeOrder implements Comparator<Batch> { compare(Batch b1, Batch b2)833 public int compare(Batch b1, Batch b2) { 834 long when1 = b1.start; 835 long when2 = b2.start; 836 if (when1 > when2) { 837 return 1; 838 } 839 if (when1 < when2) { 840 return -1; 841 } 842 return 0; 843 } 844 } 845 846 final Comparator<Alarm> mAlarmDispatchComparator = new Comparator<Alarm>() { 847 @Override 848 public int compare(Alarm lhs, Alarm rhs) { 849 // priority class trumps everything. TICK < WAKEUP < NORMAL 850 if (lhs.priorityClass.priority < rhs.priorityClass.priority) { 851 return -1; 852 } else if (lhs.priorityClass.priority > rhs.priorityClass.priority) { 853 return 1; 854 } 855 856 // within each class, sort by nominal delivery time 857 if (lhs.whenElapsed < rhs.whenElapsed) { 858 return -1; 859 } else if (lhs.whenElapsed > rhs.whenElapsed) { 860 return 1; 861 } 862 863 // same priority class + same target delivery time 864 return 0; 865 } 866 }; 867 calculateDeliveryPriorities(ArrayList<Alarm> alarms)868 void calculateDeliveryPriorities(ArrayList<Alarm> alarms) { 869 final int N = alarms.size(); 870 for (int i = 0; i < N; i++) { 871 Alarm a = alarms.get(i); 872 873 final int alarmPrio; 874 if (a.listener == mTimeTickTrigger) { 875 alarmPrio = PRIO_TICK; 876 } else if (a.wakeup) { 877 alarmPrio = PRIO_WAKEUP; 878 } else { 879 alarmPrio = PRIO_NORMAL; 880 } 881 882 PriorityClass packagePrio = a.priorityClass; 883 String alarmPackage = a.sourcePackage; 884 if (packagePrio == null) packagePrio = mPriorities.get(alarmPackage); 885 if (packagePrio == null) { 886 packagePrio = a.priorityClass = new PriorityClass(); // lowest prio & stale sequence 887 mPriorities.put(alarmPackage, packagePrio); 888 } 889 a.priorityClass = packagePrio; 890 891 if (packagePrio.seq != mCurrentSeq) { 892 // first alarm we've seen in the current delivery generation from this package 893 packagePrio.priority = alarmPrio; 894 packagePrio.seq = mCurrentSeq; 895 } else { 896 // Multiple alarms from this package being delivered in this generation; 897 // bump the package's delivery class if it's warranted. 898 // TICK < WAKEUP < NORMAL 899 if (alarmPrio < packagePrio.priority) { 900 packagePrio.priority = alarmPrio; 901 } 902 } 903 } 904 } 905 906 // minimum recurrence period or alarm futurity for us to be able to fuzz it 907 static final long MIN_FUZZABLE_INTERVAL = 10000; 908 static final BatchTimeOrder sBatchOrder = new BatchTimeOrder(); 909 final ArrayList<Batch> mAlarmBatches = new ArrayList<>(); 910 911 // set to non-null if in idle mode; while in this mode, any alarms we don't want 912 // to run during this time are placed in mPendingWhileIdleAlarms 913 Alarm mPendingIdleUntil = null; 914 Alarm mNextWakeFromIdle = null; 915 ArrayList<Alarm> mPendingWhileIdleAlarms = new ArrayList<>(); 916 917 @VisibleForTesting AlarmManagerService(Context context, Injector injector)918 AlarmManagerService(Context context, Injector injector) { 919 super(context); 920 mInjector = injector; 921 } 922 AlarmManagerService(Context context)923 AlarmManagerService(Context context) { 924 this(context, new Injector(context)); 925 } 926 convertToElapsed(long when, int type)927 private long convertToElapsed(long when, int type) { 928 final boolean isRtc = (type == RTC || type == RTC_WAKEUP); 929 if (isRtc) { 930 when -= mInjector.getCurrentTimeMillis() - mInjector.getElapsedRealtime(); 931 } 932 return when; 933 } 934 935 // Apply a heuristic to { recurrence interval, futurity of the trigger time } to 936 // calculate the end of our nominal delivery window for the alarm. maxTriggerTime(long now, long triggerAtTime, long interval)937 static long maxTriggerTime(long now, long triggerAtTime, long interval) { 938 // Current heuristic: batchable window is 75% of either the recurrence interval 939 // [for a periodic alarm] or of the time from now to the desired delivery time, 940 // with a minimum delay/interval of 10 seconds, under which we will simply not 941 // defer the alarm. 942 long futurity = (interval == 0) 943 ? (triggerAtTime - now) 944 : interval; 945 if (futurity < MIN_FUZZABLE_INTERVAL) { 946 futurity = 0; 947 } 948 return clampPositive(triggerAtTime + (long)(.75 * futurity)); 949 } 950 951 // returns true if the batch was added at the head addBatchLocked(ArrayList<Batch> list, Batch newBatch)952 static boolean addBatchLocked(ArrayList<Batch> list, Batch newBatch) { 953 int index = Collections.binarySearch(list, newBatch, sBatchOrder); 954 if (index < 0) { 955 index = 0 - index - 1; 956 } 957 list.add(index, newBatch); 958 return (index == 0); 959 } 960 insertAndBatchAlarmLocked(Alarm alarm)961 private void insertAndBatchAlarmLocked(Alarm alarm) { 962 final int whichBatch = ((alarm.flags & AlarmManager.FLAG_STANDALONE) != 0) ? -1 963 : attemptCoalesceLocked(alarm.whenElapsed, alarm.maxWhenElapsed); 964 965 if (whichBatch < 0) { 966 addBatchLocked(mAlarmBatches, new Batch(alarm)); 967 } else { 968 final Batch batch = mAlarmBatches.get(whichBatch); 969 if (batch.add(alarm)) { 970 // The start time of this batch advanced, so batch ordering may 971 // have just been broken. Move it to where it now belongs. 972 mAlarmBatches.remove(whichBatch); 973 addBatchLocked(mAlarmBatches, batch); 974 } 975 } 976 } 977 978 // Return the index of the matching batch, or -1 if none found. attemptCoalesceLocked(long whenElapsed, long maxWhen)979 int attemptCoalesceLocked(long whenElapsed, long maxWhen) { 980 final int N = mAlarmBatches.size(); 981 for (int i = 0; i < N; i++) { 982 Batch b = mAlarmBatches.get(i); 983 if ((b.flags&AlarmManager.FLAG_STANDALONE) == 0 && b.canHold(whenElapsed, maxWhen)) { 984 return i; 985 } 986 } 987 return -1; 988 } 989 /** @return total count of the alarms in a set of alarm batches. */ getAlarmCount(ArrayList<Batch> batches)990 static int getAlarmCount(ArrayList<Batch> batches) { 991 int ret = 0; 992 993 final int size = batches.size(); 994 for (int i = 0; i < size; i++) { 995 ret += batches.get(i).size(); 996 } 997 return ret; 998 } 999 haveAlarmsTimeTickAlarm(ArrayList<Alarm> alarms)1000 boolean haveAlarmsTimeTickAlarm(ArrayList<Alarm> alarms) { 1001 if (alarms.size() == 0) { 1002 return false; 1003 } 1004 final int batchSize = alarms.size(); 1005 for (int j = 0; j < batchSize; j++) { 1006 if (alarms.get(j).listener == mTimeTickTrigger) { 1007 return true; 1008 } 1009 } 1010 return false; 1011 } 1012 haveBatchesTimeTickAlarm(ArrayList<Batch> batches)1013 boolean haveBatchesTimeTickAlarm(ArrayList<Batch> batches) { 1014 final int numBatches = batches.size(); 1015 for (int i = 0; i < numBatches; i++) { 1016 if (haveAlarmsTimeTickAlarm(batches.get(i).alarms)) { 1017 return true; 1018 } 1019 } 1020 return false; 1021 } 1022 1023 // The RTC clock has moved arbitrarily, so we need to recalculate all the batching rebatchAllAlarms()1024 void rebatchAllAlarms() { 1025 synchronized (mLock) { 1026 rebatchAllAlarmsLocked(true); 1027 } 1028 } 1029 rebatchAllAlarmsLocked(boolean doValidate)1030 void rebatchAllAlarmsLocked(boolean doValidate) { 1031 final long start = mStatLogger.getTime(); 1032 final int oldCount = 1033 getAlarmCount(mAlarmBatches) + ArrayUtils.size(mPendingWhileIdleAlarms); 1034 final boolean oldHasTick = haveBatchesTimeTickAlarm(mAlarmBatches) 1035 || haveAlarmsTimeTickAlarm(mPendingWhileIdleAlarms); 1036 1037 ArrayList<Batch> oldSet = (ArrayList<Batch>) mAlarmBatches.clone(); 1038 mAlarmBatches.clear(); 1039 Alarm oldPendingIdleUntil = mPendingIdleUntil; 1040 final long nowElapsed = mInjector.getElapsedRealtime(); 1041 final int oldBatches = oldSet.size(); 1042 for (int batchNum = 0; batchNum < oldBatches; batchNum++) { 1043 Batch batch = oldSet.get(batchNum); 1044 final int N = batch.size(); 1045 for (int i = 0; i < N; i++) { 1046 reAddAlarmLocked(batch.get(i), nowElapsed, doValidate); 1047 } 1048 } 1049 if (oldPendingIdleUntil != null && oldPendingIdleUntil != mPendingIdleUntil) { 1050 Slog.wtf(TAG, "Rebatching: idle until changed from " + oldPendingIdleUntil 1051 + " to " + mPendingIdleUntil); 1052 if (mPendingIdleUntil == null) { 1053 // Somehow we lost this... we need to restore all of the pending alarms. 1054 restorePendingWhileIdleAlarmsLocked(); 1055 } 1056 } 1057 final int newCount = 1058 getAlarmCount(mAlarmBatches) + ArrayUtils.size(mPendingWhileIdleAlarms); 1059 final boolean newHasTick = haveBatchesTimeTickAlarm(mAlarmBatches) 1060 || haveAlarmsTimeTickAlarm(mPendingWhileIdleAlarms); 1061 1062 if (oldCount != newCount) { 1063 Slog.wtf(TAG, "Rebatching: total count changed from " + oldCount + " to " + newCount); 1064 } 1065 if (oldHasTick != newHasTick) { 1066 Slog.wtf(TAG, "Rebatching: hasTick changed from " + oldHasTick + " to " + newHasTick); 1067 } 1068 1069 rescheduleKernelAlarmsLocked(); 1070 updateNextAlarmClockLocked(); 1071 mStatLogger.logDurationStat(Stats.REBATCH_ALL_ALARMS, start); 1072 } 1073 1074 /** 1075 * Re-orders the alarm batches based on newly evaluated send times based on the current 1076 * app-standby buckets 1077 * @param targetPackages [Package, User] pairs for which alarms need to be re-evaluated, 1078 * null indicates all 1079 * @return True if there was any reordering done to the current list. 1080 */ reorderAlarmsBasedOnStandbyBuckets(ArraySet<Pair<String, Integer>> targetPackages)1081 boolean reorderAlarmsBasedOnStandbyBuckets(ArraySet<Pair<String, Integer>> targetPackages) { 1082 final long start = mStatLogger.getTime(); 1083 final ArrayList<Alarm> rescheduledAlarms = new ArrayList<>(); 1084 1085 for (int batchIndex = mAlarmBatches.size() - 1; batchIndex >= 0; batchIndex--) { 1086 final Batch batch = mAlarmBatches.get(batchIndex); 1087 for (int alarmIndex = batch.size() - 1; alarmIndex >= 0; alarmIndex--) { 1088 final Alarm alarm = batch.get(alarmIndex); 1089 final Pair<String, Integer> packageUser = 1090 Pair.create(alarm.sourcePackage, UserHandle.getUserId(alarm.creatorUid)); 1091 if (targetPackages != null && !targetPackages.contains(packageUser)) { 1092 continue; 1093 } 1094 if (adjustDeliveryTimeBasedOnBucketLocked(alarm)) { 1095 batch.remove(alarm); 1096 rescheduledAlarms.add(alarm); 1097 } 1098 } 1099 if (batch.size() == 0) { 1100 mAlarmBatches.remove(batchIndex); 1101 } 1102 } 1103 for (int i = 0; i < rescheduledAlarms.size(); i++) { 1104 final Alarm a = rescheduledAlarms.get(i); 1105 insertAndBatchAlarmLocked(a); 1106 } 1107 1108 mStatLogger.logDurationStat(Stats.REORDER_ALARMS_FOR_STANDBY, start); 1109 return rescheduledAlarms.size() > 0; 1110 } 1111 reAddAlarmLocked(Alarm a, long nowElapsed, boolean doValidate)1112 void reAddAlarmLocked(Alarm a, long nowElapsed, boolean doValidate) { 1113 a.when = a.origWhen; 1114 long whenElapsed = convertToElapsed(a.when, a.type); 1115 final long maxElapsed; 1116 if (a.windowLength == AlarmManager.WINDOW_EXACT) { 1117 // Exact 1118 maxElapsed = whenElapsed; 1119 } else { 1120 // Not exact. Preserve any explicit window, otherwise recalculate 1121 // the window based on the alarm's new futurity. Note that this 1122 // reflects a policy of preferring timely to deferred delivery. 1123 maxElapsed = (a.windowLength > 0) 1124 ? clampPositive(whenElapsed + a.windowLength) 1125 : maxTriggerTime(nowElapsed, whenElapsed, a.repeatInterval); 1126 } 1127 a.expectedWhenElapsed = a.whenElapsed = whenElapsed; 1128 a.expectedMaxWhenElapsed = a.maxWhenElapsed = maxElapsed; 1129 setImplLocked(a, true, doValidate); 1130 } 1131 clampPositive(long val)1132 static long clampPositive(long val) { 1133 return (val >= 0) ? val : Long.MAX_VALUE; 1134 } 1135 1136 /** 1137 * Sends alarms that were blocked due to user applied background restrictions - either because 1138 * the user lifted those or the uid came to foreground. 1139 * 1140 * @param uid uid to filter on 1141 * @param packageName package to filter on, or null for all packages in uid 1142 */ sendPendingBackgroundAlarmsLocked(int uid, String packageName)1143 void sendPendingBackgroundAlarmsLocked(int uid, String packageName) { 1144 final ArrayList<Alarm> alarmsForUid = mPendingBackgroundAlarms.get(uid); 1145 if (alarmsForUid == null || alarmsForUid.size() == 0) { 1146 return; 1147 } 1148 final ArrayList<Alarm> alarmsToDeliver; 1149 if (packageName != null) { 1150 if (DEBUG_BG_LIMIT) { 1151 Slog.d(TAG, "Sending blocked alarms for uid " + uid + ", package " + packageName); 1152 } 1153 alarmsToDeliver = new ArrayList<>(); 1154 for (int i = alarmsForUid.size() - 1; i >= 0; i--) { 1155 final Alarm a = alarmsForUid.get(i); 1156 if (a.matches(packageName)) { 1157 alarmsToDeliver.add(alarmsForUid.remove(i)); 1158 } 1159 } 1160 if (alarmsForUid.size() == 0) { 1161 mPendingBackgroundAlarms.remove(uid); 1162 } 1163 } else { 1164 if (DEBUG_BG_LIMIT) { 1165 Slog.d(TAG, "Sending blocked alarms for uid " + uid); 1166 } 1167 alarmsToDeliver = alarmsForUid; 1168 mPendingBackgroundAlarms.remove(uid); 1169 } 1170 deliverPendingBackgroundAlarmsLocked(alarmsToDeliver, mInjector.getElapsedRealtime()); 1171 } 1172 1173 /** 1174 * Check all alarms in {@link #mPendingBackgroundAlarms} and send the ones that are not 1175 * restricted. 1176 * 1177 * This is only called when the global "force all apps-standby" flag changes or when the 1178 * power save whitelist changes, so it's okay to be slow. 1179 */ sendAllUnrestrictedPendingBackgroundAlarmsLocked()1180 void sendAllUnrestrictedPendingBackgroundAlarmsLocked() { 1181 final ArrayList<Alarm> alarmsToDeliver = new ArrayList<>(); 1182 1183 findAllUnrestrictedPendingBackgroundAlarmsLockedInner( 1184 mPendingBackgroundAlarms, alarmsToDeliver, this::isBackgroundRestricted); 1185 1186 if (alarmsToDeliver.size() > 0) { 1187 deliverPendingBackgroundAlarmsLocked(alarmsToDeliver, mInjector.getElapsedRealtime()); 1188 } 1189 } 1190 1191 @VisibleForTesting findAllUnrestrictedPendingBackgroundAlarmsLockedInner( SparseArray<ArrayList<Alarm>> pendingAlarms, ArrayList<Alarm> unrestrictedAlarms, Predicate<Alarm> isBackgroundRestricted)1192 static void findAllUnrestrictedPendingBackgroundAlarmsLockedInner( 1193 SparseArray<ArrayList<Alarm>> pendingAlarms, ArrayList<Alarm> unrestrictedAlarms, 1194 Predicate<Alarm> isBackgroundRestricted) { 1195 1196 for (int uidIndex = pendingAlarms.size() - 1; uidIndex >= 0; uidIndex--) { 1197 final int uid = pendingAlarms.keyAt(uidIndex); 1198 final ArrayList<Alarm> alarmsForUid = pendingAlarms.valueAt(uidIndex); 1199 1200 for (int alarmIndex = alarmsForUid.size() - 1; alarmIndex >= 0; alarmIndex--) { 1201 final Alarm alarm = alarmsForUid.get(alarmIndex); 1202 1203 if (isBackgroundRestricted.test(alarm)) { 1204 continue; 1205 } 1206 1207 unrestrictedAlarms.add(alarm); 1208 alarmsForUid.remove(alarmIndex); 1209 } 1210 1211 if (alarmsForUid.size() == 0) { 1212 pendingAlarms.removeAt(uidIndex); 1213 } 1214 } 1215 } 1216 deliverPendingBackgroundAlarmsLocked(ArrayList<Alarm> alarms, long nowELAPSED)1217 private void deliverPendingBackgroundAlarmsLocked(ArrayList<Alarm> alarms, long nowELAPSED) { 1218 final int N = alarms.size(); 1219 boolean hasWakeup = false; 1220 for (int i = 0; i < N; i++) { 1221 final Alarm alarm = alarms.get(i); 1222 if (alarm.wakeup) { 1223 hasWakeup = true; 1224 } 1225 alarm.count = 1; 1226 // Recurring alarms may have passed several alarm intervals while the 1227 // alarm was kept pending. Send the appropriate trigger count. 1228 if (alarm.repeatInterval > 0) { 1229 alarm.count += (nowELAPSED - alarm.expectedWhenElapsed) / alarm.repeatInterval; 1230 // Also schedule its next recurrence 1231 final long delta = alarm.count * alarm.repeatInterval; 1232 final long nextElapsed = alarm.expectedWhenElapsed + delta; 1233 setImplLocked(alarm.type, alarm.when + delta, nextElapsed, alarm.windowLength, 1234 maxTriggerTime(nowELAPSED, nextElapsed, alarm.repeatInterval), 1235 alarm.repeatInterval, alarm.operation, null, null, alarm.flags, true, 1236 alarm.workSource, alarm.alarmClock, alarm.uid, alarm.packageName); 1237 // Kernel alarms will be rescheduled as needed in setImplLocked 1238 } 1239 } 1240 if (!hasWakeup && checkAllowNonWakeupDelayLocked(nowELAPSED)) { 1241 // No need to wakeup for non wakeup alarms 1242 if (mPendingNonWakeupAlarms.size() == 0) { 1243 mStartCurrentDelayTime = nowELAPSED; 1244 mNextNonWakeupDeliveryTime = nowELAPSED 1245 + ((currentNonWakeupFuzzLocked(nowELAPSED)*3)/2); 1246 } 1247 mPendingNonWakeupAlarms.addAll(alarms); 1248 mNumDelayedAlarms += alarms.size(); 1249 } else { 1250 if (DEBUG_BG_LIMIT) { 1251 Slog.d(TAG, "Waking up to deliver pending blocked alarms"); 1252 } 1253 // Since we are waking up, also deliver any pending non wakeup alarms we have. 1254 if (mPendingNonWakeupAlarms.size() > 0) { 1255 alarms.addAll(mPendingNonWakeupAlarms); 1256 final long thisDelayTime = nowELAPSED - mStartCurrentDelayTime; 1257 mTotalDelayTime += thisDelayTime; 1258 if (mMaxDelayTime < thisDelayTime) { 1259 mMaxDelayTime = thisDelayTime; 1260 } 1261 mPendingNonWakeupAlarms.clear(); 1262 } 1263 calculateDeliveryPriorities(alarms); 1264 Collections.sort(alarms, mAlarmDispatchComparator); 1265 deliverAlarmsLocked(alarms, nowELAPSED); 1266 } 1267 } 1268 restorePendingWhileIdleAlarmsLocked()1269 void restorePendingWhileIdleAlarmsLocked() { 1270 if (RECORD_DEVICE_IDLE_ALARMS) { 1271 IdleDispatchEntry ent = new IdleDispatchEntry(); 1272 ent.uid = 0; 1273 ent.pkg = "FINISH IDLE"; 1274 ent.elapsedRealtime = mInjector.getElapsedRealtime(); 1275 mAllowWhileIdleDispatches.add(ent); 1276 } 1277 1278 // Bring pending alarms back into the main list. 1279 if (mPendingWhileIdleAlarms.size() > 0) { 1280 ArrayList<Alarm> alarms = mPendingWhileIdleAlarms; 1281 mPendingWhileIdleAlarms = new ArrayList<>(); 1282 final long nowElapsed = mInjector.getElapsedRealtime(); 1283 for (int i=alarms.size() - 1; i >= 0; i--) { 1284 Alarm a = alarms.get(i); 1285 reAddAlarmLocked(a, nowElapsed, false); 1286 } 1287 } 1288 1289 // Reschedule everything. 1290 rescheduleKernelAlarmsLocked(); 1291 updateNextAlarmClockLocked(); 1292 1293 } 1294 1295 static final class InFlight { 1296 final PendingIntent mPendingIntent; 1297 final long mWhenElapsed; 1298 final IBinder mListener; 1299 final WorkSource mWorkSource; 1300 final int mUid; 1301 final int mCreatorUid; 1302 final String mTag; 1303 final BroadcastStats mBroadcastStats; 1304 final FilterStats mFilterStats; 1305 final int mAlarmType; 1306 InFlight(AlarmManagerService service, Alarm alarm, long nowELAPSED)1307 InFlight(AlarmManagerService service, Alarm alarm, long nowELAPSED) { 1308 mPendingIntent = alarm.operation; 1309 mWhenElapsed = nowELAPSED; 1310 mListener = alarm.listener != null ? alarm.listener.asBinder() : null; 1311 mWorkSource = alarm.workSource; 1312 mUid = alarm.uid; 1313 mCreatorUid = alarm.creatorUid; 1314 mTag = alarm.statsTag; 1315 mBroadcastStats = (alarm.operation != null) 1316 ? service.getStatsLocked(alarm.operation) 1317 : service.getStatsLocked(alarm.uid, alarm.packageName); 1318 FilterStats fs = mBroadcastStats.filterStats.get(mTag); 1319 if (fs == null) { 1320 fs = new FilterStats(mBroadcastStats, mTag); 1321 mBroadcastStats.filterStats.put(mTag, fs); 1322 } 1323 fs.lastTime = nowELAPSED; 1324 mFilterStats = fs; 1325 mAlarmType = alarm.type; 1326 } 1327 isBroadcast()1328 boolean isBroadcast() { 1329 return mPendingIntent != null && mPendingIntent.isBroadcast(); 1330 } 1331 1332 @Override toString()1333 public String toString() { 1334 return "InFlight{" 1335 + "pendingIntent=" + mPendingIntent 1336 + ", when=" + mWhenElapsed 1337 + ", workSource=" + mWorkSource 1338 + ", uid=" + mUid 1339 + ", creatorUid=" + mCreatorUid 1340 + ", tag=" + mTag 1341 + ", broadcastStats=" + mBroadcastStats 1342 + ", filterStats=" + mFilterStats 1343 + ", alarmType=" + mAlarmType 1344 + "}"; 1345 } 1346 dumpDebug(ProtoOutputStream proto, long fieldId)1347 public void dumpDebug(ProtoOutputStream proto, long fieldId) { 1348 final long token = proto.start(fieldId); 1349 1350 proto.write(InFlightProto.UID, mUid); 1351 proto.write(InFlightProto.TAG, mTag); 1352 proto.write(InFlightProto.WHEN_ELAPSED_MS, mWhenElapsed); 1353 proto.write(InFlightProto.ALARM_TYPE, mAlarmType); 1354 if (mPendingIntent != null) { 1355 mPendingIntent.dumpDebug(proto, InFlightProto.PENDING_INTENT); 1356 } 1357 if (mBroadcastStats != null) { 1358 mBroadcastStats.dumpDebug(proto, InFlightProto.BROADCAST_STATS); 1359 } 1360 if (mFilterStats != null) { 1361 mFilterStats.dumpDebug(proto, InFlightProto.FILTER_STATS); 1362 } 1363 if (mWorkSource != null) { 1364 mWorkSource.dumpDebug(proto, InFlightProto.WORK_SOURCE); 1365 } 1366 1367 proto.end(token); 1368 } 1369 } 1370 notifyBroadcastAlarmPendingLocked(int uid)1371 private void notifyBroadcastAlarmPendingLocked(int uid) { 1372 final int numListeners = mInFlightListeners.size(); 1373 for (int i = 0; i < numListeners; i++) { 1374 mInFlightListeners.get(i).broadcastAlarmPending(uid); 1375 } 1376 } 1377 notifyBroadcastAlarmCompleteLocked(int uid)1378 private void notifyBroadcastAlarmCompleteLocked(int uid) { 1379 final int numListeners = mInFlightListeners.size(); 1380 for (int i = 0; i < numListeners; i++) { 1381 mInFlightListeners.get(i).broadcastAlarmComplete(uid); 1382 } 1383 } 1384 1385 static final class FilterStats { 1386 final BroadcastStats mBroadcastStats; 1387 final String mTag; 1388 1389 long lastTime; 1390 long aggregateTime; 1391 int count; 1392 int numWakeup; 1393 long startTime; 1394 int nesting; 1395 FilterStats(BroadcastStats broadcastStats, String tag)1396 FilterStats(BroadcastStats broadcastStats, String tag) { 1397 mBroadcastStats = broadcastStats; 1398 mTag = tag; 1399 } 1400 1401 @Override toString()1402 public String toString() { 1403 return "FilterStats{" 1404 + "tag=" + mTag 1405 + ", lastTime=" + lastTime 1406 + ", aggregateTime=" + aggregateTime 1407 + ", count=" + count 1408 + ", numWakeup=" + numWakeup 1409 + ", startTime=" + startTime 1410 + ", nesting=" + nesting 1411 + "}"; 1412 } 1413 dumpDebug(ProtoOutputStream proto, long fieldId)1414 public void dumpDebug(ProtoOutputStream proto, long fieldId) { 1415 final long token = proto.start(fieldId); 1416 1417 proto.write(FilterStatsProto.TAG, mTag); 1418 proto.write(FilterStatsProto.LAST_FLIGHT_TIME_REALTIME, lastTime); 1419 proto.write(FilterStatsProto.TOTAL_FLIGHT_DURATION_MS, aggregateTime); 1420 proto.write(FilterStatsProto.COUNT, count); 1421 proto.write(FilterStatsProto.WAKEUP_COUNT, numWakeup); 1422 proto.write(FilterStatsProto.START_TIME_REALTIME, startTime); 1423 proto.write(FilterStatsProto.NESTING, nesting); 1424 1425 proto.end(token); 1426 } 1427 } 1428 1429 static final class BroadcastStats { 1430 final int mUid; 1431 final String mPackageName; 1432 1433 long aggregateTime; 1434 int count; 1435 int numWakeup; 1436 long startTime; 1437 int nesting; 1438 final ArrayMap<String, FilterStats> filterStats = new ArrayMap<String, FilterStats>(); 1439 BroadcastStats(int uid, String packageName)1440 BroadcastStats(int uid, String packageName) { 1441 mUid = uid; 1442 mPackageName = packageName; 1443 } 1444 1445 @Override toString()1446 public String toString() { 1447 return "BroadcastStats{" 1448 + "uid=" + mUid 1449 + ", packageName=" + mPackageName 1450 + ", aggregateTime=" + aggregateTime 1451 + ", count=" + count 1452 + ", numWakeup=" + numWakeup 1453 + ", startTime=" + startTime 1454 + ", nesting=" + nesting 1455 + "}"; 1456 } 1457 dumpDebug(ProtoOutputStream proto, long fieldId)1458 public void dumpDebug(ProtoOutputStream proto, long fieldId) { 1459 final long token = proto.start(fieldId); 1460 1461 proto.write(BroadcastStatsProto.UID, mUid); 1462 proto.write(BroadcastStatsProto.PACKAGE_NAME, mPackageName); 1463 proto.write(BroadcastStatsProto.TOTAL_FLIGHT_DURATION_MS, aggregateTime); 1464 proto.write(BroadcastStatsProto.COUNT, count); 1465 proto.write(BroadcastStatsProto.WAKEUP_COUNT, numWakeup); 1466 proto.write(BroadcastStatsProto.START_TIME_REALTIME, startTime); 1467 proto.write(BroadcastStatsProto.NESTING, nesting); 1468 1469 proto.end(token); 1470 } 1471 } 1472 1473 final SparseArray<ArrayMap<String, BroadcastStats>> mBroadcastStats 1474 = new SparseArray<ArrayMap<String, BroadcastStats>>(); 1475 1476 int mNumDelayedAlarms = 0; 1477 long mTotalDelayTime = 0; 1478 long mMaxDelayTime = 0; 1479 1480 @Override onStart()1481 public void onStart() { 1482 mInjector.init(); 1483 1484 mListenerDeathRecipient = new IBinder.DeathRecipient() { 1485 @Override 1486 public void binderDied() { 1487 } 1488 1489 @Override 1490 public void binderDied(IBinder who) { 1491 final IAlarmListener listener = IAlarmListener.Stub.asInterface(who); 1492 removeImpl(null, listener); 1493 } 1494 }; 1495 1496 synchronized (mLock) { 1497 mHandler = new AlarmHandler(); 1498 mConstants = new Constants(mHandler); 1499 mAppWakeupHistory = new AppWakeupHistory(Constants.DEFAULT_APP_STANDBY_WINDOW); 1500 1501 mNextWakeup = mNextNonWakeup = 0; 1502 1503 // We have to set current TimeZone info to kernel 1504 // because kernel doesn't keep this after reboot 1505 setTimeZoneImpl(SystemProperties.get(TIMEZONE_PROPERTY)); 1506 1507 // Ensure that we're booting with a halfway sensible current time. Use the 1508 // most recent of Build.TIME, the root file system's timestamp, and the 1509 // value of the ro.build.date.utc system property (which is in seconds). 1510 final long systemBuildTime = Long.max( 1511 1000L * SystemProperties.getLong("ro.build.date.utc", -1L), 1512 Long.max(Environment.getRootDirectory().lastModified(), Build.TIME)); 1513 if (mInjector.getCurrentTimeMillis() < systemBuildTime) { 1514 Slog.i(TAG, "Current time only " + mInjector.getCurrentTimeMillis() 1515 + ", advancing to build time " + systemBuildTime); 1516 mInjector.setKernelTime(systemBuildTime); 1517 } 1518 1519 // Determine SysUI's uid 1520 mSystemUiUid = mInjector.getSystemUiUid(); 1521 if (mSystemUiUid <= 0) { 1522 Slog.wtf(TAG, "SysUI package not found!"); 1523 } 1524 mWakeLock = mInjector.getAlarmWakeLock(); 1525 1526 mTimeTickIntent = new Intent(Intent.ACTION_TIME_TICK).addFlags( 1527 Intent.FLAG_RECEIVER_REGISTERED_ONLY 1528 | Intent.FLAG_RECEIVER_FOREGROUND 1529 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); 1530 1531 mTimeTickTrigger = new IAlarmListener.Stub() { 1532 @Override 1533 public void doAlarm(final IAlarmCompleteListener callback) throws RemoteException { 1534 if (DEBUG_BATCH) { 1535 Slog.v(TAG, "Received TIME_TICK alarm; rescheduling"); 1536 } 1537 1538 // Via handler because dispatch invokes this within its lock. OnAlarmListener 1539 // takes care of this automatically, but we're using the direct internal 1540 // interface here rather than that client-side wrapper infrastructure. 1541 mHandler.post(() -> { 1542 getContext().sendBroadcastAsUser(mTimeTickIntent, UserHandle.ALL); 1543 1544 try { 1545 callback.alarmComplete(this); 1546 } catch (RemoteException e) { /* local method call */ } 1547 }); 1548 1549 synchronized (mLock) { 1550 mLastTickReceived = mInjector.getCurrentTimeMillis(); 1551 } 1552 mClockReceiver.scheduleTimeTickEvent(); 1553 } 1554 }; 1555 1556 Intent intent = new Intent(Intent.ACTION_DATE_CHANGED); 1557 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING 1558 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); 1559 mDateChangeSender = PendingIntent.getBroadcastAsUser(getContext(), 0, intent, 1560 Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT, UserHandle.ALL); 1561 1562 mClockReceiver = mInjector.getClockReceiver(this); 1563 new ChargingReceiver(); 1564 new InteractiveStateReceiver(); 1565 new UninstallReceiver(); 1566 1567 if (mInjector.isAlarmDriverPresent()) { 1568 AlarmThread waitThread = new AlarmThread(); 1569 waitThread.start(); 1570 } else { 1571 Slog.w(TAG, "Failed to open alarm driver. Falling back to a handler."); 1572 } 1573 1574 try { 1575 ActivityManager.getService().registerUidObserver(new UidObserver(), 1576 ActivityManager.UID_OBSERVER_GONE | ActivityManager.UID_OBSERVER_IDLE 1577 | ActivityManager.UID_OBSERVER_ACTIVE, 1578 ActivityManager.PROCESS_STATE_UNKNOWN, null); 1579 } catch (RemoteException e) { 1580 // ignored; both services live in system_server 1581 } 1582 } 1583 publishLocalService(AlarmManagerInternal.class, new LocalService()); 1584 publishBinderService(Context.ALARM_SERVICE, mService); 1585 } 1586 1587 @Override onBootPhase(int phase)1588 public void onBootPhase(int phase) { 1589 if (phase == PHASE_SYSTEM_SERVICES_READY) { 1590 synchronized (mLock) { 1591 mConstants.start(getContext().getContentResolver()); 1592 mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE); 1593 mLocalDeviceIdleController = 1594 LocalServices.getService(DeviceIdleInternal.class); 1595 mUsageStatsManagerInternal = 1596 LocalServices.getService(UsageStatsManagerInternal.class); 1597 AppStandbyInternal appStandbyInternal = 1598 LocalServices.getService(AppStandbyInternal.class); 1599 appStandbyInternal.addListener(new AppStandbyTracker()); 1600 1601 mAppStateTracker = LocalServices.getService(AppStateTracker.class); 1602 mAppStateTracker.addListener(mForceAppStandbyListener); 1603 1604 mClockReceiver.scheduleTimeTickEvent(); 1605 mClockReceiver.scheduleDateChangedEvent(); 1606 } 1607 } 1608 } 1609 1610 @Override finalize()1611 protected void finalize() throws Throwable { 1612 try { 1613 mInjector.close(); 1614 } finally { 1615 super.finalize(); 1616 } 1617 } 1618 setTimeImpl(long millis)1619 boolean setTimeImpl(long millis) { 1620 if (!mInjector.isAlarmDriverPresent()) { 1621 Slog.w(TAG, "Not setting time since no alarm driver is available."); 1622 return false; 1623 } 1624 1625 synchronized (mLock) { 1626 final long currentTimeMillis = mInjector.getCurrentTimeMillis(); 1627 mInjector.setKernelTime(millis); 1628 final TimeZone timeZone = TimeZone.getDefault(); 1629 final int currentTzOffset = timeZone.getOffset(currentTimeMillis); 1630 final int newTzOffset = timeZone.getOffset(millis); 1631 if (currentTzOffset != newTzOffset) { 1632 Slog.i(TAG, "Timezone offset has changed, updating kernel timezone"); 1633 mInjector.setKernelTimezone(-(newTzOffset / 60000)); 1634 } 1635 // The native implementation of setKernelTime can return -1 even when the kernel 1636 // time was set correctly, so assume setting kernel time was successful and always 1637 // return true. 1638 return true; 1639 } 1640 } 1641 setTimeZoneImpl(String tz)1642 void setTimeZoneImpl(String tz) { 1643 if (TextUtils.isEmpty(tz)) { 1644 return; 1645 } 1646 1647 TimeZone zone = TimeZone.getTimeZone(tz); 1648 // Prevent reentrant calls from stepping on each other when writing 1649 // the time zone property 1650 boolean timeZoneWasChanged = false; 1651 synchronized (this) { 1652 String current = SystemProperties.get(TIMEZONE_PROPERTY); 1653 if (current == null || !current.equals(zone.getID())) { 1654 if (localLOGV) { 1655 Slog.v(TAG, "timezone changed: " + current + ", new=" + zone.getID()); 1656 } 1657 timeZoneWasChanged = true; 1658 SystemProperties.set(TIMEZONE_PROPERTY, zone.getID()); 1659 } 1660 1661 // Update the kernel timezone information 1662 // Kernel tracks time offsets as 'minutes west of GMT' 1663 int gmtOffset = zone.getOffset(mInjector.getCurrentTimeMillis()); 1664 mInjector.setKernelTimezone(-(gmtOffset / 60000)); 1665 } 1666 1667 TimeZone.setDefault(null); 1668 1669 if (timeZoneWasChanged) { 1670 // Don't wait for broadcasts to update our midnight alarm 1671 mClockReceiver.scheduleDateChangedEvent(); 1672 1673 // And now let everyone else know 1674 Intent intent = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 1675 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING 1676 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND 1677 | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT 1678 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); 1679 intent.putExtra(Intent.EXTRA_TIMEZONE, zone.getID()); 1680 getContext().sendBroadcastAsUser(intent, UserHandle.ALL); 1681 } 1682 } 1683 removeImpl(PendingIntent operation, IAlarmListener listener)1684 void removeImpl(PendingIntent operation, IAlarmListener listener) { 1685 synchronized (mLock) { 1686 removeLocked(operation, listener); 1687 } 1688 } 1689 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)1690 void setImpl(int type, long triggerAtTime, long windowLength, long interval, 1691 PendingIntent operation, IAlarmListener directReceiver, String listenerTag, 1692 int flags, WorkSource workSource, AlarmManager.AlarmClockInfo alarmClock, 1693 int callingUid, String callingPackage) { 1694 // must be *either* PendingIntent or AlarmReceiver, but not both 1695 if ((operation == null && directReceiver == null) 1696 || (operation != null && directReceiver != null)) { 1697 Slog.w(TAG, "Alarms must either supply a PendingIntent or an AlarmReceiver"); 1698 // NB: previous releases failed silently here, so we are continuing to do the same 1699 // rather than throw an IllegalArgumentException. 1700 return; 1701 } 1702 1703 if (directReceiver != null) { 1704 try { 1705 directReceiver.asBinder().linkToDeath(mListenerDeathRecipient, 0); 1706 } catch (RemoteException e) { 1707 Slog.w(TAG, "Dropping unreachable alarm listener " + listenerTag); 1708 return; 1709 } 1710 } 1711 1712 // Sanity check the window length. This will catch people mistakenly 1713 // trying to pass an end-of-window timestamp rather than a duration. 1714 if (windowLength > AlarmManager.INTERVAL_HALF_DAY) { 1715 Slog.w(TAG, "Window length " + windowLength 1716 + "ms suspiciously long; limiting to 1 hour"); 1717 windowLength = AlarmManager.INTERVAL_HOUR; 1718 } 1719 1720 // Sanity check the recurrence interval. This will catch people who supply 1721 // seconds when the API expects milliseconds, or apps trying shenanigans 1722 // around intentional period overflow, etc. 1723 final long minInterval = mConstants.MIN_INTERVAL; 1724 if (interval > 0 && interval < minInterval) { 1725 Slog.w(TAG, "Suspiciously short interval " + interval 1726 + " millis; expanding to " + (minInterval/1000) 1727 + " seconds"); 1728 interval = minInterval; 1729 } else if (interval > mConstants.MAX_INTERVAL) { 1730 Slog.w(TAG, "Suspiciously long interval " + interval 1731 + " millis; clamping"); 1732 interval = mConstants.MAX_INTERVAL; 1733 } 1734 1735 if (type < RTC_WAKEUP || type > ELAPSED_REALTIME) { 1736 throw new IllegalArgumentException("Invalid alarm type " + type); 1737 } 1738 1739 if (triggerAtTime < 0) { 1740 final long what = Binder.getCallingPid(); 1741 Slog.w(TAG, "Invalid alarm trigger time! " + triggerAtTime + " from uid=" + callingUid 1742 + " pid=" + what); 1743 triggerAtTime = 0; 1744 } 1745 1746 final long nowElapsed = mInjector.getElapsedRealtime(); 1747 final long nominalTrigger = convertToElapsed(triggerAtTime, type); 1748 // Try to prevent spamming by making sure apps aren't firing alarms in the immediate future 1749 final long minTrigger = nowElapsed 1750 + (UserHandle.isCore(callingUid) ? 0L : mConstants.MIN_FUTURITY); 1751 final long triggerElapsed = (nominalTrigger > minTrigger) ? nominalTrigger : minTrigger; 1752 1753 final long maxElapsed; 1754 if (windowLength == AlarmManager.WINDOW_EXACT) { 1755 maxElapsed = triggerElapsed; 1756 } else if (windowLength < 0) { 1757 maxElapsed = maxTriggerTime(nowElapsed, triggerElapsed, interval); 1758 // Fix this window in place, so that as time approaches we don't collapse it. 1759 windowLength = maxElapsed - triggerElapsed; 1760 } else { 1761 maxElapsed = triggerElapsed + windowLength; 1762 } 1763 synchronized (mLock) { 1764 if (DEBUG_BATCH) { 1765 Slog.v(TAG, "set(" + operation + ") : type=" + type 1766 + " triggerAtTime=" + triggerAtTime + " win=" + windowLength 1767 + " tElapsed=" + triggerElapsed + " maxElapsed=" + maxElapsed 1768 + " interval=" + interval + " flags=0x" + Integer.toHexString(flags)); 1769 } 1770 if (mAlarmsPerUid.get(callingUid, 0) >= mConstants.MAX_ALARMS_PER_UID) { 1771 final String errorMsg = 1772 "Maximum limit of concurrent alarms " + mConstants.MAX_ALARMS_PER_UID 1773 + " reached for uid: " + UserHandle.formatUid(callingUid) 1774 + ", callingPackage: " + callingPackage; 1775 Slog.w(TAG, errorMsg); 1776 if (DEBUG_PER_UID_LIMIT && UserHandle.isCore(callingUid)) { 1777 logAllAlarmsForUidLocked(callingUid); 1778 } 1779 throw new IllegalStateException(errorMsg); 1780 } 1781 setImplLocked(type, triggerAtTime, triggerElapsed, windowLength, maxElapsed, 1782 interval, operation, directReceiver, listenerTag, flags, true, workSource, 1783 alarmClock, callingUid, callingPackage); 1784 } 1785 } 1786 logAllAlarmsForUidLocked(int uid)1787 private void logAllAlarmsForUidLocked(int uid) { 1788 final StringWriter logWriter = new StringWriter(); 1789 final PrintWriter pw = new PrintWriter(logWriter); 1790 1791 pw.println("List of all pending alarms for " + UserHandle.formatUid(uid) + ":"); 1792 dumpUpcomingNAlarmsForUid(pw, uid, mConstants.MAX_ALARMS_PER_UID); 1793 pw.flush(); 1794 Slog.d(TAG, logWriter.toString()); 1795 } 1796 dumpUpcomingNAlarmsForUid(PrintWriter pw, int uid, int n)1797 private void dumpUpcomingNAlarmsForUid(PrintWriter pw, int uid, int n) { 1798 final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 1799 final long nowElapsed = mInjector.getElapsedRealtime(); 1800 final long nowRtc = mInjector.getCurrentTimeMillis(); 1801 1802 int count = 0; 1803 for (int i = 0; i < mAlarmBatches.size() && count < n; i++) { 1804 final Batch b = mAlarmBatches.get(i); 1805 for (int j = 0; j < b.size() && count < n; j++) { 1806 final Alarm a = b.get(j); 1807 if (a.uid == uid) { 1808 final String label = labelForType(a.type); 1809 pw.print(label + " #" + (++count) + ": "); 1810 pw.println(a); 1811 a.dump(pw, " ", nowElapsed, nowRtc, sdf); 1812 } 1813 } 1814 } 1815 } 1816 setImplLocked(int type, long when, long whenElapsed, long windowLength, long maxWhen, long interval, PendingIntent operation, IAlarmListener directReceiver, String listenerTag, int flags, boolean doValidate, WorkSource workSource, AlarmManager.AlarmClockInfo alarmClock, int callingUid, String callingPackage)1817 private void setImplLocked(int type, long when, long whenElapsed, long windowLength, 1818 long maxWhen, long interval, PendingIntent operation, IAlarmListener directReceiver, 1819 String listenerTag, int flags, boolean doValidate, WorkSource workSource, 1820 AlarmManager.AlarmClockInfo alarmClock, int callingUid, String callingPackage) { 1821 Alarm a = new Alarm(type, when, whenElapsed, windowLength, maxWhen, interval, 1822 operation, directReceiver, listenerTag, workSource, flags, alarmClock, 1823 callingUid, callingPackage); 1824 try { 1825 if (ActivityManager.getService().isAppStartModeDisabled(callingUid, callingPackage)) { 1826 Slog.w(TAG, "Not setting alarm from " + callingUid + ":" + a 1827 + " -- package not allowed to start"); 1828 return; 1829 } 1830 } catch (RemoteException e) { 1831 } 1832 removeLocked(operation, directReceiver); 1833 incrementAlarmCount(a.uid); 1834 setImplLocked(a, false, doValidate); 1835 } 1836 1837 /** 1838 * Returns the maximum alarms that an app in the specified bucket can receive in a rolling time 1839 * window given by {@link Constants#APP_STANDBY_WINDOW} 1840 */ 1841 @VisibleForTesting getQuotaForBucketLocked(int bucket)1842 int getQuotaForBucketLocked(int bucket) { 1843 final int index; 1844 if (bucket <= UsageStatsManager.STANDBY_BUCKET_ACTIVE) { 1845 index = ACTIVE_INDEX; 1846 } else if (bucket <= UsageStatsManager.STANDBY_BUCKET_WORKING_SET) { 1847 index = WORKING_INDEX; 1848 } else if (bucket <= UsageStatsManager.STANDBY_BUCKET_FREQUENT) { 1849 index = FREQUENT_INDEX; 1850 } else if (bucket < UsageStatsManager.STANDBY_BUCKET_NEVER) { 1851 index = RARE_INDEX; 1852 } else { 1853 index = NEVER_INDEX; 1854 } 1855 return mConstants.APP_STANDBY_QUOTAS[index]; 1856 } 1857 1858 /** 1859 * Adjusts the alarm delivery time based on the current app standby bucket. 1860 * @param alarm The alarm to adjust 1861 * @return true if the alarm delivery time was updated. 1862 */ adjustDeliveryTimeBasedOnBucketLocked(Alarm alarm)1863 private boolean adjustDeliveryTimeBasedOnBucketLocked(Alarm alarm) { 1864 if (isExemptFromAppStandby(alarm)) { 1865 return false; 1866 } 1867 if (mAppStandbyParole) { 1868 if (alarm.whenElapsed > alarm.expectedWhenElapsed) { 1869 // We did defer this alarm earlier, restore original requirements 1870 alarm.whenElapsed = alarm.expectedWhenElapsed; 1871 alarm.maxWhenElapsed = alarm.expectedMaxWhenElapsed; 1872 return true; 1873 } 1874 return false; 1875 } 1876 final long oldWhenElapsed = alarm.whenElapsed; 1877 final long oldMaxWhenElapsed = alarm.maxWhenElapsed; 1878 1879 final String sourcePackage = alarm.sourcePackage; 1880 final int sourceUserId = UserHandle.getUserId(alarm.creatorUid); 1881 final int standbyBucket = mUsageStatsManagerInternal.getAppStandbyBucket( 1882 sourcePackage, sourceUserId, mInjector.getElapsedRealtime()); 1883 1884 // Quota deferring implementation: 1885 boolean deferred = false; 1886 final int wakeupsInWindow = mAppWakeupHistory.getTotalWakeupsInWindow(sourcePackage, 1887 sourceUserId); 1888 if (standbyBucket == UsageStatsManager.STANDBY_BUCKET_RESTRICTED) { 1889 // Special case because it's 1/day instead of 1/hour. 1890 // AppWakeupHistory doesn't delete old wakeup times until a new one is logged, so we 1891 // should always have the last wakeup available. 1892 if (wakeupsInWindow > 0) { 1893 final long lastWakeupTime = mAppWakeupHistory.getNthLastWakeupForPackage( 1894 sourcePackage, sourceUserId, mConstants.APP_STANDBY_RESTRICTED_QUOTA); 1895 if (mInjector.getElapsedRealtime() - lastWakeupTime 1896 < mConstants.APP_STANDBY_RESTRICTED_WINDOW) { 1897 final long minElapsed = 1898 lastWakeupTime + mConstants.APP_STANDBY_RESTRICTED_WINDOW; 1899 if (alarm.expectedWhenElapsed < minElapsed) { 1900 alarm.whenElapsed = alarm.maxWhenElapsed = minElapsed; 1901 deferred = true; 1902 } 1903 } 1904 } 1905 } else { 1906 final int quotaForBucket = getQuotaForBucketLocked(standbyBucket); 1907 if (wakeupsInWindow >= quotaForBucket) { 1908 final long minElapsed; 1909 if (quotaForBucket <= 0) { 1910 // Just keep deferring for a day till the quota changes 1911 minElapsed = mInjector.getElapsedRealtime() + MILLIS_IN_DAY; 1912 } else { 1913 // Suppose the quota for window was q, and the qth last delivery time for this 1914 // package was t(q) then the next delivery must be after t(q) + <window_size> 1915 final long t = mAppWakeupHistory.getNthLastWakeupForPackage( 1916 sourcePackage, sourceUserId, quotaForBucket); 1917 minElapsed = t + mConstants.APP_STANDBY_WINDOW; 1918 } 1919 if (alarm.expectedWhenElapsed < minElapsed) { 1920 alarm.whenElapsed = alarm.maxWhenElapsed = minElapsed; 1921 deferred = true; 1922 } 1923 } 1924 } 1925 if (!deferred) { 1926 // Restore original requirements in case they were changed earlier. 1927 alarm.whenElapsed = alarm.expectedWhenElapsed; 1928 alarm.maxWhenElapsed = alarm.expectedMaxWhenElapsed; 1929 } 1930 1931 return (oldWhenElapsed != alarm.whenElapsed || oldMaxWhenElapsed != alarm.maxWhenElapsed); 1932 } 1933 setImplLocked(Alarm a, boolean rebatching, boolean doValidate)1934 private void setImplLocked(Alarm a, boolean rebatching, boolean doValidate) { 1935 if ((a.flags&AlarmManager.FLAG_IDLE_UNTIL) != 0) { 1936 // This is a special alarm that will put the system into idle until it goes off. 1937 // The caller has given the time they want this to happen at, however we need 1938 // to pull that earlier if there are existing alarms that have requested to 1939 // bring us out of idle at an earlier time. 1940 if (mNextWakeFromIdle != null && a.whenElapsed > mNextWakeFromIdle.whenElapsed) { 1941 a.when = a.whenElapsed = a.maxWhenElapsed = mNextWakeFromIdle.whenElapsed; 1942 } 1943 // Add fuzz to make the alarm go off some time before the actual desired time. 1944 final long nowElapsed = mInjector.getElapsedRealtime(); 1945 final int fuzz = fuzzForDuration(a.whenElapsed-nowElapsed); 1946 if (fuzz > 0) { 1947 if (mRandom == null) { 1948 mRandom = new Random(); 1949 } 1950 final int delta = mRandom.nextInt(fuzz); 1951 a.whenElapsed -= delta; 1952 if (false) { 1953 Slog.d(TAG, "Alarm when: " + a.whenElapsed); 1954 Slog.d(TAG, "Delta until alarm: " + (a.whenElapsed-nowElapsed)); 1955 Slog.d(TAG, "Applied fuzz: " + fuzz); 1956 Slog.d(TAG, "Final delta: " + delta); 1957 Slog.d(TAG, "Final when: " + a.whenElapsed); 1958 } 1959 a.when = a.maxWhenElapsed = a.whenElapsed; 1960 } 1961 1962 } else if (mPendingIdleUntil != null) { 1963 // We currently have an idle until alarm scheduled; if the new alarm has 1964 // not explicitly stated it wants to run while idle, then put it on hold. 1965 if ((a.flags&(AlarmManager.FLAG_ALLOW_WHILE_IDLE 1966 | AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED 1967 | AlarmManager.FLAG_WAKE_FROM_IDLE)) 1968 == 0) { 1969 mPendingWhileIdleAlarms.add(a); 1970 return; 1971 } 1972 } 1973 if (RECORD_DEVICE_IDLE_ALARMS) { 1974 if ((a.flags & AlarmManager.FLAG_ALLOW_WHILE_IDLE) != 0) { 1975 IdleDispatchEntry ent = new IdleDispatchEntry(); 1976 ent.uid = a.uid; 1977 ent.pkg = a.operation.getCreatorPackage(); 1978 ent.tag = a.operation.getTag(""); 1979 ent.op = "SET"; 1980 ent.elapsedRealtime = mInjector.getElapsedRealtime(); 1981 ent.argRealtime = a.whenElapsed; 1982 mAllowWhileIdleDispatches.add(ent); 1983 } 1984 } 1985 adjustDeliveryTimeBasedOnBucketLocked(a); 1986 insertAndBatchAlarmLocked(a); 1987 1988 if (a.alarmClock != null) { 1989 mNextAlarmClockMayChange = true; 1990 } 1991 1992 boolean needRebatch = false; 1993 1994 if ((a.flags&AlarmManager.FLAG_IDLE_UNTIL) != 0) { 1995 if (RECORD_DEVICE_IDLE_ALARMS) { 1996 if (mPendingIdleUntil == null) { 1997 IdleDispatchEntry ent = new IdleDispatchEntry(); 1998 ent.uid = 0; 1999 ent.pkg = "START IDLE"; 2000 ent.elapsedRealtime = mInjector.getElapsedRealtime(); 2001 mAllowWhileIdleDispatches.add(ent); 2002 } 2003 } 2004 if ((mPendingIdleUntil != a) && (mPendingIdleUntil != null)) { 2005 Slog.wtfStack(TAG, "setImplLocked: idle until changed from " + mPendingIdleUntil 2006 + " to " + a); 2007 } 2008 2009 mPendingIdleUntil = a; 2010 needRebatch = true; 2011 } else if ((a.flags&AlarmManager.FLAG_WAKE_FROM_IDLE) != 0) { 2012 if (mNextWakeFromIdle == null || mNextWakeFromIdle.whenElapsed > a.whenElapsed) { 2013 mNextWakeFromIdle = a; 2014 // If this wake from idle is earlier than whatever was previously scheduled, 2015 // and we are currently idling, then we need to rebatch alarms in case the idle 2016 // until time needs to be updated. 2017 if (mPendingIdleUntil != null) { 2018 needRebatch = true; 2019 } 2020 } 2021 } 2022 2023 if (!rebatching) { 2024 if (DEBUG_VALIDATE) { 2025 if (doValidate && !validateConsistencyLocked()) { 2026 Slog.v(TAG, "Tipping-point operation: type=" + a.type + " when=" + a.when 2027 + " when(hex)=" + Long.toHexString(a.when) 2028 + " whenElapsed=" + a.whenElapsed 2029 + " maxWhenElapsed=" + a.maxWhenElapsed 2030 + " interval=" + a.repeatInterval + " op=" + a.operation 2031 + " flags=0x" + Integer.toHexString(a.flags)); 2032 rebatchAllAlarmsLocked(false); 2033 needRebatch = false; 2034 } 2035 } 2036 2037 if (needRebatch) { 2038 rebatchAllAlarmsLocked(false); 2039 } 2040 2041 rescheduleKernelAlarmsLocked(); 2042 updateNextAlarmClockLocked(); 2043 } 2044 } 2045 2046 /** 2047 * System-process internal API 2048 */ 2049 private final class LocalService implements AlarmManagerInternal { 2050 @Override isIdling()2051 public boolean isIdling() { 2052 return isIdlingImpl(); 2053 } 2054 2055 @Override removeAlarmsForUid(int uid)2056 public void removeAlarmsForUid(int uid) { 2057 synchronized (mLock) { 2058 removeLocked(uid); 2059 } 2060 } 2061 2062 @Override remove(PendingIntent pi)2063 public void remove(PendingIntent pi) { 2064 mHandler.obtainMessage(AlarmHandler.REMOVE_FOR_CANCELED, pi).sendToTarget(); 2065 } 2066 2067 @Override registerInFlightListener(InFlightListener callback)2068 public void registerInFlightListener(InFlightListener callback) { 2069 synchronized (mLock) { 2070 mInFlightListeners.add(callback); 2071 } 2072 } 2073 } 2074 2075 /** 2076 * Public-facing binder interface 2077 */ 2078 private final IBinder mService = new IAlarmManager.Stub() { 2079 @Override 2080 public void set(String callingPackage, 2081 int type, long triggerAtTime, long windowLength, long interval, int flags, 2082 PendingIntent operation, IAlarmListener directReceiver, String listenerTag, 2083 WorkSource workSource, AlarmManager.AlarmClockInfo alarmClock) { 2084 final int callingUid = Binder.getCallingUid(); 2085 2086 // make sure the caller is not lying about which package should be blamed for 2087 // wakelock time spent in alarm delivery 2088 mAppOps.checkPackage(callingUid, callingPackage); 2089 2090 // Repeating alarms must use PendingIntent, not direct listener 2091 if (interval != 0) { 2092 if (directReceiver != null) { 2093 throw new IllegalArgumentException("Repeating alarms cannot use AlarmReceivers"); 2094 } 2095 } 2096 2097 if (workSource != null) { 2098 getContext().enforcePermission( 2099 android.Manifest.permission.UPDATE_DEVICE_STATS, 2100 Binder.getCallingPid(), callingUid, "AlarmManager.set"); 2101 } 2102 2103 // No incoming callers can request either WAKE_FROM_IDLE or 2104 // ALLOW_WHILE_IDLE_UNRESTRICTED -- we will apply those later as appropriate. 2105 flags &= ~(AlarmManager.FLAG_WAKE_FROM_IDLE 2106 | AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED); 2107 2108 // Only the system can use FLAG_IDLE_UNTIL -- this is used to tell the alarm 2109 // manager when to come out of idle mode, which is only for DeviceIdleController. 2110 if (callingUid != Process.SYSTEM_UID) { 2111 flags &= ~AlarmManager.FLAG_IDLE_UNTIL; 2112 } 2113 2114 // If this is an exact time alarm, then it can't be batched with other alarms. 2115 if (windowLength == AlarmManager.WINDOW_EXACT) { 2116 flags |= AlarmManager.FLAG_STANDALONE; 2117 } 2118 2119 // If this alarm is for an alarm clock, then it must be standalone and we will 2120 // use it to wake early from idle if needed. 2121 if (alarmClock != null) { 2122 flags |= AlarmManager.FLAG_WAKE_FROM_IDLE | AlarmManager.FLAG_STANDALONE; 2123 2124 // If the caller is a core system component or on the user's whitelist, and not calling 2125 // to do work on behalf of someone else, then always set ALLOW_WHILE_IDLE_UNRESTRICTED. 2126 // This means we will allow these alarms to go off as normal even while idle, with no 2127 // timing restrictions. 2128 } else if (workSource == null && (callingUid < Process.FIRST_APPLICATION_UID 2129 || UserHandle.isSameApp(callingUid, mSystemUiUid) 2130 || ((mAppStateTracker != null) 2131 && mAppStateTracker.isUidPowerSaveUserWhitelisted(callingUid)))) { 2132 flags |= AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED; 2133 flags &= ~AlarmManager.FLAG_ALLOW_WHILE_IDLE; 2134 } 2135 2136 setImpl(type, triggerAtTime, windowLength, interval, operation, directReceiver, 2137 listenerTag, flags, workSource, alarmClock, callingUid, callingPackage); 2138 } 2139 2140 @Override 2141 public boolean setTime(long millis) { 2142 getContext().enforceCallingOrSelfPermission( 2143 "android.permission.SET_TIME", 2144 "setTime"); 2145 2146 return setTimeImpl(millis); 2147 } 2148 2149 @Override 2150 public void setTimeZone(String tz) { 2151 getContext().enforceCallingOrSelfPermission( 2152 "android.permission.SET_TIME_ZONE", 2153 "setTimeZone"); 2154 2155 final long oldId = Binder.clearCallingIdentity(); 2156 try { 2157 setTimeZoneImpl(tz); 2158 } finally { 2159 Binder.restoreCallingIdentity(oldId); 2160 } 2161 } 2162 2163 @Override 2164 public void remove(PendingIntent operation, IAlarmListener listener) { 2165 if (operation == null && listener == null) { 2166 Slog.w(TAG, "remove() with no intent or listener"); 2167 return; 2168 } 2169 synchronized (mLock) { 2170 removeLocked(operation, listener); 2171 } 2172 } 2173 2174 @Override 2175 public long getNextWakeFromIdleTime() { 2176 return getNextWakeFromIdleTimeImpl(); 2177 } 2178 2179 @Override 2180 public AlarmManager.AlarmClockInfo getNextAlarmClock(int userId) { 2181 userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), 2182 Binder.getCallingUid(), userId, false /* allowAll */, false /* requireFull */, 2183 "getNextAlarmClock", null); 2184 2185 return getNextAlarmClockImpl(userId); 2186 } 2187 2188 @Override 2189 public long currentNetworkTimeMillis() { 2190 final NtpTrustedTime time = NtpTrustedTime.getInstance(getContext()); 2191 NtpTrustedTime.TimeResult ntpResult = time.getCachedTimeResult(); 2192 if (ntpResult != null) { 2193 return ntpResult.currentTimeMillis(); 2194 } else { 2195 throw new ParcelableException(new DateTimeException("Missing NTP fix")); 2196 } 2197 } 2198 2199 @Override 2200 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2201 if (!DumpUtils.checkDumpAndUsageStatsPermission(getContext(), TAG, pw)) return; 2202 2203 if (args.length > 0 && "--proto".equals(args[0])) { 2204 dumpProto(fd); 2205 } else { 2206 dumpImpl(pw); 2207 } 2208 } 2209 2210 @Override 2211 public void onShellCommand(FileDescriptor in, FileDescriptor out, 2212 FileDescriptor err, String[] args, ShellCallback callback, 2213 ResultReceiver resultReceiver) { 2214 (new ShellCmd()).exec(this, in, out, err, args, callback, resultReceiver); 2215 } 2216 }; 2217 dumpImpl(PrintWriter pw)2218 void dumpImpl(PrintWriter pw) { 2219 synchronized (mLock) { 2220 pw.println("Current Alarm Manager state:"); 2221 mConstants.dump(pw, " "); 2222 pw.println(); 2223 2224 if (mAppStateTracker != null) { 2225 mAppStateTracker.dump(pw, " "); 2226 pw.println(); 2227 } 2228 2229 pw.println(" App Standby Parole: " + mAppStandbyParole); 2230 pw.println(); 2231 2232 final long nowELAPSED = mInjector.getElapsedRealtime(); 2233 final long nowUPTIME = SystemClock.uptimeMillis(); 2234 final long nowRTC = mInjector.getCurrentTimeMillis(); 2235 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 2236 2237 pw.print(" nowRTC="); pw.print(nowRTC); 2238 pw.print("="); pw.print(sdf.format(new Date(nowRTC))); 2239 pw.print(" nowELAPSED="); pw.print(nowELAPSED); 2240 pw.println(); 2241 pw.print(" mLastTimeChangeClockTime="); pw.print(mLastTimeChangeClockTime); 2242 pw.print("="); pw.println(sdf.format(new Date(mLastTimeChangeClockTime))); 2243 pw.print(" mLastTimeChangeRealtime="); pw.println(mLastTimeChangeRealtime); 2244 pw.print(" mLastTickReceived="); pw.println(sdf.format(new Date(mLastTickReceived))); 2245 pw.print(" mLastTickSet="); pw.println(sdf.format(new Date(mLastTickSet))); 2246 pw.print(" mLastTickAdded="); pw.println(sdf.format(new Date(mLastTickAdded))); 2247 pw.print(" mLastTickRemoved="); pw.println(sdf.format(new Date(mLastTickRemoved))); 2248 2249 if (RECORD_ALARMS_IN_HISTORY) { 2250 pw.println(); 2251 pw.println(" Recent TIME_TICK history:"); 2252 int i = mNextTickHistory; 2253 do { 2254 i--; 2255 if (i < 0) i = TICK_HISTORY_DEPTH - 1; 2256 final long time = mTickHistory[i]; 2257 pw.print(" "); 2258 pw.println((time > 0) 2259 ? sdf.format(new Date(nowRTC - (nowELAPSED - time))) 2260 : "-"); 2261 } while (i != mNextTickHistory); 2262 } 2263 2264 SystemServiceManager ssm = LocalServices.getService(SystemServiceManager.class); 2265 if (ssm != null) { 2266 pw.println(); 2267 pw.print(" RuntimeStarted="); 2268 pw.print(sdf.format( 2269 new Date(nowRTC - nowELAPSED + ssm.getRuntimeStartElapsedTime()))); 2270 if (ssm.isRuntimeRestarted()) { 2271 pw.print(" (Runtime restarted)"); 2272 } 2273 pw.println(); 2274 pw.print(" Runtime uptime (elapsed): "); 2275 TimeUtils.formatDuration(nowELAPSED, ssm.getRuntimeStartElapsedTime(), pw); 2276 pw.println(); 2277 pw.print(" Runtime uptime (uptime): "); 2278 TimeUtils.formatDuration(nowUPTIME, ssm.getRuntimeStartUptime(), pw); 2279 pw.println(); 2280 } 2281 2282 pw.println(); 2283 if (!mInteractive) { 2284 pw.print(" Time since non-interactive: "); 2285 TimeUtils.formatDuration(nowELAPSED - mNonInteractiveStartTime, pw); 2286 pw.println(); 2287 } 2288 pw.print(" Max wakeup delay: "); 2289 TimeUtils.formatDuration(currentNonWakeupFuzzLocked(nowELAPSED), pw); 2290 pw.println(); 2291 pw.print(" Time since last dispatch: "); 2292 TimeUtils.formatDuration(nowELAPSED - mLastAlarmDeliveryTime, pw); 2293 pw.println(); 2294 pw.print(" Next non-wakeup delivery time: "); 2295 TimeUtils.formatDuration(mNextNonWakeupDeliveryTime, nowELAPSED, pw); 2296 pw.println(); 2297 2298 long nextWakeupRTC = mNextWakeup + (nowRTC - nowELAPSED); 2299 long nextNonWakeupRTC = mNextNonWakeup + (nowRTC - nowELAPSED); 2300 pw.print(" Next non-wakeup alarm: "); 2301 TimeUtils.formatDuration(mNextNonWakeup, nowELAPSED, pw); 2302 pw.print(" = "); pw.print(mNextNonWakeup); 2303 pw.print(" = "); pw.println(sdf.format(new Date(nextNonWakeupRTC))); 2304 pw.print(" set at "); TimeUtils.formatDuration(mNextNonWakeUpSetAt, nowELAPSED, pw); 2305 pw.println(); 2306 pw.print(" Next wakeup alarm: "); TimeUtils.formatDuration(mNextWakeup, nowELAPSED, pw); 2307 pw.print(" = "); pw.print(mNextWakeup); 2308 pw.print(" = "); pw.println(sdf.format(new Date(nextWakeupRTC))); 2309 pw.print(" set at "); TimeUtils.formatDuration(mNextWakeUpSetAt, nowELAPSED, pw); 2310 pw.println(); 2311 2312 pw.print(" Next kernel non-wakeup alarm: "); 2313 TimeUtils.formatDuration(mInjector.getNextAlarm(ELAPSED_REALTIME), pw); 2314 pw.println(); 2315 pw.print(" Next kernel wakeup alarm: "); 2316 TimeUtils.formatDuration(mInjector.getNextAlarm(ELAPSED_REALTIME_WAKEUP), pw); 2317 pw.println(); 2318 2319 pw.print(" Last wakeup: "); TimeUtils.formatDuration(mLastWakeup, nowELAPSED, pw); 2320 pw.print(" = "); pw.println(mLastWakeup); 2321 pw.print(" Last trigger: "); TimeUtils.formatDuration(mLastTrigger, nowELAPSED, pw); 2322 pw.print(" = "); pw.println(mLastTrigger); 2323 pw.print(" Num time change events: "); pw.println(mNumTimeChanged); 2324 2325 pw.println(); 2326 pw.println(" Next alarm clock information: "); 2327 final TreeSet<Integer> users = new TreeSet<>(); 2328 for (int i = 0; i < mNextAlarmClockForUser.size(); i++) { 2329 users.add(mNextAlarmClockForUser.keyAt(i)); 2330 } 2331 for (int i = 0; i < mPendingSendNextAlarmClockChangedForUser.size(); i++) { 2332 users.add(mPendingSendNextAlarmClockChangedForUser.keyAt(i)); 2333 } 2334 for (int user : users) { 2335 final AlarmManager.AlarmClockInfo next = mNextAlarmClockForUser.get(user); 2336 final long time = next != null ? next.getTriggerTime() : 0; 2337 final boolean pendingSend = mPendingSendNextAlarmClockChangedForUser.get(user); 2338 pw.print(" user:"); pw.print(user); 2339 pw.print(" pendingSend:"); pw.print(pendingSend); 2340 pw.print(" time:"); pw.print(time); 2341 if (time > 0) { 2342 pw.print(" = "); pw.print(sdf.format(new Date(time))); 2343 pw.print(" = "); TimeUtils.formatDuration(time, nowRTC, pw); 2344 } 2345 pw.println(); 2346 } 2347 if (mAlarmBatches.size() > 0) { 2348 pw.println(); 2349 pw.print(" Pending alarm batches: "); 2350 pw.println(mAlarmBatches.size()); 2351 for (Batch b : mAlarmBatches) { 2352 pw.print(b); pw.println(':'); 2353 dumpAlarmList(pw, b.alarms, " ", nowELAPSED, nowRTC, sdf); 2354 } 2355 } 2356 pw.println(); 2357 pw.println(" Pending user blocked background alarms: "); 2358 boolean blocked = false; 2359 for (int i = 0; i < mPendingBackgroundAlarms.size(); i++) { 2360 final ArrayList<Alarm> blockedAlarms = mPendingBackgroundAlarms.valueAt(i); 2361 if (blockedAlarms != null && blockedAlarms.size() > 0) { 2362 blocked = true; 2363 dumpAlarmList(pw, blockedAlarms, " ", nowELAPSED, nowRTC, sdf); 2364 } 2365 } 2366 if (!blocked) { 2367 pw.println(" none"); 2368 } 2369 pw.println(); 2370 pw.print(" Pending alarms per uid: ["); 2371 for (int i = 0; i < mAlarmsPerUid.size(); i++) { 2372 if (i > 0) { 2373 pw.print(", "); 2374 } 2375 UserHandle.formatUid(pw, mAlarmsPerUid.keyAt(i)); 2376 pw.print(":"); 2377 pw.print(mAlarmsPerUid.valueAt(i)); 2378 } 2379 pw.println("]"); 2380 pw.println(); 2381 2382 mAppWakeupHistory.dump(pw, " ", nowELAPSED); 2383 2384 if (mPendingIdleUntil != null || mPendingWhileIdleAlarms.size() > 0) { 2385 pw.println(); 2386 pw.println(" Idle mode state:"); 2387 pw.print(" Idling until: "); 2388 if (mPendingIdleUntil != null) { 2389 pw.println(mPendingIdleUntil); 2390 mPendingIdleUntil.dump(pw, " ", nowELAPSED, nowRTC, sdf); 2391 } else { 2392 pw.println("null"); 2393 } 2394 pw.println(" Pending alarms:"); 2395 dumpAlarmList(pw, mPendingWhileIdleAlarms, " ", nowELAPSED, nowRTC, sdf); 2396 } 2397 if (mNextWakeFromIdle != null) { 2398 pw.println(); 2399 pw.print(" Next wake from idle: "); pw.println(mNextWakeFromIdle); 2400 mNextWakeFromIdle.dump(pw, " ", nowELAPSED, nowRTC, sdf); 2401 } 2402 2403 pw.println(); 2404 pw.print(" Past-due non-wakeup alarms: "); 2405 if (mPendingNonWakeupAlarms.size() > 0) { 2406 pw.println(mPendingNonWakeupAlarms.size()); 2407 dumpAlarmList(pw, mPendingNonWakeupAlarms, " ", nowELAPSED, nowRTC, sdf); 2408 } else { 2409 pw.println("(none)"); 2410 } 2411 pw.print(" Number of delayed alarms: "); pw.print(mNumDelayedAlarms); 2412 pw.print(", total delay time: "); TimeUtils.formatDuration(mTotalDelayTime, pw); 2413 pw.println(); 2414 pw.print(" Max delay time: "); TimeUtils.formatDuration(mMaxDelayTime, pw); 2415 pw.print(", max non-interactive time: "); 2416 TimeUtils.formatDuration(mNonInteractiveTime, pw); 2417 pw.println(); 2418 2419 pw.println(); 2420 pw.print(" Broadcast ref count: "); pw.println(mBroadcastRefCount); 2421 pw.print(" PendingIntent send count: "); pw.println(mSendCount); 2422 pw.print(" PendingIntent finish count: "); pw.println(mSendFinishCount); 2423 pw.print(" Listener send count: "); pw.println(mListenerCount); 2424 pw.print(" Listener finish count: "); pw.println(mListenerFinishCount); 2425 pw.println(); 2426 2427 if (mInFlight.size() > 0) { 2428 pw.println("Outstanding deliveries:"); 2429 for (int i = 0; i < mInFlight.size(); i++) { 2430 pw.print(" #"); pw.print(i); pw.print(": "); 2431 pw.println(mInFlight.get(i)); 2432 } 2433 pw.println(); 2434 } 2435 2436 if (mLastAllowWhileIdleDispatch.size() > 0) { 2437 pw.println(" Last allow while idle dispatch times:"); 2438 for (int i=0; i<mLastAllowWhileIdleDispatch.size(); i++) { 2439 pw.print(" UID "); 2440 final int uid = mLastAllowWhileIdleDispatch.keyAt(i); 2441 UserHandle.formatUid(pw, uid); 2442 pw.print(": "); 2443 final long lastTime = mLastAllowWhileIdleDispatch.valueAt(i); 2444 TimeUtils.formatDuration(lastTime, nowELAPSED, pw); 2445 2446 final long minInterval = getWhileIdleMinIntervalLocked(uid); 2447 pw.print(" Next allowed:"); 2448 TimeUtils.formatDuration(lastTime + minInterval, nowELAPSED, pw); 2449 pw.print(" ("); 2450 TimeUtils.formatDuration(minInterval, 0, pw); 2451 pw.print(")"); 2452 2453 pw.println(); 2454 } 2455 } 2456 2457 pw.print(" mUseAllowWhileIdleShortTime: ["); 2458 for (int i = 0; i < mUseAllowWhileIdleShortTime.size(); i++) { 2459 if (mUseAllowWhileIdleShortTime.valueAt(i)) { 2460 UserHandle.formatUid(pw, mUseAllowWhileIdleShortTime.keyAt(i)); 2461 pw.print(" "); 2462 } 2463 } 2464 pw.println("]"); 2465 pw.println(); 2466 2467 if (mLog.dump(pw, " Recent problems", " ")) { 2468 pw.println(); 2469 } 2470 2471 final FilterStats[] topFilters = new FilterStats[10]; 2472 final Comparator<FilterStats> comparator = new Comparator<FilterStats>() { 2473 @Override 2474 public int compare(FilterStats lhs, FilterStats rhs) { 2475 if (lhs.aggregateTime < rhs.aggregateTime) { 2476 return 1; 2477 } else if (lhs.aggregateTime > rhs.aggregateTime) { 2478 return -1; 2479 } 2480 return 0; 2481 } 2482 }; 2483 int len = 0; 2484 // Get the top 10 FilterStats, ordered by aggregateTime. 2485 for (int iu=0; iu<mBroadcastStats.size(); iu++) { 2486 ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(iu); 2487 for (int ip=0; ip<uidStats.size(); ip++) { 2488 BroadcastStats bs = uidStats.valueAt(ip); 2489 for (int is=0; is<bs.filterStats.size(); is++) { 2490 FilterStats fs = bs.filterStats.valueAt(is); 2491 int pos = len > 0 2492 ? Arrays.binarySearch(topFilters, 0, len, fs, comparator) : 0; 2493 if (pos < 0) { 2494 pos = -pos - 1; 2495 } 2496 if (pos < topFilters.length) { 2497 int copylen = topFilters.length - pos - 1; 2498 if (copylen > 0) { 2499 System.arraycopy(topFilters, pos, topFilters, pos+1, copylen); 2500 } 2501 topFilters[pos] = fs; 2502 if (len < topFilters.length) { 2503 len++; 2504 } 2505 } 2506 } 2507 } 2508 } 2509 if (len > 0) { 2510 pw.println(" Top Alarms:"); 2511 for (int i=0; i<len; i++) { 2512 FilterStats fs = topFilters[i]; 2513 pw.print(" "); 2514 if (fs.nesting > 0) pw.print("*ACTIVE* "); 2515 TimeUtils.formatDuration(fs.aggregateTime, pw); 2516 pw.print(" running, "); pw.print(fs.numWakeup); 2517 pw.print(" wakeups, "); pw.print(fs.count); 2518 pw.print(" alarms: "); UserHandle.formatUid(pw, fs.mBroadcastStats.mUid); 2519 pw.print(":"); pw.print(fs.mBroadcastStats.mPackageName); 2520 pw.println(); 2521 pw.print(" "); pw.print(fs.mTag); 2522 pw.println(); 2523 } 2524 } 2525 2526 pw.println(" "); 2527 pw.println(" Alarm Stats:"); 2528 final ArrayList<FilterStats> tmpFilters = new ArrayList<FilterStats>(); 2529 for (int iu=0; iu<mBroadcastStats.size(); iu++) { 2530 ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(iu); 2531 for (int ip=0; ip<uidStats.size(); ip++) { 2532 BroadcastStats bs = uidStats.valueAt(ip); 2533 pw.print(" "); 2534 if (bs.nesting > 0) pw.print("*ACTIVE* "); 2535 UserHandle.formatUid(pw, bs.mUid); 2536 pw.print(":"); 2537 pw.print(bs.mPackageName); 2538 pw.print(" "); TimeUtils.formatDuration(bs.aggregateTime, pw); 2539 pw.print(" running, "); pw.print(bs.numWakeup); 2540 pw.println(" wakeups:"); 2541 tmpFilters.clear(); 2542 for (int is=0; is<bs.filterStats.size(); is++) { 2543 tmpFilters.add(bs.filterStats.valueAt(is)); 2544 } 2545 Collections.sort(tmpFilters, comparator); 2546 for (int i=0; i<tmpFilters.size(); i++) { 2547 FilterStats fs = tmpFilters.get(i); 2548 pw.print(" "); 2549 if (fs.nesting > 0) pw.print("*ACTIVE* "); 2550 TimeUtils.formatDuration(fs.aggregateTime, pw); 2551 pw.print(" "); pw.print(fs.numWakeup); 2552 pw.print(" wakes " ); pw.print(fs.count); 2553 pw.print(" alarms, last "); 2554 TimeUtils.formatDuration(fs.lastTime, nowELAPSED, pw); 2555 pw.println(":"); 2556 pw.print(" "); 2557 pw.print(fs.mTag); 2558 pw.println(); 2559 } 2560 } 2561 } 2562 pw.println(); 2563 mStatLogger.dump(pw, " "); 2564 2565 if (RECORD_DEVICE_IDLE_ALARMS) { 2566 pw.println(); 2567 pw.println(" Allow while idle dispatches:"); 2568 for (int i = 0; i < mAllowWhileIdleDispatches.size(); i++) { 2569 IdleDispatchEntry ent = mAllowWhileIdleDispatches.get(i); 2570 pw.print(" "); 2571 TimeUtils.formatDuration(ent.elapsedRealtime, nowELAPSED, pw); 2572 pw.print(": "); 2573 UserHandle.formatUid(pw, ent.uid); 2574 pw.print(":"); 2575 pw.println(ent.pkg); 2576 if (ent.op != null) { 2577 pw.print(" "); 2578 pw.print(ent.op); 2579 pw.print(" / "); 2580 pw.print(ent.tag); 2581 if (ent.argRealtime != 0) { 2582 pw.print(" ("); 2583 TimeUtils.formatDuration(ent.argRealtime, nowELAPSED, pw); 2584 pw.print(")"); 2585 } 2586 pw.println(); 2587 } 2588 } 2589 } 2590 2591 if (WAKEUP_STATS) { 2592 pw.println(); 2593 pw.println(" Recent Wakeup History:"); 2594 long last = -1; 2595 for (WakeupEvent event : mRecentWakeups) { 2596 pw.print(" "); pw.print(sdf.format(new Date(event.when))); 2597 pw.print('|'); 2598 if (last < 0) { 2599 pw.print('0'); 2600 } else { 2601 pw.print(event.when - last); 2602 } 2603 last = event.when; 2604 pw.print('|'); pw.print(event.uid); 2605 pw.print('|'); pw.print(event.action); 2606 pw.println(); 2607 } 2608 pw.println(); 2609 } 2610 } 2611 } 2612 dumpProto(FileDescriptor fd)2613 void dumpProto(FileDescriptor fd) { 2614 final ProtoOutputStream proto = new ProtoOutputStream(fd); 2615 2616 synchronized (mLock) { 2617 final long nowRTC = mInjector.getCurrentTimeMillis(); 2618 final long nowElapsed = mInjector.getElapsedRealtime(); 2619 proto.write(AlarmManagerServiceDumpProto.CURRENT_TIME, nowRTC); 2620 proto.write(AlarmManagerServiceDumpProto.ELAPSED_REALTIME, nowElapsed); 2621 proto.write(AlarmManagerServiceDumpProto.LAST_TIME_CHANGE_CLOCK_TIME, 2622 mLastTimeChangeClockTime); 2623 proto.write(AlarmManagerServiceDumpProto.LAST_TIME_CHANGE_REALTIME, 2624 mLastTimeChangeRealtime); 2625 2626 mConstants.dumpProto(proto, AlarmManagerServiceDumpProto.SETTINGS); 2627 2628 if (mAppStateTracker != null) { 2629 mAppStateTracker.dumpProto(proto, AlarmManagerServiceDumpProto.APP_STATE_TRACKER); 2630 } 2631 2632 proto.write(AlarmManagerServiceDumpProto.IS_INTERACTIVE, mInteractive); 2633 if (!mInteractive) { 2634 // Durations 2635 proto.write(AlarmManagerServiceDumpProto.TIME_SINCE_NON_INTERACTIVE_MS, 2636 nowElapsed - mNonInteractiveStartTime); 2637 proto.write(AlarmManagerServiceDumpProto.MAX_WAKEUP_DELAY_MS, 2638 currentNonWakeupFuzzLocked(nowElapsed)); 2639 proto.write(AlarmManagerServiceDumpProto.TIME_SINCE_LAST_DISPATCH_MS, 2640 nowElapsed - mLastAlarmDeliveryTime); 2641 proto.write(AlarmManagerServiceDumpProto.TIME_UNTIL_NEXT_NON_WAKEUP_DELIVERY_MS, 2642 nowElapsed - mNextNonWakeupDeliveryTime); 2643 } 2644 2645 proto.write(AlarmManagerServiceDumpProto.TIME_UNTIL_NEXT_NON_WAKEUP_ALARM_MS, 2646 mNextNonWakeup - nowElapsed); 2647 proto.write(AlarmManagerServiceDumpProto.TIME_UNTIL_NEXT_WAKEUP_MS, 2648 mNextWakeup - nowElapsed); 2649 proto.write(AlarmManagerServiceDumpProto.TIME_SINCE_LAST_WAKEUP_MS, 2650 nowElapsed - mLastWakeup); 2651 proto.write(AlarmManagerServiceDumpProto.TIME_SINCE_LAST_WAKEUP_SET_MS, 2652 nowElapsed - mNextWakeUpSetAt); 2653 proto.write(AlarmManagerServiceDumpProto.TIME_CHANGE_EVENT_COUNT, mNumTimeChanged); 2654 2655 final TreeSet<Integer> users = new TreeSet<>(); 2656 final int nextAlarmClockForUserSize = mNextAlarmClockForUser.size(); 2657 for (int i = 0; i < nextAlarmClockForUserSize; i++) { 2658 users.add(mNextAlarmClockForUser.keyAt(i)); 2659 } 2660 final int pendingSendNextAlarmClockChangedForUserSize = 2661 mPendingSendNextAlarmClockChangedForUser.size(); 2662 for (int i = 0; i < pendingSendNextAlarmClockChangedForUserSize; i++) { 2663 users.add(mPendingSendNextAlarmClockChangedForUser.keyAt(i)); 2664 } 2665 for (int user : users) { 2666 final AlarmManager.AlarmClockInfo next = mNextAlarmClockForUser.get(user); 2667 final long time = next != null ? next.getTriggerTime() : 0; 2668 final boolean pendingSend = mPendingSendNextAlarmClockChangedForUser.get(user); 2669 final long aToken = proto.start(AlarmManagerServiceDumpProto.NEXT_ALARM_CLOCK_METADATA); 2670 proto.write(AlarmClockMetadataProto.USER, user); 2671 proto.write(AlarmClockMetadataProto.IS_PENDING_SEND, pendingSend); 2672 proto.write(AlarmClockMetadataProto.TRIGGER_TIME_MS, time); 2673 proto.end(aToken); 2674 } 2675 for (Batch b : mAlarmBatches) { 2676 b.dumpDebug(proto, AlarmManagerServiceDumpProto.PENDING_ALARM_BATCHES, 2677 nowElapsed, nowRTC); 2678 } 2679 for (int i = 0; i < mPendingBackgroundAlarms.size(); i++) { 2680 final ArrayList<Alarm> blockedAlarms = mPendingBackgroundAlarms.valueAt(i); 2681 if (blockedAlarms != null) { 2682 for (Alarm a : blockedAlarms) { 2683 a.dumpDebug(proto, 2684 AlarmManagerServiceDumpProto.PENDING_USER_BLOCKED_BACKGROUND_ALARMS, 2685 nowElapsed, nowRTC); 2686 } 2687 } 2688 } 2689 if (mPendingIdleUntil != null) { 2690 mPendingIdleUntil.dumpDebug( 2691 proto, AlarmManagerServiceDumpProto.PENDING_IDLE_UNTIL, nowElapsed, nowRTC); 2692 } 2693 for (Alarm a : mPendingWhileIdleAlarms) { 2694 a.dumpDebug(proto, AlarmManagerServiceDumpProto.PENDING_WHILE_IDLE_ALARMS, 2695 nowElapsed, nowRTC); 2696 } 2697 if (mNextWakeFromIdle != null) { 2698 mNextWakeFromIdle.dumpDebug(proto, AlarmManagerServiceDumpProto.NEXT_WAKE_FROM_IDLE, 2699 nowElapsed, nowRTC); 2700 } 2701 2702 for (Alarm a : mPendingNonWakeupAlarms) { 2703 a.dumpDebug(proto, AlarmManagerServiceDumpProto.PAST_DUE_NON_WAKEUP_ALARMS, 2704 nowElapsed, nowRTC); 2705 } 2706 2707 proto.write(AlarmManagerServiceDumpProto.DELAYED_ALARM_COUNT, mNumDelayedAlarms); 2708 proto.write(AlarmManagerServiceDumpProto.TOTAL_DELAY_TIME_MS, mTotalDelayTime); 2709 proto.write(AlarmManagerServiceDumpProto.MAX_DELAY_DURATION_MS, mMaxDelayTime); 2710 proto.write(AlarmManagerServiceDumpProto.MAX_NON_INTERACTIVE_DURATION_MS, 2711 mNonInteractiveTime); 2712 2713 proto.write(AlarmManagerServiceDumpProto.BROADCAST_REF_COUNT, mBroadcastRefCount); 2714 proto.write(AlarmManagerServiceDumpProto.PENDING_INTENT_SEND_COUNT, mSendCount); 2715 proto.write(AlarmManagerServiceDumpProto.PENDING_INTENT_FINISH_COUNT, mSendFinishCount); 2716 proto.write(AlarmManagerServiceDumpProto.LISTENER_SEND_COUNT, mListenerCount); 2717 proto.write(AlarmManagerServiceDumpProto.LISTENER_FINISH_COUNT, mListenerFinishCount); 2718 2719 for (InFlight f : mInFlight) { 2720 f.dumpDebug(proto, AlarmManagerServiceDumpProto.OUTSTANDING_DELIVERIES); 2721 } 2722 2723 for (int i = 0; i < mLastAllowWhileIdleDispatch.size(); ++i) { 2724 final long token = proto.start( 2725 AlarmManagerServiceDumpProto.LAST_ALLOW_WHILE_IDLE_DISPATCH_TIMES); 2726 final int uid = mLastAllowWhileIdleDispatch.keyAt(i); 2727 final long lastTime = mLastAllowWhileIdleDispatch.valueAt(i); 2728 2729 proto.write(AlarmManagerServiceDumpProto.LastAllowWhileIdleDispatch.UID, uid); 2730 proto.write(AlarmManagerServiceDumpProto.LastAllowWhileIdleDispatch.TIME_MS, lastTime); 2731 proto.write(AlarmManagerServiceDumpProto.LastAllowWhileIdleDispatch.NEXT_ALLOWED_MS, 2732 lastTime + getWhileIdleMinIntervalLocked(uid)); 2733 proto.end(token); 2734 } 2735 2736 for (int i = 0; i < mUseAllowWhileIdleShortTime.size(); i++) { 2737 if (mUseAllowWhileIdleShortTime.valueAt(i)) { 2738 proto.write(AlarmManagerServiceDumpProto.USE_ALLOW_WHILE_IDLE_SHORT_TIME, 2739 mUseAllowWhileIdleShortTime.keyAt(i)); 2740 } 2741 } 2742 2743 mLog.dumpDebug(proto, AlarmManagerServiceDumpProto.RECENT_PROBLEMS); 2744 2745 final FilterStats[] topFilters = new FilterStats[10]; 2746 final Comparator<FilterStats> comparator = new Comparator<FilterStats>() { 2747 @Override 2748 public int compare(FilterStats lhs, FilterStats rhs) { 2749 if (lhs.aggregateTime < rhs.aggregateTime) { 2750 return 1; 2751 } else if (lhs.aggregateTime > rhs.aggregateTime) { 2752 return -1; 2753 } 2754 return 0; 2755 } 2756 }; 2757 int len = 0; 2758 // Get the top 10 FilterStats, ordered by aggregateTime. 2759 for (int iu = 0; iu < mBroadcastStats.size(); ++iu) { 2760 ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(iu); 2761 for (int ip = 0; ip < uidStats.size(); ++ip) { 2762 BroadcastStats bs = uidStats.valueAt(ip); 2763 for (int is = 0; is < bs.filterStats.size(); ++is) { 2764 FilterStats fs = bs.filterStats.valueAt(is); 2765 int pos = len > 0 2766 ? Arrays.binarySearch(topFilters, 0, len, fs, comparator) : 0; 2767 if (pos < 0) { 2768 pos = -pos - 1; 2769 } 2770 if (pos < topFilters.length) { 2771 int copylen = topFilters.length - pos - 1; 2772 if (copylen > 0) { 2773 System.arraycopy(topFilters, pos, topFilters, pos+1, copylen); 2774 } 2775 topFilters[pos] = fs; 2776 if (len < topFilters.length) { 2777 len++; 2778 } 2779 } 2780 } 2781 } 2782 } 2783 for (int i = 0; i < len; ++i) { 2784 final long token = proto.start(AlarmManagerServiceDumpProto.TOP_ALARMS); 2785 FilterStats fs = topFilters[i]; 2786 2787 proto.write(AlarmManagerServiceDumpProto.TopAlarm.UID, fs.mBroadcastStats.mUid); 2788 proto.write(AlarmManagerServiceDumpProto.TopAlarm.PACKAGE_NAME, 2789 fs.mBroadcastStats.mPackageName); 2790 fs.dumpDebug(proto, AlarmManagerServiceDumpProto.TopAlarm.FILTER); 2791 2792 proto.end(token); 2793 } 2794 2795 final ArrayList<FilterStats> tmpFilters = new ArrayList<FilterStats>(); 2796 for (int iu = 0; iu < mBroadcastStats.size(); ++iu) { 2797 ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(iu); 2798 for (int ip = 0; ip < uidStats.size(); ++ip) { 2799 final long token = proto.start(AlarmManagerServiceDumpProto.ALARM_STATS); 2800 2801 BroadcastStats bs = uidStats.valueAt(ip); 2802 bs.dumpDebug(proto, AlarmManagerServiceDumpProto.AlarmStat.BROADCAST); 2803 2804 // uidStats is an ArrayMap, which we can't sort. 2805 tmpFilters.clear(); 2806 for (int is = 0; is < bs.filterStats.size(); ++is) { 2807 tmpFilters.add(bs.filterStats.valueAt(is)); 2808 } 2809 Collections.sort(tmpFilters, comparator); 2810 for (FilterStats fs : tmpFilters) { 2811 fs.dumpDebug(proto, AlarmManagerServiceDumpProto.AlarmStat.FILTERS); 2812 } 2813 2814 proto.end(token); 2815 } 2816 } 2817 2818 if (RECORD_DEVICE_IDLE_ALARMS) { 2819 for (int i = 0; i < mAllowWhileIdleDispatches.size(); i++) { 2820 IdleDispatchEntry ent = mAllowWhileIdleDispatches.get(i); 2821 final long token = proto.start( 2822 AlarmManagerServiceDumpProto.ALLOW_WHILE_IDLE_DISPATCHES); 2823 2824 proto.write(IdleDispatchEntryProto.UID, ent.uid); 2825 proto.write(IdleDispatchEntryProto.PKG, ent.pkg); 2826 proto.write(IdleDispatchEntryProto.TAG, ent.tag); 2827 proto.write(IdleDispatchEntryProto.OP, ent.op); 2828 proto.write(IdleDispatchEntryProto.ENTRY_CREATION_REALTIME, 2829 ent.elapsedRealtime); 2830 proto.write(IdleDispatchEntryProto.ARG_REALTIME, ent.argRealtime); 2831 2832 proto.end(token); 2833 } 2834 } 2835 2836 if (WAKEUP_STATS) { 2837 for (WakeupEvent event : mRecentWakeups) { 2838 final long token = proto.start(AlarmManagerServiceDumpProto.RECENT_WAKEUP_HISTORY); 2839 proto.write(WakeupEventProto.UID, event.uid); 2840 proto.write(WakeupEventProto.ACTION, event.action); 2841 proto.write(WakeupEventProto.WHEN, event.when); 2842 proto.end(token); 2843 } 2844 } 2845 } 2846 2847 proto.flush(); 2848 } 2849 logBatchesLocked(SimpleDateFormat sdf)2850 private void logBatchesLocked(SimpleDateFormat sdf) { 2851 ByteArrayOutputStream bs = new ByteArrayOutputStream(2048); 2852 PrintWriter pw = new PrintWriter(bs); 2853 final long nowRTC = mInjector.getCurrentTimeMillis(); 2854 final long nowELAPSED = mInjector.getElapsedRealtime(); 2855 final int NZ = mAlarmBatches.size(); 2856 for (int iz = 0; iz < NZ; iz++) { 2857 Batch bz = mAlarmBatches.get(iz); 2858 pw.append("Batch "); pw.print(iz); pw.append(": "); pw.println(bz); 2859 dumpAlarmList(pw, bz.alarms, " ", nowELAPSED, nowRTC, sdf); 2860 pw.flush(); 2861 Slog.v(TAG, bs.toString()); 2862 bs.reset(); 2863 } 2864 } 2865 validateConsistencyLocked()2866 private boolean validateConsistencyLocked() { 2867 if (DEBUG_VALIDATE) { 2868 long lastTime = Long.MIN_VALUE; 2869 final int N = mAlarmBatches.size(); 2870 for (int i = 0; i < N; i++) { 2871 Batch b = mAlarmBatches.get(i); 2872 if (b.start >= lastTime) { 2873 // duplicate start times are okay because of standalone batches 2874 lastTime = b.start; 2875 } else { 2876 Slog.e(TAG, "CONSISTENCY FAILURE: Batch " + i + " is out of order"); 2877 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 2878 logBatchesLocked(sdf); 2879 return false; 2880 } 2881 } 2882 } 2883 return true; 2884 } 2885 findFirstWakeupBatchLocked()2886 private Batch findFirstWakeupBatchLocked() { 2887 final int N = mAlarmBatches.size(); 2888 for (int i = 0; i < N; i++) { 2889 Batch b = mAlarmBatches.get(i); 2890 if (b.hasWakeups()) { 2891 return b; 2892 } 2893 } 2894 return null; 2895 } 2896 getNextWakeFromIdleTimeImpl()2897 long getNextWakeFromIdleTimeImpl() { 2898 synchronized (mLock) { 2899 return mNextWakeFromIdle != null ? mNextWakeFromIdle.whenElapsed : Long.MAX_VALUE; 2900 } 2901 } 2902 isIdlingImpl()2903 private boolean isIdlingImpl() { 2904 synchronized (mLock) { 2905 return mPendingIdleUntil != null; 2906 } 2907 } 2908 getNextAlarmClockImpl(int userId)2909 AlarmManager.AlarmClockInfo getNextAlarmClockImpl(int userId) { 2910 synchronized (mLock) { 2911 return mNextAlarmClockForUser.get(userId); 2912 } 2913 } 2914 2915 /** 2916 * Recomputes the next alarm clock for all users. 2917 */ updateNextAlarmClockLocked()2918 private void updateNextAlarmClockLocked() { 2919 if (!mNextAlarmClockMayChange) { 2920 return; 2921 } 2922 mNextAlarmClockMayChange = false; 2923 2924 SparseArray<AlarmManager.AlarmClockInfo> nextForUser = mTmpSparseAlarmClockArray; 2925 nextForUser.clear(); 2926 2927 final int N = mAlarmBatches.size(); 2928 for (int i = 0; i < N; i++) { 2929 ArrayList<Alarm> alarms = mAlarmBatches.get(i).alarms; 2930 final int M = alarms.size(); 2931 2932 for (int j = 0; j < M; j++) { 2933 Alarm a = alarms.get(j); 2934 if (a.alarmClock != null) { 2935 final int userId = UserHandle.getUserId(a.uid); 2936 AlarmManager.AlarmClockInfo current = mNextAlarmClockForUser.get(userId); 2937 2938 if (DEBUG_ALARM_CLOCK) { 2939 Log.v(TAG, "Found AlarmClockInfo " + a.alarmClock + " at " + 2940 formatNextAlarm(getContext(), a.alarmClock, userId) + 2941 " for user " + userId); 2942 } 2943 2944 // Alarms and batches are sorted by time, no need to compare times here. 2945 if (nextForUser.get(userId) == null) { 2946 nextForUser.put(userId, a.alarmClock); 2947 } else if (a.alarmClock.equals(current) 2948 && current.getTriggerTime() <= nextForUser.get(userId).getTriggerTime()) { 2949 // same/earlier time and it's the one we cited before, so stick with it 2950 nextForUser.put(userId, current); 2951 } 2952 } 2953 } 2954 } 2955 2956 // Update mNextAlarmForUser with new values. 2957 final int NN = nextForUser.size(); 2958 for (int i = 0; i < NN; i++) { 2959 AlarmManager.AlarmClockInfo newAlarm = nextForUser.valueAt(i); 2960 int userId = nextForUser.keyAt(i); 2961 AlarmManager.AlarmClockInfo currentAlarm = mNextAlarmClockForUser.get(userId); 2962 if (!newAlarm.equals(currentAlarm)) { 2963 updateNextAlarmInfoForUserLocked(userId, newAlarm); 2964 } 2965 } 2966 2967 // Remove users without any alarm clocks scheduled. 2968 final int NNN = mNextAlarmClockForUser.size(); 2969 for (int i = NNN - 1; i >= 0; i--) { 2970 int userId = mNextAlarmClockForUser.keyAt(i); 2971 if (nextForUser.get(userId) == null) { 2972 updateNextAlarmInfoForUserLocked(userId, null); 2973 } 2974 } 2975 } 2976 updateNextAlarmInfoForUserLocked(int userId, AlarmManager.AlarmClockInfo alarmClock)2977 private void updateNextAlarmInfoForUserLocked(int userId, 2978 AlarmManager.AlarmClockInfo alarmClock) { 2979 if (alarmClock != null) { 2980 if (DEBUG_ALARM_CLOCK) { 2981 Log.v(TAG, "Next AlarmClockInfoForUser(" + userId + "): " + 2982 formatNextAlarm(getContext(), alarmClock, userId)); 2983 } 2984 mNextAlarmClockForUser.put(userId, alarmClock); 2985 } else { 2986 if (DEBUG_ALARM_CLOCK) { 2987 Log.v(TAG, "Next AlarmClockInfoForUser(" + userId + "): None"); 2988 } 2989 mNextAlarmClockForUser.remove(userId); 2990 } 2991 2992 mPendingSendNextAlarmClockChangedForUser.put(userId, true); 2993 mHandler.removeMessages(AlarmHandler.SEND_NEXT_ALARM_CLOCK_CHANGED); 2994 mHandler.sendEmptyMessage(AlarmHandler.SEND_NEXT_ALARM_CLOCK_CHANGED); 2995 } 2996 2997 /** 2998 * Updates NEXT_ALARM_FORMATTED and sends NEXT_ALARM_CLOCK_CHANGED_INTENT for all users 2999 * for which alarm clocks have changed since the last call to this. 3000 * 3001 * Do not call with a lock held. Only call from mHandler's thread. 3002 * 3003 * @see AlarmHandler#SEND_NEXT_ALARM_CLOCK_CHANGED 3004 */ sendNextAlarmClockChanged()3005 private void sendNextAlarmClockChanged() { 3006 SparseArray<AlarmManager.AlarmClockInfo> pendingUsers = mHandlerSparseAlarmClockArray; 3007 pendingUsers.clear(); 3008 3009 synchronized (mLock) { 3010 final int N = mPendingSendNextAlarmClockChangedForUser.size(); 3011 for (int i = 0; i < N; i++) { 3012 int userId = mPendingSendNextAlarmClockChangedForUser.keyAt(i); 3013 pendingUsers.append(userId, mNextAlarmClockForUser.get(userId)); 3014 } 3015 mPendingSendNextAlarmClockChangedForUser.clear(); 3016 } 3017 3018 final int N = pendingUsers.size(); 3019 for (int i = 0; i < N; i++) { 3020 int userId = pendingUsers.keyAt(i); 3021 AlarmManager.AlarmClockInfo alarmClock = pendingUsers.valueAt(i); 3022 Settings.System.putStringForUser(getContext().getContentResolver(), 3023 Settings.System.NEXT_ALARM_FORMATTED, 3024 formatNextAlarm(getContext(), alarmClock, userId), 3025 userId); 3026 3027 getContext().sendBroadcastAsUser(NEXT_ALARM_CLOCK_CHANGED_INTENT, 3028 new UserHandle(userId)); 3029 } 3030 } 3031 3032 /** 3033 * Formats an alarm like platform/packages/apps/DeskClock used to. 3034 */ formatNextAlarm(final Context context, AlarmManager.AlarmClockInfo info, int userId)3035 private static String formatNextAlarm(final Context context, AlarmManager.AlarmClockInfo info, 3036 int userId) { 3037 String skeleton = DateFormat.is24HourFormat(context, userId) ? "EHm" : "Ehma"; 3038 String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton); 3039 return (info == null) ? "" : 3040 DateFormat.format(pattern, info.getTriggerTime()).toString(); 3041 } 3042 rescheduleKernelAlarmsLocked()3043 void rescheduleKernelAlarmsLocked() { 3044 // Schedule the next upcoming wakeup alarm. If there is a deliverable batch 3045 // prior to that which contains no wakeups, we schedule that as well. 3046 final long nowElapsed = mInjector.getElapsedRealtime(); 3047 long nextNonWakeup = 0; 3048 if (mAlarmBatches.size() > 0) { 3049 final Batch firstWakeup = findFirstWakeupBatchLocked(); 3050 final Batch firstBatch = mAlarmBatches.get(0); 3051 if (firstWakeup != null) { 3052 mNextWakeup = firstWakeup.start; 3053 mNextWakeUpSetAt = nowElapsed; 3054 setLocked(ELAPSED_REALTIME_WAKEUP, firstWakeup.start); 3055 } 3056 if (firstBatch != firstWakeup) { 3057 nextNonWakeup = firstBatch.start; 3058 } 3059 } 3060 if (mPendingNonWakeupAlarms.size() > 0) { 3061 if (nextNonWakeup == 0 || mNextNonWakeupDeliveryTime < nextNonWakeup) { 3062 nextNonWakeup = mNextNonWakeupDeliveryTime; 3063 } 3064 } 3065 if (nextNonWakeup != 0) { 3066 mNextNonWakeup = nextNonWakeup; 3067 mNextNonWakeUpSetAt = nowElapsed; 3068 setLocked(ELAPSED_REALTIME, nextNonWakeup); 3069 } 3070 } 3071 removeLocked(PendingIntent operation, IAlarmListener directReceiver)3072 void removeLocked(PendingIntent operation, IAlarmListener directReceiver) { 3073 if (operation == null && directReceiver == null) { 3074 if (localLOGV) { 3075 Slog.w(TAG, "requested remove() of null operation", 3076 new RuntimeException("here")); 3077 } 3078 return; 3079 } 3080 3081 boolean didRemove = false; 3082 final Predicate<Alarm> whichAlarms = (Alarm a) -> a.matches(operation, directReceiver); 3083 for (int i = mAlarmBatches.size() - 1; i >= 0; i--) { 3084 Batch b = mAlarmBatches.get(i); 3085 didRemove |= b.remove(whichAlarms, false); 3086 if (b.size() == 0) { 3087 mAlarmBatches.remove(i); 3088 } 3089 } 3090 for (int i = mPendingWhileIdleAlarms.size() - 1; i >= 0; i--) { 3091 final Alarm alarm = mPendingWhileIdleAlarms.get(i); 3092 if (alarm.matches(operation, directReceiver)) { 3093 // Don't set didRemove, since this doesn't impact the scheduled alarms. 3094 mPendingWhileIdleAlarms.remove(i); 3095 decrementAlarmCount(alarm.uid, 1); 3096 } 3097 } 3098 for (int i = mPendingBackgroundAlarms.size() - 1; i >= 0; i--) { 3099 final ArrayList<Alarm> alarmsForUid = mPendingBackgroundAlarms.valueAt(i); 3100 for (int j = alarmsForUid.size() - 1; j >= 0; j--) { 3101 final Alarm alarm = alarmsForUid.get(j); 3102 if (alarm.matches(operation, directReceiver)) { 3103 // Don't set didRemove, since this doesn't impact the scheduled alarms. 3104 alarmsForUid.remove(j); 3105 decrementAlarmCount(alarm.uid, 1); 3106 } 3107 } 3108 if (alarmsForUid.size() == 0) { 3109 mPendingBackgroundAlarms.removeAt(i); 3110 } 3111 } 3112 if (didRemove) { 3113 if (DEBUG_BATCH) { 3114 Slog.v(TAG, "remove(operation) changed bounds; rebatching"); 3115 } 3116 boolean restorePending = false; 3117 if (mPendingIdleUntil != null && mPendingIdleUntil.matches(operation, directReceiver)) { 3118 mPendingIdleUntil = null; 3119 restorePending = true; 3120 } 3121 if (mNextWakeFromIdle != null && mNextWakeFromIdle.matches(operation, directReceiver)) { 3122 mNextWakeFromIdle = null; 3123 } 3124 rebatchAllAlarmsLocked(true); 3125 if (restorePending) { 3126 restorePendingWhileIdleAlarmsLocked(); 3127 } 3128 updateNextAlarmClockLocked(); 3129 } 3130 } 3131 removeLocked(final int uid)3132 void removeLocked(final int uid) { 3133 if (uid == Process.SYSTEM_UID) { 3134 // If a force-stop occurs for a system-uid package, ignore it. 3135 return; 3136 } 3137 boolean didRemove = false; 3138 final Predicate<Alarm> whichAlarms = (Alarm a) -> a.uid == uid; 3139 for (int i = mAlarmBatches.size() - 1; i >= 0; i--) { 3140 Batch b = mAlarmBatches.get(i); 3141 didRemove |= b.remove(whichAlarms, false); 3142 if (b.size() == 0) { 3143 mAlarmBatches.remove(i); 3144 } 3145 } 3146 for (int i = mPendingWhileIdleAlarms.size() - 1; i >= 0; i--) { 3147 final Alarm a = mPendingWhileIdleAlarms.get(i); 3148 if (a.uid == uid) { 3149 // Don't set didRemove, since this doesn't impact the scheduled alarms. 3150 mPendingWhileIdleAlarms.remove(i); 3151 decrementAlarmCount(uid, 1); 3152 } 3153 } 3154 for (int i = mPendingBackgroundAlarms.size() - 1; i >= 0; i --) { 3155 final ArrayList<Alarm> alarmsForUid = mPendingBackgroundAlarms.valueAt(i); 3156 for (int j = alarmsForUid.size() - 1; j >= 0; j--) { 3157 if (alarmsForUid.get(j).uid == uid) { 3158 alarmsForUid.remove(j); 3159 decrementAlarmCount(uid, 1); 3160 } 3161 } 3162 if (alarmsForUid.size() == 0) { 3163 mPendingBackgroundAlarms.removeAt(i); 3164 } 3165 } 3166 // If we're currently keying off of this app's alarms for doze transitions, 3167 // make sure to reset to other triggers. 3168 if (mNextWakeFromIdle != null && mNextWakeFromIdle.uid == uid) { 3169 mNextWakeFromIdle = null; 3170 } 3171 if (mPendingIdleUntil != null && mPendingIdleUntil.uid == uid) { 3172 // Should never happen - only the system uid is allowed to set idle-until alarms 3173 Slog.wtf(TAG, "Removed app uid " + uid + " set idle-until alarm!"); 3174 mPendingIdleUntil = null; 3175 } 3176 if (didRemove) { 3177 if (DEBUG_BATCH) { 3178 Slog.v(TAG, "remove(uid) changed bounds; rebatching"); 3179 } 3180 rebatchAllAlarmsLocked(true); 3181 rescheduleKernelAlarmsLocked(); 3182 updateNextAlarmClockLocked(); 3183 } 3184 } 3185 removeLocked(final String packageName)3186 void removeLocked(final String packageName) { 3187 if (packageName == null) { 3188 if (localLOGV) { 3189 Slog.w(TAG, "requested remove() of null packageName", 3190 new RuntimeException("here")); 3191 } 3192 return; 3193 } 3194 3195 boolean didRemove = false; 3196 final MutableBoolean removedNextWakeFromIdle = new MutableBoolean(false); 3197 final Predicate<Alarm> whichAlarms = (Alarm a) -> { 3198 final boolean didMatch = a.matches(packageName); 3199 if (didMatch && a == mNextWakeFromIdle) { 3200 removedNextWakeFromIdle.value = true; 3201 } 3202 return didMatch; 3203 }; 3204 final boolean oldHasTick = haveBatchesTimeTickAlarm(mAlarmBatches); 3205 for (int i = mAlarmBatches.size() - 1; i >= 0; i--) { 3206 Batch b = mAlarmBatches.get(i); 3207 didRemove |= b.remove(whichAlarms, false); 3208 if (b.size() == 0) { 3209 mAlarmBatches.remove(i); 3210 } 3211 } 3212 final boolean newHasTick = haveBatchesTimeTickAlarm(mAlarmBatches); 3213 if (oldHasTick != newHasTick) { 3214 Slog.wtf(TAG, "removeLocked: hasTick changed from " + oldHasTick + " to " + newHasTick); 3215 } 3216 3217 for (int i = mPendingWhileIdleAlarms.size() - 1; i >= 0; i--) { 3218 final Alarm a = mPendingWhileIdleAlarms.get(i); 3219 if (a.matches(packageName)) { 3220 // Don't set didRemove, since this doesn't impact the scheduled alarms. 3221 mPendingWhileIdleAlarms.remove(i); 3222 decrementAlarmCount(a.uid, 1); 3223 } 3224 } 3225 for (int i = mPendingBackgroundAlarms.size() - 1; i >= 0; i --) { 3226 final ArrayList<Alarm> alarmsForUid = mPendingBackgroundAlarms.valueAt(i); 3227 for (int j = alarmsForUid.size() - 1; j >= 0; j--) { 3228 final Alarm alarm = alarmsForUid.get(j); 3229 if (alarm.matches(packageName)) { 3230 alarmsForUid.remove(j); 3231 decrementAlarmCount(alarm.uid, 1); 3232 } 3233 } 3234 if (alarmsForUid.size() == 0) { 3235 mPendingBackgroundAlarms.removeAt(i); 3236 } 3237 } 3238 // If we're currently keying off of this app's alarms for doze transitions, 3239 // make sure to reset to other triggers. 3240 if (removedNextWakeFromIdle.value) { 3241 mNextWakeFromIdle = null; 3242 } 3243 if (didRemove) { 3244 if (DEBUG_BATCH) { 3245 Slog.v(TAG, "remove(package) changed bounds; rebatching"); 3246 } 3247 rebatchAllAlarmsLocked(true); 3248 rescheduleKernelAlarmsLocked(); 3249 updateNextAlarmClockLocked(); 3250 } 3251 } 3252 3253 // Only called for ephemeral apps removeForStoppedLocked(final int uid)3254 void removeForStoppedLocked(final int uid) { 3255 if (uid == Process.SYSTEM_UID) { 3256 // If a force-stop occurs for a system-uid package, ignore it. 3257 return; 3258 } 3259 boolean didRemove = false; 3260 final Predicate<Alarm> whichAlarms = (Alarm a) -> { 3261 try { 3262 if (a.uid == uid && ActivityManager.getService().isAppStartModeDisabled( 3263 uid, a.packageName)) { 3264 return true; 3265 } 3266 } catch (RemoteException e) { /* fall through */} 3267 return false; 3268 }; 3269 for (int i = mAlarmBatches.size() - 1; i >= 0; i--) { 3270 Batch b = mAlarmBatches.get(i); 3271 didRemove |= b.remove(whichAlarms, false); 3272 if (b.size() == 0) { 3273 mAlarmBatches.remove(i); 3274 } 3275 } 3276 for (int i = mPendingWhileIdleAlarms.size() - 1; i >= 0; i--) { 3277 final Alarm a = mPendingWhileIdleAlarms.get(i); 3278 if (a.uid == uid) { 3279 // Don't set didRemove, since this doesn't impact the scheduled alarms. 3280 mPendingWhileIdleAlarms.remove(i); 3281 decrementAlarmCount(uid, 1); 3282 } 3283 } 3284 for (int i = mPendingBackgroundAlarms.size() - 1; i >= 0; i--) { 3285 if (mPendingBackgroundAlarms.keyAt(i) == uid) { 3286 final ArrayList<Alarm> toRemove = mPendingBackgroundAlarms.valueAt(i); 3287 if (toRemove != null) { 3288 decrementAlarmCount(uid, toRemove.size()); 3289 } 3290 mPendingBackgroundAlarms.removeAt(i); 3291 } 3292 } 3293 if (didRemove) { 3294 if (DEBUG_BATCH) { 3295 Slog.v(TAG, "remove(package) changed bounds; rebatching"); 3296 } 3297 rebatchAllAlarmsLocked(true); 3298 rescheduleKernelAlarmsLocked(); 3299 updateNextAlarmClockLocked(); 3300 } 3301 } 3302 removeUserLocked(int userHandle)3303 void removeUserLocked(int userHandle) { 3304 if (userHandle == USER_SYSTEM) { 3305 // If we're told we're removing the system user, ignore it. 3306 return; 3307 } 3308 boolean didRemove = false; 3309 final Predicate<Alarm> whichAlarms = 3310 (Alarm a) -> UserHandle.getUserId(a.creatorUid) == userHandle; 3311 for (int i = mAlarmBatches.size() - 1; i >= 0; i--) { 3312 Batch b = mAlarmBatches.get(i); 3313 didRemove |= b.remove(whichAlarms, false); 3314 if (b.size() == 0) { 3315 mAlarmBatches.remove(i); 3316 } 3317 } 3318 for (int i = mPendingWhileIdleAlarms.size() - 1; i >= 0; i--) { 3319 if (UserHandle.getUserId(mPendingWhileIdleAlarms.get(i).creatorUid) 3320 == userHandle) { 3321 // Don't set didRemove, since this doesn't impact the scheduled alarms. 3322 final Alarm removed = mPendingWhileIdleAlarms.remove(i); 3323 decrementAlarmCount(removed.uid, 1); 3324 } 3325 } 3326 for (int i = mPendingBackgroundAlarms.size() - 1; i >= 0; i--) { 3327 if (UserHandle.getUserId(mPendingBackgroundAlarms.keyAt(i)) == userHandle) { 3328 final ArrayList<Alarm> toRemove = mPendingBackgroundAlarms.valueAt(i); 3329 if (toRemove != null) { 3330 for (int j = 0; j < toRemove.size(); j++) { 3331 decrementAlarmCount(toRemove.get(j).uid, 1); 3332 } 3333 } 3334 mPendingBackgroundAlarms.removeAt(i); 3335 } 3336 } 3337 for (int i = mLastAllowWhileIdleDispatch.size() - 1; i >= 0; i--) { 3338 if (UserHandle.getUserId(mLastAllowWhileIdleDispatch.keyAt(i)) == userHandle) { 3339 mLastAllowWhileIdleDispatch.removeAt(i); 3340 } 3341 } 3342 3343 if (didRemove) { 3344 if (DEBUG_BATCH) { 3345 Slog.v(TAG, "remove(user) changed bounds; rebatching"); 3346 } 3347 rebatchAllAlarmsLocked(true); 3348 rescheduleKernelAlarmsLocked(); 3349 updateNextAlarmClockLocked(); 3350 } 3351 } 3352 interactiveStateChangedLocked(boolean interactive)3353 void interactiveStateChangedLocked(boolean interactive) { 3354 if (mInteractive != interactive) { 3355 mInteractive = interactive; 3356 final long nowELAPSED = mInjector.getElapsedRealtime(); 3357 if (interactive) { 3358 if (mPendingNonWakeupAlarms.size() > 0) { 3359 final long thisDelayTime = nowELAPSED - mStartCurrentDelayTime; 3360 mTotalDelayTime += thisDelayTime; 3361 if (mMaxDelayTime < thisDelayTime) { 3362 mMaxDelayTime = thisDelayTime; 3363 } 3364 deliverAlarmsLocked(mPendingNonWakeupAlarms, nowELAPSED); 3365 mPendingNonWakeupAlarms.clear(); 3366 } 3367 if (mNonInteractiveStartTime > 0) { 3368 long dur = nowELAPSED - mNonInteractiveStartTime; 3369 if (dur > mNonInteractiveTime) { 3370 mNonInteractiveTime = dur; 3371 } 3372 } 3373 // And send a TIME_TICK right now, since it is important to get the UI updated. 3374 mHandler.post(() -> 3375 getContext().sendBroadcastAsUser(mTimeTickIntent, UserHandle.ALL)); 3376 } else { 3377 mNonInteractiveStartTime = nowELAPSED; 3378 } 3379 } 3380 } 3381 lookForPackageLocked(String packageName)3382 boolean lookForPackageLocked(String packageName) { 3383 for (int i = 0; i < mAlarmBatches.size(); i++) { 3384 Batch b = mAlarmBatches.get(i); 3385 if (b.hasPackage(packageName)) { 3386 return true; 3387 } 3388 } 3389 for (int i = 0; i < mPendingWhileIdleAlarms.size(); i++) { 3390 final Alarm a = mPendingWhileIdleAlarms.get(i); 3391 if (a.matches(packageName)) { 3392 return true; 3393 } 3394 } 3395 return false; 3396 } 3397 setLocked(int type, long when)3398 private void setLocked(int type, long when) { 3399 if (mInjector.isAlarmDriverPresent()) { 3400 mInjector.setAlarm(type, when); 3401 } else { 3402 Message msg = Message.obtain(); 3403 msg.what = AlarmHandler.ALARM_EVENT; 3404 3405 mHandler.removeMessages(msg.what); 3406 mHandler.sendMessageAtTime(msg, when); 3407 } 3408 } 3409 dumpAlarmList(PrintWriter pw, ArrayList<Alarm> list, String prefix, String label, long nowELAPSED, long nowRTC, SimpleDateFormat sdf)3410 private static final void dumpAlarmList(PrintWriter pw, ArrayList<Alarm> list, 3411 String prefix, String label, long nowELAPSED, long nowRTC, SimpleDateFormat sdf) { 3412 for (int i=list.size()-1; i>=0; i--) { 3413 Alarm a = list.get(i); 3414 pw.print(prefix); pw.print(label); pw.print(" #"); pw.print(i); 3415 pw.print(": "); pw.println(a); 3416 a.dump(pw, prefix + " ", nowELAPSED, nowRTC, sdf); 3417 } 3418 } 3419 labelForType(int type)3420 private static final String labelForType(int type) { 3421 switch (type) { 3422 case RTC: return "RTC"; 3423 case RTC_WAKEUP : return "RTC_WAKEUP"; 3424 case ELAPSED_REALTIME : return "ELAPSED"; 3425 case ELAPSED_REALTIME_WAKEUP: return "ELAPSED_WAKEUP"; 3426 } 3427 return "--unknown--"; 3428 } 3429 dumpAlarmList(PrintWriter pw, ArrayList<Alarm> list, String prefix, long nowELAPSED, long nowRTC, SimpleDateFormat sdf)3430 private static final void dumpAlarmList(PrintWriter pw, ArrayList<Alarm> list, 3431 String prefix, long nowELAPSED, long nowRTC, SimpleDateFormat sdf) { 3432 for (int i=list.size()-1; i>=0; i--) { 3433 Alarm a = list.get(i); 3434 final String label = labelForType(a.type); 3435 pw.print(prefix); pw.print(label); pw.print(" #"); pw.print(i); 3436 pw.print(": "); pw.println(a); 3437 a.dump(pw, prefix + " ", nowELAPSED, nowRTC, sdf); 3438 } 3439 } 3440 isBackgroundRestricted(Alarm alarm)3441 private boolean isBackgroundRestricted(Alarm alarm) { 3442 boolean exemptOnBatterySaver = (alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0; 3443 if (alarm.alarmClock != null) { 3444 // Don't defer alarm clocks 3445 return false; 3446 } 3447 if (alarm.operation != null) { 3448 if (alarm.operation.isActivity()) { 3449 // Don't defer starting actual UI 3450 return false; 3451 } 3452 if (alarm.operation.isForegroundService()) { 3453 // FG service alarms are nearly as important; consult AST policy 3454 exemptOnBatterySaver = true; 3455 } 3456 } 3457 final String sourcePackage = alarm.sourcePackage; 3458 final int sourceUid = alarm.creatorUid; 3459 return (mAppStateTracker != null) && 3460 mAppStateTracker.areAlarmsRestricted(sourceUid, sourcePackage, 3461 exemptOnBatterySaver); 3462 } 3463 init()3464 private static native long init(); close(long nativeData)3465 private static native void close(long nativeData); set(long nativeData, int type, long seconds, long nanoseconds)3466 private static native int set(long nativeData, int type, long seconds, long nanoseconds); waitForAlarm(long nativeData)3467 private static native int waitForAlarm(long nativeData); setKernelTime(long nativeData, long millis)3468 private static native int setKernelTime(long nativeData, long millis); setKernelTimezone(long nativeData, int minuteswest)3469 private static native int setKernelTimezone(long nativeData, int minuteswest); getNextAlarm(long nativeData, int type)3470 private static native long getNextAlarm(long nativeData, int type); 3471 getWhileIdleMinIntervalLocked(int uid)3472 private long getWhileIdleMinIntervalLocked(int uid) { 3473 final boolean dozing = mPendingIdleUntil != null; 3474 final boolean ebs = (mAppStateTracker != null) 3475 && mAppStateTracker.isForceAllAppsStandbyEnabled(); 3476 if (!dozing && !ebs) { 3477 return mConstants.ALLOW_WHILE_IDLE_SHORT_TIME; 3478 } 3479 if (dozing) { 3480 return mConstants.ALLOW_WHILE_IDLE_LONG_TIME; 3481 } 3482 if (mUseAllowWhileIdleShortTime.get(uid)) { 3483 // if the last allow-while-idle went off while uid was fg, or the uid 3484 // recently came into fg, don't block the alarm for long. 3485 return mConstants.ALLOW_WHILE_IDLE_SHORT_TIME; 3486 } 3487 return mConstants.ALLOW_WHILE_IDLE_LONG_TIME; 3488 } 3489 triggerAlarmsLocked(ArrayList<Alarm> triggerList, final long nowELAPSED)3490 boolean triggerAlarmsLocked(ArrayList<Alarm> triggerList, final long nowELAPSED) { 3491 boolean hasWakeup = false; 3492 // batches are temporally sorted, so we need only pull from the 3493 // start of the list until we either empty it or hit a batch 3494 // that is not yet deliverable 3495 while (mAlarmBatches.size() > 0) { 3496 Batch batch = mAlarmBatches.get(0); 3497 if (batch.start > nowELAPSED) { 3498 // Everything else is scheduled for the future 3499 break; 3500 } 3501 3502 // We will (re)schedule some alarms now; don't let that interfere 3503 // with delivery of this current batch 3504 mAlarmBatches.remove(0); 3505 3506 final int N = batch.size(); 3507 for (int i = 0; i < N; i++) { 3508 Alarm alarm = batch.get(i); 3509 3510 if ((alarm.flags&AlarmManager.FLAG_ALLOW_WHILE_IDLE) != 0) { 3511 // If this is an ALLOW_WHILE_IDLE alarm, we constrain how frequently the app can 3512 // schedule such alarms. The first such alarm from an app is always delivered. 3513 final long lastTime = mLastAllowWhileIdleDispatch.get(alarm.creatorUid, -1); 3514 final long minTime = lastTime + getWhileIdleMinIntervalLocked(alarm.creatorUid); 3515 if (lastTime >= 0 && nowELAPSED < minTime) { 3516 // Whoops, it hasn't been long enough since the last ALLOW_WHILE_IDLE 3517 // alarm went off for this app. Reschedule the alarm to be in the 3518 // correct time period. 3519 alarm.expectedWhenElapsed = alarm.whenElapsed = minTime; 3520 if (alarm.maxWhenElapsed < minTime) { 3521 alarm.maxWhenElapsed = minTime; 3522 } 3523 alarm.expectedMaxWhenElapsed = alarm.maxWhenElapsed; 3524 if (RECORD_DEVICE_IDLE_ALARMS) { 3525 IdleDispatchEntry ent = new IdleDispatchEntry(); 3526 ent.uid = alarm.uid; 3527 ent.pkg = alarm.operation.getCreatorPackage(); 3528 ent.tag = alarm.operation.getTag(""); 3529 ent.op = "RESCHEDULE"; 3530 ent.elapsedRealtime = nowELAPSED; 3531 ent.argRealtime = lastTime; 3532 mAllowWhileIdleDispatches.add(ent); 3533 } 3534 setImplLocked(alarm, true, false); 3535 continue; 3536 } 3537 } 3538 if (isBackgroundRestricted(alarm)) { 3539 // Alarms with FLAG_WAKE_FROM_IDLE or mPendingIdleUntil alarm are not deferred 3540 if (DEBUG_BG_LIMIT) { 3541 Slog.d(TAG, "Deferring alarm " + alarm + " due to user forced app standby"); 3542 } 3543 ArrayList<Alarm> alarmsForUid = mPendingBackgroundAlarms.get(alarm.creatorUid); 3544 if (alarmsForUid == null) { 3545 alarmsForUid = new ArrayList<>(); 3546 mPendingBackgroundAlarms.put(alarm.creatorUid, alarmsForUid); 3547 } 3548 alarmsForUid.add(alarm); 3549 continue; 3550 } 3551 3552 alarm.count = 1; 3553 triggerList.add(alarm); 3554 if ((alarm.flags&AlarmManager.FLAG_WAKE_FROM_IDLE) != 0) { 3555 EventLogTags.writeDeviceIdleWakeFromIdle(mPendingIdleUntil != null ? 1 : 0, 3556 alarm.statsTag); 3557 } 3558 if (mPendingIdleUntil == alarm) { 3559 mPendingIdleUntil = null; 3560 rebatchAllAlarmsLocked(false); 3561 restorePendingWhileIdleAlarmsLocked(); 3562 } 3563 if (mNextWakeFromIdle == alarm) { 3564 mNextWakeFromIdle = null; 3565 rebatchAllAlarmsLocked(false); 3566 } 3567 3568 // Recurring alarms may have passed several alarm intervals while the 3569 // phone was asleep or off, so pass a trigger count when sending them. 3570 if (alarm.repeatInterval > 0) { 3571 // this adjustment will be zero if we're late by 3572 // less than one full repeat interval 3573 alarm.count += (nowELAPSED - alarm.expectedWhenElapsed) / alarm.repeatInterval; 3574 // Also schedule its next recurrence 3575 final long delta = alarm.count * alarm.repeatInterval; 3576 final long nextElapsed = alarm.expectedWhenElapsed + delta; 3577 setImplLocked(alarm.type, alarm.when + delta, nextElapsed, alarm.windowLength, 3578 maxTriggerTime(nowELAPSED, nextElapsed, alarm.repeatInterval), 3579 alarm.repeatInterval, alarm.operation, null, null, alarm.flags, true, 3580 alarm.workSource, alarm.alarmClock, alarm.uid, alarm.packageName); 3581 } 3582 3583 if (alarm.wakeup) { 3584 hasWakeup = true; 3585 } 3586 3587 // We removed an alarm clock. Let the caller recompute the next alarm clock. 3588 if (alarm.alarmClock != null) { 3589 mNextAlarmClockMayChange = true; 3590 } 3591 } 3592 } 3593 3594 // This is a new alarm delivery set; bump the sequence number to indicate that 3595 // all apps' alarm delivery classes should be recalculated. 3596 mCurrentSeq++; 3597 calculateDeliveryPriorities(triggerList); 3598 Collections.sort(triggerList, mAlarmDispatchComparator); 3599 3600 if (localLOGV) { 3601 for (int i=0; i<triggerList.size(); i++) { 3602 Slog.v(TAG, "Triggering alarm #" + i + ": " + triggerList.get(i)); 3603 } 3604 } 3605 3606 return hasWakeup; 3607 } 3608 3609 /** 3610 * This Comparator sorts Alarms into increasing time order. 3611 */ 3612 public static class IncreasingTimeOrder implements Comparator<Alarm> { compare(Alarm a1, Alarm a2)3613 public int compare(Alarm a1, Alarm a2) { 3614 long when1 = a1.whenElapsed; 3615 long when2 = a2.whenElapsed; 3616 if (when1 > when2) { 3617 return 1; 3618 } 3619 if (when1 < when2) { 3620 return -1; 3621 } 3622 return 0; 3623 } 3624 } 3625 3626 @VisibleForTesting 3627 static class Alarm { 3628 public final int type; 3629 public final long origWhen; 3630 public final boolean wakeup; 3631 public final PendingIntent operation; 3632 public final IAlarmListener listener; 3633 public final String listenerTag; 3634 public final String statsTag; 3635 public final WorkSource workSource; 3636 public final int flags; 3637 public final AlarmManager.AlarmClockInfo alarmClock; 3638 public final int uid; 3639 public final int creatorUid; 3640 public final String packageName; 3641 public final String sourcePackage; 3642 public int count; 3643 public long when; 3644 public long windowLength; 3645 public long whenElapsed; // 'when' in the elapsed time base 3646 public long maxWhenElapsed; // also in the elapsed time base 3647 // Expected alarm expiry time before app standby deferring is applied. 3648 public long expectedWhenElapsed; 3649 public long expectedMaxWhenElapsed; 3650 public long repeatInterval; 3651 public PriorityClass priorityClass; 3652 Alarm(int _type, long _when, long _whenElapsed, long _windowLength, long _maxWhen, long _interval, PendingIntent _op, IAlarmListener _rec, String _listenerTag, WorkSource _ws, int _flags, AlarmManager.AlarmClockInfo _info, int _uid, String _pkgName)3653 public Alarm(int _type, long _when, long _whenElapsed, long _windowLength, long _maxWhen, 3654 long _interval, PendingIntent _op, IAlarmListener _rec, String _listenerTag, 3655 WorkSource _ws, int _flags, AlarmManager.AlarmClockInfo _info, 3656 int _uid, String _pkgName) { 3657 type = _type; 3658 origWhen = _when; 3659 wakeup = _type == AlarmManager.ELAPSED_REALTIME_WAKEUP 3660 || _type == AlarmManager.RTC_WAKEUP; 3661 when = _when; 3662 whenElapsed = _whenElapsed; 3663 expectedWhenElapsed = _whenElapsed; 3664 windowLength = _windowLength; 3665 maxWhenElapsed = expectedMaxWhenElapsed = clampPositive(_maxWhen); 3666 repeatInterval = _interval; 3667 operation = _op; 3668 listener = _rec; 3669 listenerTag = _listenerTag; 3670 statsTag = makeTag(_op, _listenerTag, _type); 3671 workSource = _ws; 3672 flags = _flags; 3673 alarmClock = _info; 3674 uid = _uid; 3675 packageName = _pkgName; 3676 sourcePackage = (operation != null) ? operation.getCreatorPackage() : packageName; 3677 creatorUid = (operation != null) ? operation.getCreatorUid() : uid; 3678 } 3679 makeTag(PendingIntent pi, String tag, int type)3680 public static String makeTag(PendingIntent pi, String tag, int type) { 3681 final String alarmString = type == ELAPSED_REALTIME_WAKEUP || type == RTC_WAKEUP 3682 ? "*walarm*:" : "*alarm*:"; 3683 return (pi != null) ? pi.getTag(alarmString) : (alarmString + tag); 3684 } 3685 makeWakeupEvent(long nowRTC)3686 public WakeupEvent makeWakeupEvent(long nowRTC) { 3687 return new WakeupEvent(nowRTC, creatorUid, 3688 (operation != null) 3689 ? operation.getIntent().getAction() 3690 : ("<listener>:" + listenerTag)); 3691 } 3692 3693 // Returns true if either matches matches(PendingIntent pi, IAlarmListener rec)3694 public boolean matches(PendingIntent pi, IAlarmListener rec) { 3695 return (operation != null) 3696 ? operation.equals(pi) 3697 : rec != null && listener.asBinder().equals(rec.asBinder()); 3698 } 3699 matches(String packageName)3700 public boolean matches(String packageName) { 3701 return packageName.equals(sourcePackage); 3702 } 3703 3704 @Override toString()3705 public String toString() { 3706 StringBuilder sb = new StringBuilder(128); 3707 sb.append("Alarm{"); 3708 sb.append(Integer.toHexString(System.identityHashCode(this))); 3709 sb.append(" type "); 3710 sb.append(type); 3711 sb.append(" when "); 3712 sb.append(when); 3713 sb.append(" "); 3714 sb.append(sourcePackage); 3715 sb.append('}'); 3716 return sb.toString(); 3717 } 3718 dump(PrintWriter pw, String prefix, long nowELAPSED, long nowRTC, SimpleDateFormat sdf)3719 public void dump(PrintWriter pw, String prefix, long nowELAPSED, long nowRTC, 3720 SimpleDateFormat sdf) { 3721 final boolean isRtc = (type == RTC || type == RTC_WAKEUP); 3722 pw.print(prefix); pw.print("tag="); pw.println(statsTag); 3723 pw.print(prefix); pw.print("type="); pw.print(type); 3724 pw.print(" expectedWhenElapsed="); TimeUtils.formatDuration( 3725 expectedWhenElapsed, nowELAPSED, pw); 3726 pw.print(" expectedMaxWhenElapsed="); TimeUtils.formatDuration( 3727 expectedMaxWhenElapsed, nowELAPSED, pw); 3728 pw.print(" whenElapsed="); TimeUtils.formatDuration(whenElapsed, 3729 nowELAPSED, pw); 3730 pw.print(" maxWhenElapsed="); TimeUtils.formatDuration(maxWhenElapsed, 3731 nowELAPSED, pw); 3732 pw.print(" when="); 3733 if (isRtc) { 3734 pw.print(sdf.format(new Date(when))); 3735 } else { 3736 TimeUtils.formatDuration(when, nowELAPSED, pw); 3737 } 3738 pw.println(); 3739 pw.print(prefix); pw.print("window="); TimeUtils.formatDuration(windowLength, pw); 3740 pw.print(" repeatInterval="); pw.print(repeatInterval); 3741 pw.print(" count="); pw.print(count); 3742 pw.print(" flags=0x"); pw.println(Integer.toHexString(flags)); 3743 if (alarmClock != null) { 3744 pw.print(prefix); pw.println("Alarm clock:"); 3745 pw.print(prefix); pw.print(" triggerTime="); 3746 pw.println(sdf.format(new Date(alarmClock.getTriggerTime()))); 3747 pw.print(prefix); pw.print(" showIntent="); pw.println(alarmClock.getShowIntent()); 3748 } 3749 pw.print(prefix); pw.print("operation="); pw.println(operation); 3750 if (listener != null) { 3751 pw.print(prefix); pw.print("listener="); pw.println(listener.asBinder()); 3752 } 3753 } 3754 dumpDebug(ProtoOutputStream proto, long fieldId, long nowElapsed, long nowRTC)3755 public void dumpDebug(ProtoOutputStream proto, long fieldId, long nowElapsed, 3756 long nowRTC) { 3757 final long token = proto.start(fieldId); 3758 3759 proto.write(AlarmProto.TAG, statsTag); 3760 proto.write(AlarmProto.TYPE, type); 3761 proto.write(AlarmProto.TIME_UNTIL_WHEN_ELAPSED_MS, whenElapsed - nowElapsed); 3762 proto.write(AlarmProto.WINDOW_LENGTH_MS, windowLength); 3763 proto.write(AlarmProto.REPEAT_INTERVAL_MS, repeatInterval); 3764 proto.write(AlarmProto.COUNT, count); 3765 proto.write(AlarmProto.FLAGS, flags); 3766 if (alarmClock != null) { 3767 alarmClock.dumpDebug(proto, AlarmProto.ALARM_CLOCK); 3768 } 3769 if (operation != null) { 3770 operation.dumpDebug(proto, AlarmProto.OPERATION); 3771 } 3772 if (listener != null) { 3773 proto.write(AlarmProto.LISTENER, listener.asBinder().toString()); 3774 } 3775 3776 proto.end(token); 3777 } 3778 } 3779 recordWakeupAlarms(ArrayList<Batch> batches, long nowELAPSED, long nowRTC)3780 void recordWakeupAlarms(ArrayList<Batch> batches, long nowELAPSED, long nowRTC) { 3781 final int numBatches = batches.size(); 3782 for (int nextBatch = 0; nextBatch < numBatches; nextBatch++) { 3783 Batch b = batches.get(nextBatch); 3784 if (b.start > nowELAPSED) { 3785 break; 3786 } 3787 3788 final int numAlarms = b.alarms.size(); 3789 for (int nextAlarm = 0; nextAlarm < numAlarms; nextAlarm++) { 3790 Alarm a = b.alarms.get(nextAlarm); 3791 mRecentWakeups.add(a.makeWakeupEvent(nowRTC)); 3792 } 3793 } 3794 } 3795 currentNonWakeupFuzzLocked(long nowELAPSED)3796 long currentNonWakeupFuzzLocked(long nowELAPSED) { 3797 long timeSinceOn = nowELAPSED - mNonInteractiveStartTime; 3798 if (timeSinceOn < 5*60*1000) { 3799 // If the screen has been off for 5 minutes, only delay by at most two minutes. 3800 return 2*60*1000; 3801 } else if (timeSinceOn < 30*60*1000) { 3802 // If the screen has been off for 30 minutes, only delay by at most 15 minutes. 3803 return 15*60*1000; 3804 } else { 3805 // Otherwise, we will delay by at most an hour. 3806 return 60*60*1000; 3807 } 3808 } 3809 fuzzForDuration(long duration)3810 static int fuzzForDuration(long duration) { 3811 if (duration < 15*60*1000) { 3812 // If the duration until the time is less than 15 minutes, the maximum fuzz 3813 // is the duration. 3814 return (int)duration; 3815 } else if (duration < 90*60*1000) { 3816 // If duration is less than 1 1/2 hours, the maximum fuzz is 15 minutes, 3817 return 15*60*1000; 3818 } else { 3819 // Otherwise, we will fuzz by at most half an hour. 3820 return 30*60*1000; 3821 } 3822 } 3823 checkAllowNonWakeupDelayLocked(long nowELAPSED)3824 boolean checkAllowNonWakeupDelayLocked(long nowELAPSED) { 3825 if (mInteractive) { 3826 return false; 3827 } 3828 if (mLastAlarmDeliveryTime <= 0) { 3829 return false; 3830 } 3831 if (mPendingNonWakeupAlarms.size() > 0 && mNextNonWakeupDeliveryTime < nowELAPSED) { 3832 // This is just a little paranoia, if somehow we have pending non-wakeup alarms 3833 // and the next delivery time is in the past, then just deliver them all. This 3834 // avoids bugs where we get stuck in a loop trying to poll for alarms. 3835 return false; 3836 } 3837 long timeSinceLast = nowELAPSED - mLastAlarmDeliveryTime; 3838 return timeSinceLast <= currentNonWakeupFuzzLocked(nowELAPSED); 3839 } 3840 deliverAlarmsLocked(ArrayList<Alarm> triggerList, long nowELAPSED)3841 void deliverAlarmsLocked(ArrayList<Alarm> triggerList, long nowELAPSED) { 3842 mLastAlarmDeliveryTime = nowELAPSED; 3843 for (int i=0; i<triggerList.size(); i++) { 3844 Alarm alarm = triggerList.get(i); 3845 final boolean allowWhileIdle = (alarm.flags&AlarmManager.FLAG_ALLOW_WHILE_IDLE) != 0; 3846 if (alarm.wakeup) { 3847 Trace.traceBegin(Trace.TRACE_TAG_POWER, "Dispatch wakeup alarm to " + alarm.packageName); 3848 } else { 3849 Trace.traceBegin(Trace.TRACE_TAG_POWER, "Dispatch non-wakeup alarm to " + alarm.packageName); 3850 } 3851 try { 3852 if (localLOGV) { 3853 Slog.v(TAG, "sending alarm " + alarm); 3854 } 3855 if (RECORD_ALARMS_IN_HISTORY) { 3856 ActivityManager.noteAlarmStart(alarm.operation, alarm.workSource, alarm.uid, 3857 alarm.statsTag); 3858 } 3859 mDeliveryTracker.deliverLocked(alarm, nowELAPSED, allowWhileIdle); 3860 } catch (RuntimeException e) { 3861 Slog.w(TAG, "Failure sending alarm.", e); 3862 } 3863 Trace.traceEnd(Trace.TRACE_TAG_POWER); 3864 decrementAlarmCount(alarm.uid, 1); 3865 } 3866 } 3867 isExemptFromAppStandby(Alarm a)3868 private boolean isExemptFromAppStandby(Alarm a) { 3869 return a.alarmClock != null || UserHandle.isCore(a.creatorUid) 3870 || (a.flags & FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED) != 0; 3871 } 3872 3873 @VisibleForTesting 3874 static class Injector { 3875 private long mNativeData; 3876 private Context mContext; 3877 Injector(Context context)3878 Injector(Context context) { 3879 mContext = context; 3880 } 3881 init()3882 void init() { 3883 mNativeData = AlarmManagerService.init(); 3884 } 3885 waitForAlarm()3886 int waitForAlarm() { 3887 return AlarmManagerService.waitForAlarm(mNativeData); 3888 } 3889 isAlarmDriverPresent()3890 boolean isAlarmDriverPresent() { 3891 return mNativeData != 0; 3892 } 3893 setAlarm(int type, long millis)3894 void setAlarm(int type, long millis) { 3895 // The kernel never triggers alarms with negative wakeup times 3896 // so we ensure they are positive. 3897 final long alarmSeconds, alarmNanoseconds; 3898 if (millis < 0) { 3899 alarmSeconds = 0; 3900 alarmNanoseconds = 0; 3901 } else { 3902 alarmSeconds = millis / 1000; 3903 alarmNanoseconds = (millis % 1000) * 1000 * 1000; 3904 } 3905 3906 final int result = AlarmManagerService.set(mNativeData, type, alarmSeconds, 3907 alarmNanoseconds); 3908 if (result != 0) { 3909 final long nowElapsed = SystemClock.elapsedRealtime(); 3910 Slog.wtf(TAG, "Unable to set kernel alarm, now=" + nowElapsed 3911 + " type=" + type + " @ (" + alarmSeconds + "," + alarmNanoseconds 3912 + "), ret = " + result + " = " + Os.strerror(result)); 3913 } 3914 } 3915 getNextAlarm(int type)3916 long getNextAlarm(int type) { 3917 return AlarmManagerService.getNextAlarm(mNativeData, type); 3918 } 3919 setKernelTimezone(int minutesWest)3920 void setKernelTimezone(int minutesWest) { 3921 AlarmManagerService.setKernelTimezone(mNativeData, minutesWest); 3922 } 3923 setKernelTime(long millis)3924 void setKernelTime(long millis) { 3925 if (mNativeData != 0) { 3926 AlarmManagerService.setKernelTime(mNativeData, millis); 3927 } 3928 } 3929 close()3930 void close() { 3931 AlarmManagerService.close(mNativeData); 3932 } 3933 getElapsedRealtime()3934 long getElapsedRealtime() { 3935 return SystemClock.elapsedRealtime(); 3936 } 3937 getCurrentTimeMillis()3938 long getCurrentTimeMillis() { 3939 return System.currentTimeMillis(); 3940 } 3941 getAlarmWakeLock()3942 PowerManager.WakeLock getAlarmWakeLock() { 3943 final PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 3944 return pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*alarm*"); 3945 } 3946 getSystemUiUid()3947 int getSystemUiUid() { 3948 PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class); 3949 return pm.getPackageUid(pm.getSystemUiServiceComponent().getPackageName(), 3950 MATCH_SYSTEM_ONLY, USER_SYSTEM); 3951 } 3952 getClockReceiver(AlarmManagerService service)3953 ClockReceiver getClockReceiver(AlarmManagerService service) { 3954 return service.new ClockReceiver(); 3955 } 3956 } 3957 3958 private class AlarmThread extends Thread 3959 { 3960 private int mFalseWakeups; 3961 private int mWtfThreshold; AlarmThread()3962 public AlarmThread() 3963 { 3964 super("AlarmManager"); 3965 mFalseWakeups = 0; 3966 mWtfThreshold = 100; 3967 } 3968 run()3969 public void run() 3970 { 3971 ArrayList<Alarm> triggerList = new ArrayList<Alarm>(); 3972 3973 while (true) 3974 { 3975 int result = mInjector.waitForAlarm(); 3976 final long nowRTC = mInjector.getCurrentTimeMillis(); 3977 final long nowELAPSED = mInjector.getElapsedRealtime(); 3978 synchronized (mLock) { 3979 mLastWakeup = nowELAPSED; 3980 } 3981 if (result == 0) { 3982 Slog.wtf(TAG, "waitForAlarm returned 0, nowRTC = " + nowRTC 3983 + ", nowElapsed = " + nowELAPSED); 3984 } 3985 triggerList.clear(); 3986 3987 if ((result & TIME_CHANGED_MASK) != 0) { 3988 // The kernel can give us spurious time change notifications due to 3989 // small adjustments it makes internally; we want to filter those out. 3990 final long lastTimeChangeClockTime; 3991 final long expectedClockTime; 3992 synchronized (mLock) { 3993 lastTimeChangeClockTime = mLastTimeChangeClockTime; 3994 expectedClockTime = lastTimeChangeClockTime 3995 + (nowELAPSED - mLastTimeChangeRealtime); 3996 } 3997 if (lastTimeChangeClockTime == 0 || nowRTC < (expectedClockTime-1000) 3998 || nowRTC > (expectedClockTime+1000)) { 3999 // The change is by at least +/- 1000 ms (or this is the first change), 4000 // let's do it! 4001 if (DEBUG_BATCH) { 4002 Slog.v(TAG, "Time changed notification from kernel; rebatching"); 4003 } 4004 // StatsLog requires currentTimeMillis(), which == nowRTC to within usecs. 4005 FrameworkStatsLog.write(FrameworkStatsLog.WALL_CLOCK_TIME_SHIFTED, nowRTC); 4006 removeImpl(null, mTimeTickTrigger); 4007 removeImpl(mDateChangeSender, null); 4008 rebatchAllAlarms(); 4009 mClockReceiver.scheduleTimeTickEvent(); 4010 mClockReceiver.scheduleDateChangedEvent(); 4011 synchronized (mLock) { 4012 mNumTimeChanged++; 4013 mLastTimeChangeClockTime = nowRTC; 4014 mLastTimeChangeRealtime = nowELAPSED; 4015 } 4016 Intent intent = new Intent(Intent.ACTION_TIME_CHANGED); 4017 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING 4018 | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT 4019 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND 4020 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); 4021 getContext().sendBroadcastAsUser(intent, UserHandle.ALL); 4022 4023 // The world has changed on us, so we need to re-evaluate alarms 4024 // regardless of whether the kernel has told us one went off. 4025 result |= IS_WAKEUP_MASK; 4026 } 4027 } 4028 4029 if (result != TIME_CHANGED_MASK) { 4030 // If this was anything besides just a time change, then figure what if 4031 // anything to do about alarms. 4032 synchronized (mLock) { 4033 if (localLOGV) Slog.v( 4034 TAG, "Checking for alarms... rtc=" + nowRTC 4035 + ", elapsed=" + nowELAPSED); 4036 4037 if (WAKEUP_STATS) { 4038 if ((result & IS_WAKEUP_MASK) != 0) { 4039 long newEarliest = nowRTC - RECENT_WAKEUP_PERIOD; 4040 int n = 0; 4041 for (WakeupEvent event : mRecentWakeups) { 4042 if (event.when > newEarliest) break; 4043 n++; // number of now-stale entries at the list head 4044 } 4045 for (int i = 0; i < n; i++) { 4046 mRecentWakeups.remove(); 4047 } 4048 4049 recordWakeupAlarms(mAlarmBatches, nowELAPSED, nowRTC); 4050 } 4051 } 4052 4053 mLastTrigger = nowELAPSED; 4054 boolean hasWakeup = triggerAlarmsLocked(triggerList, nowELAPSED); 4055 if (!hasWakeup && checkAllowNonWakeupDelayLocked(nowELAPSED)) { 4056 // if there are no wakeup alarms and the screen is off, we can 4057 // delay what we have so far until the future. 4058 if (mPendingNonWakeupAlarms.size() == 0) { 4059 mStartCurrentDelayTime = nowELAPSED; 4060 mNextNonWakeupDeliveryTime = nowELAPSED 4061 + ((currentNonWakeupFuzzLocked(nowELAPSED)*3)/2); 4062 } 4063 mPendingNonWakeupAlarms.addAll(triggerList); 4064 mNumDelayedAlarms += triggerList.size(); 4065 rescheduleKernelAlarmsLocked(); 4066 updateNextAlarmClockLocked(); 4067 } else { 4068 // now deliver the alarm intents; if there are pending non-wakeup 4069 // alarms, we need to merge them in to the list. note we don't 4070 // just deliver them first because we generally want non-wakeup 4071 // alarms delivered after wakeup alarms. 4072 if (mPendingNonWakeupAlarms.size() > 0) { 4073 calculateDeliveryPriorities(mPendingNonWakeupAlarms); 4074 triggerList.addAll(mPendingNonWakeupAlarms); 4075 Collections.sort(triggerList, mAlarmDispatchComparator); 4076 final long thisDelayTime = nowELAPSED - mStartCurrentDelayTime; 4077 mTotalDelayTime += thisDelayTime; 4078 if (mMaxDelayTime < thisDelayTime) { 4079 mMaxDelayTime = thisDelayTime; 4080 } 4081 mPendingNonWakeupAlarms.clear(); 4082 } 4083 if (mLastTimeChangeRealtime != nowELAPSED && triggerList.isEmpty()) { 4084 if (++mFalseWakeups >= mWtfThreshold) { 4085 Slog.wtf(TAG, "Too many (" + mFalseWakeups 4086 + ") false wakeups, nowElapsed=" + nowELAPSED); 4087 if (mWtfThreshold < 100_000) { 4088 mWtfThreshold *= 10; 4089 } else { 4090 mFalseWakeups = 0; 4091 } 4092 } 4093 } 4094 final ArraySet<Pair<String, Integer>> triggerPackages = 4095 new ArraySet<>(); 4096 for (int i = 0; i < triggerList.size(); i++) { 4097 final Alarm a = triggerList.get(i); 4098 if (!isExemptFromAppStandby(a)) { 4099 triggerPackages.add(Pair.create( 4100 a.sourcePackage, UserHandle.getUserId(a.creatorUid))); 4101 } 4102 } 4103 deliverAlarmsLocked(triggerList, nowELAPSED); 4104 reorderAlarmsBasedOnStandbyBuckets(triggerPackages); 4105 rescheduleKernelAlarmsLocked(); 4106 updateNextAlarmClockLocked(); 4107 } 4108 } 4109 4110 } else { 4111 // Just in case -- even though no wakeup flag was set, make sure 4112 // we have updated the kernel to the next alarm time. 4113 synchronized (mLock) { 4114 rescheduleKernelAlarmsLocked(); 4115 } 4116 } 4117 } 4118 } 4119 } 4120 4121 /** 4122 * Attribute blame for a WakeLock. 4123 * @param ws WorkSource to attribute blame. 4124 * @param knownUid attribution uid; < 0 values are ignored. 4125 */ setWakelockWorkSource(WorkSource ws, int knownUid, String tag, boolean first)4126 void setWakelockWorkSource(WorkSource ws, int knownUid, String tag, boolean first) { 4127 try { 4128 mWakeLock.setHistoryTag(first ? tag : null); 4129 4130 if (ws != null) { 4131 mWakeLock.setWorkSource(ws); 4132 return; 4133 } 4134 4135 if (knownUid >= 0) { 4136 mWakeLock.setWorkSource(new WorkSource(knownUid)); 4137 return; 4138 } 4139 } catch (Exception e) { 4140 } 4141 4142 // Something went wrong; fall back to attributing the lock to the OS 4143 mWakeLock.setWorkSource(null); 4144 } 4145 getAlarmAttributionUid(Alarm alarm)4146 private static int getAlarmAttributionUid(Alarm alarm) { 4147 if (alarm.workSource != null && !alarm.workSource.isEmpty()) { 4148 return alarm.workSource.getAttributionUid(); 4149 } 4150 4151 return alarm.creatorUid; 4152 } 4153 4154 @VisibleForTesting 4155 class AlarmHandler extends Handler { 4156 public static final int ALARM_EVENT = 1; 4157 public static final int SEND_NEXT_ALARM_CLOCK_CHANGED = 2; 4158 public static final int LISTENER_TIMEOUT = 3; 4159 public static final int REPORT_ALARMS_ACTIVE = 4; 4160 public static final int APP_STANDBY_BUCKET_CHANGED = 5; 4161 public static final int CHARGING_STATUS_CHANGED = 6; 4162 public static final int REMOVE_FOR_STOPPED = 7; 4163 public static final int REMOVE_FOR_CANCELED = 8; 4164 AlarmHandler()4165 AlarmHandler() { 4166 super(Looper.myLooper()); 4167 } 4168 postRemoveForStopped(int uid)4169 public void postRemoveForStopped(int uid) { 4170 obtainMessage(REMOVE_FOR_STOPPED, uid, 0).sendToTarget(); 4171 } 4172 4173 @Override handleMessage(Message msg)4174 public void handleMessage(Message msg) { 4175 switch (msg.what) { 4176 case ALARM_EVENT: { 4177 // This code is used when the kernel timer driver is not available, which 4178 // shouldn't happen. Here, we try our best to simulate it, which may be useful 4179 // when porting Android to a new device. Note that we can't wake up a device 4180 // this way, so WAKE_UP alarms will be delivered only when the device is awake. 4181 ArrayList<Alarm> triggerList = new ArrayList<Alarm>(); 4182 synchronized (mLock) { 4183 final long nowELAPSED = mInjector.getElapsedRealtime(); 4184 triggerAlarmsLocked(triggerList, nowELAPSED); 4185 updateNextAlarmClockLocked(); 4186 } 4187 4188 // now trigger the alarms without the lock held 4189 for (int i=0; i<triggerList.size(); i++) { 4190 Alarm alarm = triggerList.get(i); 4191 try { 4192 alarm.operation.send(); 4193 } catch (PendingIntent.CanceledException e) { 4194 if (alarm.repeatInterval > 0) { 4195 // This IntentSender is no longer valid, but this 4196 // is a repeating alarm, so toss the hoser. 4197 removeImpl(alarm.operation, null); 4198 } 4199 } 4200 decrementAlarmCount(alarm.uid, 1); 4201 } 4202 break; 4203 } 4204 4205 case SEND_NEXT_ALARM_CLOCK_CHANGED: 4206 sendNextAlarmClockChanged(); 4207 break; 4208 4209 case LISTENER_TIMEOUT: 4210 mDeliveryTracker.alarmTimedOut((IBinder) msg.obj); 4211 break; 4212 4213 case REPORT_ALARMS_ACTIVE: 4214 if (mLocalDeviceIdleController != null) { 4215 mLocalDeviceIdleController.setAlarmsActive(msg.arg1 != 0); 4216 } 4217 break; 4218 4219 case CHARGING_STATUS_CHANGED: 4220 synchronized (mLock) { 4221 mAppStandbyParole = (Boolean) msg.obj; 4222 if (reorderAlarmsBasedOnStandbyBuckets(null)) { 4223 rescheduleKernelAlarmsLocked(); 4224 updateNextAlarmClockLocked(); 4225 } 4226 } 4227 break; 4228 4229 case APP_STANDBY_BUCKET_CHANGED: 4230 synchronized (mLock) { 4231 final ArraySet<Pair<String, Integer>> filterPackages = new ArraySet<>(); 4232 filterPackages.add(Pair.create((String) msg.obj, msg.arg1)); 4233 if (reorderAlarmsBasedOnStandbyBuckets(filterPackages)) { 4234 rescheduleKernelAlarmsLocked(); 4235 updateNextAlarmClockLocked(); 4236 } 4237 } 4238 break; 4239 4240 case REMOVE_FOR_STOPPED: 4241 synchronized (mLock) { 4242 removeForStoppedLocked(msg.arg1); 4243 } 4244 break; 4245 4246 case REMOVE_FOR_CANCELED: 4247 final PendingIntent operation = (PendingIntent) msg.obj; 4248 synchronized (mLock) { 4249 removeLocked(operation, null); 4250 } 4251 break; 4252 4253 default: 4254 // nope, just ignore it 4255 break; 4256 } 4257 } 4258 } 4259 4260 @VisibleForTesting 4261 class ChargingReceiver extends BroadcastReceiver { ChargingReceiver()4262 ChargingReceiver() { 4263 IntentFilter filter = new IntentFilter(); 4264 filter.addAction(BatteryManager.ACTION_CHARGING); 4265 filter.addAction(BatteryManager.ACTION_DISCHARGING); 4266 getContext().registerReceiver(this, filter); 4267 } 4268 4269 @Override onReceive(Context context, Intent intent)4270 public void onReceive(Context context, Intent intent) { 4271 final String action = intent.getAction(); 4272 final boolean charging; 4273 if (BatteryManager.ACTION_CHARGING.equals(action)) { 4274 if (DEBUG_STANDBY) { 4275 Slog.d(TAG, "Device is charging."); 4276 } 4277 charging = true; 4278 } else { 4279 if (DEBUG_STANDBY) { 4280 Slog.d(TAG, "Disconnected from power."); 4281 } 4282 charging = false; 4283 } 4284 mHandler.removeMessages(AlarmHandler.CHARGING_STATUS_CHANGED); 4285 mHandler.obtainMessage(AlarmHandler.CHARGING_STATUS_CHANGED, charging) 4286 .sendToTarget(); 4287 } 4288 } 4289 4290 @VisibleForTesting 4291 class ClockReceiver extends BroadcastReceiver { ClockReceiver()4292 public ClockReceiver() { 4293 IntentFilter filter = new IntentFilter(); 4294 filter.addAction(Intent.ACTION_DATE_CHANGED); 4295 getContext().registerReceiver(this, filter); 4296 } 4297 4298 @Override onReceive(Context context, Intent intent)4299 public void onReceive(Context context, Intent intent) { 4300 if (intent.getAction().equals(Intent.ACTION_DATE_CHANGED)) { 4301 // Since the kernel does not keep track of DST, we need to 4302 // reset the TZ information at the beginning of each day 4303 // based off of the current Zone gmt offset + userspace tracked 4304 // daylight savings information. 4305 TimeZone zone = TimeZone.getTimeZone(SystemProperties.get(TIMEZONE_PROPERTY)); 4306 int gmtOffset = zone.getOffset(mInjector.getCurrentTimeMillis()); 4307 mInjector.setKernelTimezone(-(gmtOffset / 60000)); 4308 scheduleDateChangedEvent(); 4309 } 4310 } 4311 scheduleTimeTickEvent()4312 public void scheduleTimeTickEvent() { 4313 final long currentTime = mInjector.getCurrentTimeMillis(); 4314 final long nextTime = 60000 * ((currentTime / 60000) + 1); 4315 4316 // Schedule this event for the amount of time that it would take to get to 4317 // the top of the next minute. 4318 final long tickEventDelay = nextTime - currentTime; 4319 4320 final WorkSource workSource = null; // Let system take blame for time tick events. 4321 setImpl(ELAPSED_REALTIME, mInjector.getElapsedRealtime() + tickEventDelay, 0, 4322 0, null, mTimeTickTrigger, "TIME_TICK", AlarmManager.FLAG_STANDALONE, 4323 workSource, null, Process.myUid(), "android"); 4324 4325 // Finally, remember when we set the tick alarm 4326 synchronized (mLock) { 4327 mLastTickSet = currentTime; 4328 } 4329 } 4330 scheduleDateChangedEvent()4331 public void scheduleDateChangedEvent() { 4332 Calendar calendar = Calendar.getInstance(); 4333 calendar.setTimeInMillis(mInjector.getCurrentTimeMillis()); 4334 calendar.set(Calendar.HOUR_OF_DAY, 0); 4335 calendar.set(Calendar.MINUTE, 0); 4336 calendar.set(Calendar.SECOND, 0); 4337 calendar.set(Calendar.MILLISECOND, 0); 4338 calendar.add(Calendar.DAY_OF_MONTH, 1); 4339 4340 final WorkSource workSource = null; // Let system take blame for date change events. 4341 setImpl(RTC, calendar.getTimeInMillis(), 0, 0, mDateChangeSender, null, null, 4342 AlarmManager.FLAG_STANDALONE, workSource, null, 4343 Process.myUid(), "android"); 4344 } 4345 } 4346 4347 class InteractiveStateReceiver extends BroadcastReceiver { InteractiveStateReceiver()4348 public InteractiveStateReceiver() { 4349 IntentFilter filter = new IntentFilter(); 4350 filter.addAction(Intent.ACTION_SCREEN_OFF); 4351 filter.addAction(Intent.ACTION_SCREEN_ON); 4352 filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); 4353 getContext().registerReceiver(this, filter); 4354 } 4355 4356 @Override onReceive(Context context, Intent intent)4357 public void onReceive(Context context, Intent intent) { 4358 synchronized (mLock) { 4359 interactiveStateChangedLocked(Intent.ACTION_SCREEN_ON.equals(intent.getAction())); 4360 } 4361 } 4362 } 4363 4364 class UninstallReceiver extends BroadcastReceiver { UninstallReceiver()4365 public UninstallReceiver() { 4366 IntentFilter filter = new IntentFilter(); 4367 filter.addAction(Intent.ACTION_PACKAGE_REMOVED); 4368 filter.addAction(Intent.ACTION_PACKAGE_RESTARTED); 4369 filter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 4370 filter.addDataScheme("package"); 4371 getContext().registerReceiver(this, filter); 4372 // Register for events related to sdcard installation. 4373 IntentFilter sdFilter = new IntentFilter(); 4374 sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); 4375 sdFilter.addAction(Intent.ACTION_USER_STOPPED); 4376 sdFilter.addAction(Intent.ACTION_UID_REMOVED); 4377 getContext().registerReceiver(this, sdFilter); 4378 } 4379 4380 @Override onReceive(Context context, Intent intent)4381 public void onReceive(Context context, Intent intent) { 4382 final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 4383 synchronized (mLock) { 4384 String pkgList[] = null; 4385 switch (intent.getAction()) { 4386 case Intent.ACTION_QUERY_PACKAGE_RESTART: 4387 pkgList = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 4388 for (String packageName : pkgList) { 4389 if (lookForPackageLocked(packageName)) { 4390 setResultCode(Activity.RESULT_OK); 4391 return; 4392 } 4393 } 4394 return; 4395 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 4396 pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 4397 break; 4398 case Intent.ACTION_USER_STOPPED: 4399 final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 4400 if (userHandle >= 0) { 4401 removeUserLocked(userHandle); 4402 mAppWakeupHistory.removeForUser(userHandle); 4403 } 4404 return; 4405 case Intent.ACTION_UID_REMOVED: 4406 if (uid >= 0) { 4407 mLastAllowWhileIdleDispatch.delete(uid); 4408 mUseAllowWhileIdleShortTime.delete(uid); 4409 } 4410 return; 4411 case Intent.ACTION_PACKAGE_REMOVED: 4412 if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 4413 // This package is being updated; don't kill its alarms. 4414 return; 4415 } 4416 // Intentional fall-through. 4417 case Intent.ACTION_PACKAGE_RESTARTED: 4418 final Uri data = intent.getData(); 4419 if (data != null) { 4420 final String pkg = data.getSchemeSpecificPart(); 4421 if (pkg != null) { 4422 pkgList = new String[]{pkg}; 4423 } 4424 } 4425 break; 4426 } 4427 if (pkgList != null && (pkgList.length > 0)) { 4428 for (String pkg : pkgList) { 4429 if (uid >= 0) { 4430 // package-removed and package-restarted case 4431 mAppWakeupHistory.removeForPackage(pkg, UserHandle.getUserId(uid)); 4432 removeLocked(uid); 4433 } else { 4434 // external-applications-unavailable case 4435 removeLocked(pkg); 4436 } 4437 mPriorities.remove(pkg); 4438 for (int i=mBroadcastStats.size()-1; i>=0; i--) { 4439 ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(i); 4440 if (uidStats.remove(pkg) != null) { 4441 if (uidStats.size() <= 0) { 4442 mBroadcastStats.removeAt(i); 4443 } 4444 } 4445 } 4446 } 4447 } 4448 } 4449 } 4450 } 4451 4452 final class UidObserver extends IUidObserver.Stub { onUidStateChanged(int uid, int procState, long procStateSeq, int capability)4453 @Override public void onUidStateChanged(int uid, int procState, long procStateSeq, 4454 int capability) { 4455 } 4456 onUidGone(int uid, boolean disabled)4457 @Override public void onUidGone(int uid, boolean disabled) { 4458 if (disabled) { 4459 mHandler.postRemoveForStopped(uid); 4460 } 4461 } 4462 onUidActive(int uid)4463 @Override public void onUidActive(int uid) { 4464 } 4465 onUidIdle(int uid, boolean disabled)4466 @Override public void onUidIdle(int uid, boolean disabled) { 4467 if (disabled) { 4468 mHandler.postRemoveForStopped(uid); 4469 } 4470 } 4471 onUidCachedChanged(int uid, boolean cached)4472 @Override public void onUidCachedChanged(int uid, boolean cached) { 4473 } 4474 } 4475 4476 /** 4477 * Tracking of app assignments to standby buckets 4478 */ 4479 private final class AppStandbyTracker extends 4480 AppIdleStateChangeListener { 4481 @Override onAppIdleStateChanged(final String packageName, final @UserIdInt int userId, boolean idle, int bucket, int reason)4482 public void onAppIdleStateChanged(final String packageName, final @UserIdInt int userId, 4483 boolean idle, int bucket, int reason) { 4484 if (DEBUG_STANDBY) { 4485 Slog.d(TAG, "Package " + packageName + " for user " + userId + " now in bucket " + 4486 bucket); 4487 } 4488 mHandler.removeMessages(AlarmHandler.APP_STANDBY_BUCKET_CHANGED); 4489 mHandler.obtainMessage(AlarmHandler.APP_STANDBY_BUCKET_CHANGED, userId, -1, packageName) 4490 .sendToTarget(); 4491 } 4492 } 4493 4494 private final Listener mForceAppStandbyListener = new Listener() { 4495 @Override 4496 public void unblockAllUnrestrictedAlarms() { 4497 synchronized (mLock) { 4498 sendAllUnrestrictedPendingBackgroundAlarmsLocked(); 4499 } 4500 } 4501 4502 @Override 4503 public void unblockAlarmsForUid(int uid) { 4504 synchronized (mLock) { 4505 sendPendingBackgroundAlarmsLocked(uid, null); 4506 } 4507 } 4508 4509 @Override 4510 public void unblockAlarmsForUidPackage(int uid, String packageName) { 4511 synchronized (mLock) { 4512 sendPendingBackgroundAlarmsLocked(uid, packageName); 4513 } 4514 } 4515 4516 @Override 4517 public void onUidForeground(int uid, boolean foreground) { 4518 synchronized (mLock) { 4519 if (foreground) { 4520 mUseAllowWhileIdleShortTime.put(uid, true); 4521 4522 // Note we don't have to drain the pending while-idle alarms here, because 4523 // this event should coincide with unblockAlarmsForUid(). 4524 } 4525 } 4526 } 4527 }; 4528 getStatsLocked(PendingIntent pi)4529 private final BroadcastStats getStatsLocked(PendingIntent pi) { 4530 String pkg = pi.getCreatorPackage(); 4531 int uid = pi.getCreatorUid(); 4532 return getStatsLocked(uid, pkg); 4533 } 4534 getStatsLocked(int uid, String pkgName)4535 private final BroadcastStats getStatsLocked(int uid, String pkgName) { 4536 ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.get(uid); 4537 if (uidStats == null) { 4538 uidStats = new ArrayMap<String, BroadcastStats>(); 4539 mBroadcastStats.put(uid, uidStats); 4540 } 4541 BroadcastStats bs = uidStats.get(pkgName); 4542 if (bs == null) { 4543 bs = new BroadcastStats(uid, pkgName); 4544 uidStats.put(pkgName, bs); 4545 } 4546 return bs; 4547 } 4548 4549 /** 4550 * Canonical count of (operation.send() - onSendFinished()) and 4551 * listener send/complete/timeout invocations. 4552 * Guarded by the usual lock. 4553 */ 4554 @GuardedBy("mLock") 4555 private int mSendCount = 0; 4556 @GuardedBy("mLock") 4557 private int mSendFinishCount = 0; 4558 @GuardedBy("mLock") 4559 private int mListenerCount = 0; 4560 @GuardedBy("mLock") 4561 private int mListenerFinishCount = 0; 4562 4563 class DeliveryTracker extends IAlarmCompleteListener.Stub implements PendingIntent.OnFinished { 4564 removeLocked(PendingIntent pi, Intent intent)4565 private InFlight removeLocked(PendingIntent pi, Intent intent) { 4566 for (int i = 0; i < mInFlight.size(); i++) { 4567 final InFlight inflight = mInFlight.get(i); 4568 if (inflight.mPendingIntent == pi) { 4569 if (pi.isBroadcast()) { 4570 notifyBroadcastAlarmCompleteLocked(inflight.mUid); 4571 } 4572 return mInFlight.remove(i); 4573 } 4574 } 4575 mLog.w("No in-flight alarm for " + pi + " " + intent); 4576 return null; 4577 } 4578 removeLocked(IBinder listener)4579 private InFlight removeLocked(IBinder listener) { 4580 for (int i = 0; i < mInFlight.size(); i++) { 4581 if (mInFlight.get(i).mListener == listener) { 4582 return mInFlight.remove(i); 4583 } 4584 } 4585 mLog.w("No in-flight alarm for listener " + listener); 4586 return null; 4587 } 4588 updateStatsLocked(InFlight inflight)4589 private void updateStatsLocked(InFlight inflight) { 4590 final long nowELAPSED = mInjector.getElapsedRealtime(); 4591 BroadcastStats bs = inflight.mBroadcastStats; 4592 bs.nesting--; 4593 if (bs.nesting <= 0) { 4594 bs.nesting = 0; 4595 bs.aggregateTime += nowELAPSED - bs.startTime; 4596 } 4597 FilterStats fs = inflight.mFilterStats; 4598 fs.nesting--; 4599 if (fs.nesting <= 0) { 4600 fs.nesting = 0; 4601 fs.aggregateTime += nowELAPSED - fs.startTime; 4602 } 4603 if (RECORD_ALARMS_IN_HISTORY) { 4604 ActivityManager.noteAlarmFinish(inflight.mPendingIntent, inflight.mWorkSource, 4605 inflight.mUid, inflight.mTag); 4606 } 4607 } 4608 updateTrackingLocked(InFlight inflight)4609 private void updateTrackingLocked(InFlight inflight) { 4610 if (inflight != null) { 4611 updateStatsLocked(inflight); 4612 } 4613 mBroadcastRefCount--; 4614 if (DEBUG_WAKELOCK) { 4615 Slog.d(TAG, "mBroadcastRefCount -> " + mBroadcastRefCount); 4616 } 4617 if (mBroadcastRefCount == 0) { 4618 mHandler.obtainMessage(AlarmHandler.REPORT_ALARMS_ACTIVE, 0).sendToTarget(); 4619 mWakeLock.release(); 4620 if (mInFlight.size() > 0) { 4621 mLog.w("Finished all dispatches with " + mInFlight.size() 4622 + " remaining inflights"); 4623 for (int i=0; i<mInFlight.size(); i++) { 4624 mLog.w(" Remaining #" + i + ": " + mInFlight.get(i)); 4625 } 4626 mInFlight.clear(); 4627 } 4628 } else { 4629 // the next of our alarms is now in flight. reattribute the wakelock. 4630 if (mInFlight.size() > 0) { 4631 InFlight inFlight = mInFlight.get(0); 4632 setWakelockWorkSource(inFlight.mWorkSource, inFlight.mCreatorUid, inFlight.mTag, 4633 false); 4634 } else { 4635 // should never happen 4636 mLog.w("Alarm wakelock still held but sent queue empty"); 4637 mWakeLock.setWorkSource(null); 4638 } 4639 } 4640 } 4641 4642 /** 4643 * Callback that arrives when a direct-call alarm reports that delivery has finished 4644 */ 4645 @Override alarmComplete(IBinder who)4646 public void alarmComplete(IBinder who) { 4647 if (who == null) { 4648 mLog.w("Invalid alarmComplete: uid=" + Binder.getCallingUid() 4649 + " pid=" + Binder.getCallingPid()); 4650 return; 4651 } 4652 4653 final long ident = Binder.clearCallingIdentity(); 4654 try { 4655 synchronized (mLock) { 4656 mHandler.removeMessages(AlarmHandler.LISTENER_TIMEOUT, who); 4657 InFlight inflight = removeLocked(who); 4658 if (inflight != null) { 4659 if (DEBUG_LISTENER_CALLBACK) { 4660 Slog.i(TAG, "alarmComplete() from " + who); 4661 } 4662 updateTrackingLocked(inflight); 4663 mListenerFinishCount++; 4664 } else { 4665 // Delivery timed out, and the timeout handling already took care of 4666 // updating our tracking here, so we needn't do anything further. 4667 if (DEBUG_LISTENER_CALLBACK) { 4668 Slog.i(TAG, "Late alarmComplete() from " + who); 4669 } 4670 } 4671 } 4672 } finally { 4673 Binder.restoreCallingIdentity(ident); 4674 } 4675 } 4676 4677 /** 4678 * Callback that arrives when a PendingIntent alarm has finished delivery 4679 */ 4680 @Override onSendFinished(PendingIntent pi, Intent intent, int resultCode, String resultData, Bundle resultExtras)4681 public void onSendFinished(PendingIntent pi, Intent intent, int resultCode, 4682 String resultData, Bundle resultExtras) { 4683 synchronized (mLock) { 4684 mSendFinishCount++; 4685 updateTrackingLocked(removeLocked(pi, intent)); 4686 } 4687 } 4688 4689 /** 4690 * Timeout of a direct-call alarm delivery 4691 */ alarmTimedOut(IBinder who)4692 public void alarmTimedOut(IBinder who) { 4693 synchronized (mLock) { 4694 InFlight inflight = removeLocked(who); 4695 if (inflight != null) { 4696 // TODO: implement ANR policy for the target 4697 if (DEBUG_LISTENER_CALLBACK) { 4698 Slog.i(TAG, "Alarm listener " + who + " timed out in delivery"); 4699 } 4700 updateTrackingLocked(inflight); 4701 mListenerFinishCount++; 4702 } else { 4703 if (DEBUG_LISTENER_CALLBACK) { 4704 Slog.i(TAG, "Spurious timeout of listener " + who); 4705 } 4706 mLog.w("Spurious timeout of listener " + who); 4707 } 4708 } 4709 } 4710 4711 /** 4712 * Deliver an alarm and set up the post-delivery handling appropriately 4713 */ 4714 @GuardedBy("mLock") deliverLocked(Alarm alarm, long nowELAPSED, boolean allowWhileIdle)4715 public void deliverLocked(Alarm alarm, long nowELAPSED, boolean allowWhileIdle) { 4716 final long workSourceToken = ThreadLocalWorkSource.setUid( 4717 getAlarmAttributionUid(alarm)); 4718 try { 4719 if (alarm.operation != null) { 4720 // PendingIntent alarm 4721 mSendCount++; 4722 4723 try { 4724 alarm.operation.send(getContext(), 0, 4725 mBackgroundIntent.putExtra( 4726 Intent.EXTRA_ALARM_COUNT, alarm.count), 4727 mDeliveryTracker, mHandler, null, 4728 allowWhileIdle ? mIdleOptions : null); 4729 } catch (PendingIntent.CanceledException e) { 4730 if (alarm.repeatInterval > 0) { 4731 // This IntentSender is no longer valid, but this 4732 // is a repeating alarm, so toss it 4733 removeImpl(alarm.operation, null); 4734 } 4735 // No actual delivery was possible, so the delivery tracker's 4736 // 'finished' callback won't be invoked. We also don't need 4737 // to do any wakelock or stats tracking, so we have nothing 4738 // left to do here but go on to the next thing. 4739 mSendFinishCount++; 4740 return; 4741 } 4742 } else { 4743 // Direct listener callback alarm 4744 mListenerCount++; 4745 4746 if (RECORD_ALARMS_IN_HISTORY) { 4747 if (alarm.listener == mTimeTickTrigger) { 4748 mTickHistory[mNextTickHistory++] = nowELAPSED; 4749 if (mNextTickHistory >= TICK_HISTORY_DEPTH) { 4750 mNextTickHistory = 0; 4751 } 4752 } 4753 } 4754 4755 try { 4756 if (DEBUG_LISTENER_CALLBACK) { 4757 Slog.v(TAG, "Alarm to uid=" + alarm.uid 4758 + " listener=" + alarm.listener.asBinder()); 4759 } 4760 alarm.listener.doAlarm(this); 4761 mHandler.sendMessageDelayed( 4762 mHandler.obtainMessage(AlarmHandler.LISTENER_TIMEOUT, 4763 alarm.listener.asBinder()), 4764 mConstants.LISTENER_TIMEOUT); 4765 } catch (Exception e) { 4766 if (DEBUG_LISTENER_CALLBACK) { 4767 Slog.i(TAG, "Alarm undeliverable to listener " 4768 + alarm.listener.asBinder(), e); 4769 } 4770 // As in the PendingIntent.CanceledException case, delivery of the 4771 // alarm was not possible, so we have no wakelock or timeout or 4772 // stats management to do. It threw before we posted the delayed 4773 // timeout message, so we're done here. 4774 mListenerFinishCount++; 4775 return; 4776 } 4777 } 4778 } finally { 4779 ThreadLocalWorkSource.restore(workSourceToken); 4780 } 4781 4782 // The alarm is now in flight; now arrange wakelock and stats tracking 4783 if (DEBUG_WAKELOCK) { 4784 Slog.d(TAG, "mBroadcastRefCount -> " + (mBroadcastRefCount + 1)); 4785 } 4786 if (mBroadcastRefCount == 0) { 4787 setWakelockWorkSource(alarm.workSource, alarm.creatorUid, alarm.statsTag, true); 4788 mWakeLock.acquire(); 4789 mHandler.obtainMessage(AlarmHandler.REPORT_ALARMS_ACTIVE, 1).sendToTarget(); 4790 } 4791 final InFlight inflight = new InFlight(AlarmManagerService.this, alarm, nowELAPSED); 4792 mInFlight.add(inflight); 4793 mBroadcastRefCount++; 4794 if (inflight.isBroadcast()) { 4795 notifyBroadcastAlarmPendingLocked(alarm.uid); 4796 } 4797 if (allowWhileIdle) { 4798 // Record the last time this uid handled an ALLOW_WHILE_IDLE alarm. 4799 mLastAllowWhileIdleDispatch.put(alarm.creatorUid, nowELAPSED); 4800 if ((mAppStateTracker == null) 4801 || mAppStateTracker.isUidInForeground(alarm.creatorUid)) { 4802 mUseAllowWhileIdleShortTime.put(alarm.creatorUid, true); 4803 } else { 4804 mUseAllowWhileIdleShortTime.put(alarm.creatorUid, false); 4805 } 4806 if (RECORD_DEVICE_IDLE_ALARMS) { 4807 IdleDispatchEntry ent = new IdleDispatchEntry(); 4808 ent.uid = alarm.uid; 4809 ent.pkg = alarm.packageName; 4810 ent.tag = alarm.statsTag; 4811 ent.op = "DELIVER"; 4812 ent.elapsedRealtime = nowELAPSED; 4813 mAllowWhileIdleDispatches.add(ent); 4814 } 4815 } 4816 if (!isExemptFromAppStandby(alarm)) { 4817 final Pair<String, Integer> packageUser = Pair.create(alarm.sourcePackage, 4818 UserHandle.getUserId(alarm.creatorUid)); 4819 mAppWakeupHistory.recordAlarmForPackage(alarm.sourcePackage, 4820 UserHandle.getUserId(alarm.creatorUid), nowELAPSED); 4821 } 4822 final BroadcastStats bs = inflight.mBroadcastStats; 4823 bs.count++; 4824 if (bs.nesting == 0) { 4825 bs.nesting = 1; 4826 bs.startTime = nowELAPSED; 4827 } else { 4828 bs.nesting++; 4829 } 4830 final FilterStats fs = inflight.mFilterStats; 4831 fs.count++; 4832 if (fs.nesting == 0) { 4833 fs.nesting = 1; 4834 fs.startTime = nowELAPSED; 4835 } else { 4836 fs.nesting++; 4837 } 4838 if (alarm.type == ELAPSED_REALTIME_WAKEUP 4839 || alarm.type == RTC_WAKEUP) { 4840 bs.numWakeup++; 4841 fs.numWakeup++; 4842 ActivityManager.noteWakeupAlarm( 4843 alarm.operation, alarm.workSource, alarm.uid, alarm.packageName, 4844 alarm.statsTag); 4845 } 4846 } 4847 } 4848 incrementAlarmCount(int uid)4849 private void incrementAlarmCount(int uid) { 4850 final int uidIndex = mAlarmsPerUid.indexOfKey(uid); 4851 if (uidIndex >= 0) { 4852 mAlarmsPerUid.setValueAt(uidIndex, mAlarmsPerUid.valueAt(uidIndex) + 1); 4853 } else { 4854 mAlarmsPerUid.put(uid, 1); 4855 } 4856 } 4857 decrementAlarmCount(int uid, int decrement)4858 private void decrementAlarmCount(int uid, int decrement) { 4859 int oldCount = 0; 4860 final int uidIndex = mAlarmsPerUid.indexOfKey(uid); 4861 if (uidIndex >= 0) { 4862 oldCount = mAlarmsPerUid.valueAt(uidIndex); 4863 if (oldCount > decrement) { 4864 mAlarmsPerUid.setValueAt(uidIndex, oldCount - decrement); 4865 } else { 4866 mAlarmsPerUid.removeAt(uidIndex); 4867 } 4868 } 4869 if (oldCount < decrement) { 4870 Slog.wtf(TAG, "Attempt to decrement existing alarm count " + oldCount + " by " 4871 + decrement + " for uid " + uid); 4872 } 4873 } 4874 4875 private class ShellCmd extends ShellCommand { 4876 getBinderService()4877 IAlarmManager getBinderService() { 4878 return IAlarmManager.Stub.asInterface(mService); 4879 } 4880 4881 @Override onCommand(String cmd)4882 public int onCommand(String cmd) { 4883 if (cmd == null) { 4884 return handleDefaultCommands(cmd); 4885 } 4886 4887 final PrintWriter pw = getOutPrintWriter(); 4888 try { 4889 switch (cmd) { 4890 case "set-time": 4891 final long millis = Long.parseLong(getNextArgRequired()); 4892 return (getBinderService().setTime(millis)) ? 0 : -1; 4893 case "set-timezone": 4894 final String tz = getNextArgRequired(); 4895 getBinderService().setTimeZone(tz); 4896 return 0; 4897 default: 4898 return handleDefaultCommands(cmd); 4899 } 4900 } catch (Exception e) { 4901 pw.println(e); 4902 } 4903 return -1; 4904 } 4905 4906 @Override onHelp()4907 public void onHelp() { 4908 PrintWriter pw = getOutPrintWriter(); 4909 pw.println("Alarm manager service (alarm) commands:"); 4910 pw.println(" help"); 4911 pw.println(" Print this help text."); 4912 pw.println(" set-time TIME"); 4913 pw.println(" Set the system clock time to TIME where TIME is milliseconds"); 4914 pw.println(" since the Epoch."); 4915 pw.println(" set-timezone TZ"); 4916 pw.println(" Set the system timezone to TZ where TZ is an Olson id."); 4917 } 4918 } 4919 } 4920