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