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