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 android.app.Activity; 20 import android.app.ActivityManager; 21 import android.app.AlarmManager; 22 import android.app.AppOpsManager; 23 import android.app.BroadcastOptions; 24 import android.app.IAlarmCompleteListener; 25 import android.app.IAlarmListener; 26 import android.app.IAlarmManager; 27 import android.app.IUidObserver; 28 import android.app.PendingIntent; 29 import android.content.BroadcastReceiver; 30 import android.content.ContentResolver; 31 import android.content.Context; 32 import android.content.Intent; 33 import android.content.IntentFilter; 34 import android.content.pm.ApplicationInfo; 35 import android.content.pm.PackageManager; 36 import android.content.pm.PackageManager.NameNotFoundException; 37 import android.content.pm.PermissionInfo; 38 import android.database.ContentObserver; 39 import android.net.Uri; 40 import android.os.Binder; 41 import android.os.Bundle; 42 import android.os.Environment; 43 import android.os.Handler; 44 import android.os.IBinder; 45 import android.os.Message; 46 import android.os.PowerManager; 47 import android.os.Process; 48 import android.os.RemoteException; 49 import android.os.SystemClock; 50 import android.os.SystemProperties; 51 import android.os.UserHandle; 52 import android.os.WorkSource; 53 import android.provider.Settings; 54 import android.text.TextUtils; 55 import android.text.format.DateFormat; 56 import android.util.ArrayMap; 57 import android.util.KeyValueListParser; 58 import android.util.Log; 59 import android.util.Slog; 60 import android.util.SparseArray; 61 import android.util.SparseBooleanArray; 62 import android.util.SparseLongArray; 63 import android.util.TimeUtils; 64 65 import java.io.ByteArrayOutputStream; 66 import java.io.FileDescriptor; 67 import java.io.PrintWriter; 68 import java.text.SimpleDateFormat; 69 import java.util.ArrayList; 70 import java.util.Arrays; 71 import java.util.Calendar; 72 import java.util.Collections; 73 import java.util.Comparator; 74 import java.util.Date; 75 import java.util.HashMap; 76 import java.util.LinkedList; 77 import java.util.Locale; 78 import java.util.Random; 79 import java.util.TimeZone; 80 import java.util.TreeSet; 81 82 import static android.app.AlarmManager.RTC_WAKEUP; 83 import static android.app.AlarmManager.RTC; 84 import static android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP; 85 import static android.app.AlarmManager.ELAPSED_REALTIME; 86 87 import com.android.internal.annotations.GuardedBy; 88 import com.android.internal.util.DumpUtils; 89 import com.android.internal.util.LocalLog; 90 91 class AlarmManagerService extends SystemService { 92 private static final int RTC_WAKEUP_MASK = 1 << RTC_WAKEUP; 93 private static final int RTC_MASK = 1 << RTC; 94 private static final int ELAPSED_REALTIME_WAKEUP_MASK = 1 << ELAPSED_REALTIME_WAKEUP; 95 private static final int ELAPSED_REALTIME_MASK = 1 << ELAPSED_REALTIME; 96 static final int TIME_CHANGED_MASK = 1 << 16; 97 static final int IS_WAKEUP_MASK = RTC_WAKEUP_MASK|ELAPSED_REALTIME_WAKEUP_MASK; 98 99 // Mask for testing whether a given alarm type is wakeup vs non-wakeup 100 static final int TYPE_NONWAKEUP_MASK = 0x1; // low bit => non-wakeup 101 102 static final String TAG = "AlarmManager"; 103 static final boolean localLOGV = false; 104 static final boolean DEBUG_BATCH = localLOGV || false; 105 static final boolean DEBUG_VALIDATE = localLOGV || false; 106 static final boolean DEBUG_ALARM_CLOCK = localLOGV || false; 107 static final boolean DEBUG_LISTENER_CALLBACK = localLOGV || false; 108 static final boolean DEBUG_WAKELOCK = localLOGV || false; 109 static final boolean RECORD_ALARMS_IN_HISTORY = true; 110 static final boolean RECORD_DEVICE_IDLE_ALARMS = false; 111 static final int ALARM_EVENT = 1; 112 static final String TIMEZONE_PROPERTY = "persist.sys.timezone"; 113 114 private final Intent mBackgroundIntent 115 = new Intent().addFlags(Intent.FLAG_FROM_BACKGROUND); 116 static final IncreasingTimeOrder sIncreasingTimeOrder = new IncreasingTimeOrder(); 117 118 static final boolean WAKEUP_STATS = false; 119 120 private static final Intent NEXT_ALARM_CLOCK_CHANGED_INTENT = 121 new Intent(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED) 122 .addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING 123 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); 124 125 final LocalLog mLog = new LocalLog(TAG); 126 127 AppOpsManager mAppOps; 128 DeviceIdleController.LocalService mLocalDeviceIdleController; 129 130 final Object mLock = new Object(); 131 132 long mNativeData; 133 private long mNextWakeup; 134 private long mNextNonWakeup; 135 private long mLastWakeupSet; 136 private long mLastWakeup; 137 int mBroadcastRefCount = 0; 138 PowerManager.WakeLock mWakeLock; 139 boolean mLastWakeLockUnimportantForLogging; 140 ArrayList<Alarm> mPendingNonWakeupAlarms = new ArrayList<>(); 141 ArrayList<InFlight> mInFlight = new ArrayList<>(); 142 final AlarmHandler mHandler = new AlarmHandler(); 143 ClockReceiver mClockReceiver; 144 InteractiveStateReceiver mInteractiveStateReceiver; 145 private UninstallReceiver mUninstallReceiver; 146 final DeliveryTracker mDeliveryTracker = new DeliveryTracker(); 147 PendingIntent mTimeTickSender; 148 PendingIntent mDateChangeSender; 149 Random mRandom; 150 boolean mInteractive = true; 151 long mNonInteractiveStartTime; 152 long mNonInteractiveTime; 153 long mLastAlarmDeliveryTime; 154 long mStartCurrentDelayTime; 155 long mNextNonWakeupDeliveryTime; 156 long mLastTimeChangeClockTime; 157 long mLastTimeChangeRealtime; 158 long mAllowWhileIdleMinTime; 159 int mNumTimeChanged; 160 161 // Bookkeeping about the identity of the "System UI" package, determined at runtime. 162 163 /** 164 * This permission must be defined by the canonical System UI package, 165 * with protection level "signature". 166 */ 167 private static final String SYSTEM_UI_SELF_PERMISSION = 168 "android.permission.systemui.IDENTITY"; 169 170 /** 171 * At boot we use SYSTEM_UI_SELF_PERMISSION to look up the definer's uid. 172 */ 173 int mSystemUiUid; 174 175 /** 176 * The current set of user whitelisted apps for device idle mode, meaning these are allowed 177 * to freely schedule alarms. 178 */ 179 int[] mDeviceIdleUserWhitelist = new int[0]; 180 181 /** 182 * For each uid, this is the last time we dispatched an "allow while idle" alarm, 183 * used to determine the earliest we can dispatch the next such alarm. 184 */ 185 final SparseLongArray mLastAllowWhileIdleDispatch = new SparseLongArray(); 186 187 final static class IdleDispatchEntry { 188 int uid; 189 String pkg; 190 String tag; 191 String op; 192 long elapsedRealtime; 193 long argRealtime; 194 } 195 final ArrayList<IdleDispatchEntry> mAllowWhileIdleDispatches = new ArrayList(); 196 197 /** 198 * Broadcast options to use for FLAG_ALLOW_WHILE_IDLE. 199 */ 200 Bundle mIdleOptions; 201 202 private final SparseArray<AlarmManager.AlarmClockInfo> mNextAlarmClockForUser = 203 new SparseArray<>(); 204 private final SparseArray<AlarmManager.AlarmClockInfo> mTmpSparseAlarmClockArray = 205 new SparseArray<>(); 206 private final SparseBooleanArray mPendingSendNextAlarmClockChangedForUser = 207 new SparseBooleanArray(); 208 private boolean mNextAlarmClockMayChange; 209 210 // May only use on mHandler's thread, locking not required. 211 private final SparseArray<AlarmManager.AlarmClockInfo> mHandlerSparseAlarmClockArray = 212 new SparseArray<>(); 213 214 /** 215 * All times are in milliseconds. These constants are kept synchronized with the system 216 * global Settings. Any access to this class or its fields should be done while 217 * holding the AlarmManagerService.mLock lock. 218 */ 219 private final class Constants extends ContentObserver { 220 // Key names stored in the settings value. 221 private static final String KEY_MIN_FUTURITY = "min_futurity"; 222 private static final String KEY_MIN_INTERVAL = "min_interval"; 223 private static final String KEY_ALLOW_WHILE_IDLE_SHORT_TIME = "allow_while_idle_short_time"; 224 private static final String KEY_ALLOW_WHILE_IDLE_LONG_TIME = "allow_while_idle_long_time"; 225 private static final String KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION 226 = "allow_while_idle_whitelist_duration"; 227 private static final String KEY_LISTENER_TIMEOUT = "listener_timeout"; 228 229 private static final long DEFAULT_MIN_FUTURITY = 5 * 1000; 230 private static final long DEFAULT_MIN_INTERVAL = 60 * 1000; 231 private static final long DEFAULT_ALLOW_WHILE_IDLE_SHORT_TIME = DEFAULT_MIN_FUTURITY; 232 private static final long DEFAULT_ALLOW_WHILE_IDLE_LONG_TIME = 9*60*1000; 233 private static final long DEFAULT_ALLOW_WHILE_IDLE_WHITELIST_DURATION = 10*1000; 234 235 private static final long DEFAULT_LISTENER_TIMEOUT = 5 * 1000; 236 237 // Minimum futurity of a new alarm 238 public long MIN_FUTURITY = DEFAULT_MIN_FUTURITY; 239 240 // Minimum alarm recurrence interval 241 public long MIN_INTERVAL = DEFAULT_MIN_INTERVAL; 242 243 // Minimum time between ALLOW_WHILE_IDLE alarms when system is not idle. 244 public long ALLOW_WHILE_IDLE_SHORT_TIME = DEFAULT_ALLOW_WHILE_IDLE_SHORT_TIME; 245 246 // Minimum time between ALLOW_WHILE_IDLE alarms when system is idling. 247 public long ALLOW_WHILE_IDLE_LONG_TIME = DEFAULT_ALLOW_WHILE_IDLE_LONG_TIME; 248 249 // BroadcastOptions.setTemporaryAppWhitelistDuration() to use for FLAG_ALLOW_WHILE_IDLE. 250 public long ALLOW_WHILE_IDLE_WHITELIST_DURATION 251 = DEFAULT_ALLOW_WHILE_IDLE_WHITELIST_DURATION; 252 253 // Direct alarm listener callback timeout 254 public long LISTENER_TIMEOUT = DEFAULT_LISTENER_TIMEOUT; 255 256 private ContentResolver mResolver; 257 private final KeyValueListParser mParser = new KeyValueListParser(','); 258 private long mLastAllowWhileIdleWhitelistDuration = -1; 259 260 public Constants(Handler handler) { 261 super(handler); 262 updateAllowWhileIdleMinTimeLocked(); 263 updateAllowWhileIdleWhitelistDurationLocked(); 264 } 265 266 public void start(ContentResolver resolver) { 267 mResolver = resolver; 268 mResolver.registerContentObserver(Settings.Global.getUriFor( 269 Settings.Global.ALARM_MANAGER_CONSTANTS), false, this); 270 updateConstants(); 271 } 272 273 public void updateAllowWhileIdleMinTimeLocked() { 274 mAllowWhileIdleMinTime = mPendingIdleUntil != null 275 ? ALLOW_WHILE_IDLE_LONG_TIME : ALLOW_WHILE_IDLE_SHORT_TIME; 276 } 277 278 public void updateAllowWhileIdleWhitelistDurationLocked() { 279 if (mLastAllowWhileIdleWhitelistDuration != ALLOW_WHILE_IDLE_WHITELIST_DURATION) { 280 mLastAllowWhileIdleWhitelistDuration = ALLOW_WHILE_IDLE_WHITELIST_DURATION; 281 BroadcastOptions opts = BroadcastOptions.makeBasic(); 282 opts.setTemporaryAppWhitelistDuration(ALLOW_WHILE_IDLE_WHITELIST_DURATION); 283 mIdleOptions = opts.toBundle(); 284 } 285 } 286 287 @Override 288 public void onChange(boolean selfChange, Uri uri) { 289 updateConstants(); 290 } 291 292 private void updateConstants() { 293 synchronized (mLock) { 294 try { 295 mParser.setString(Settings.Global.getString(mResolver, 296 Settings.Global.ALARM_MANAGER_CONSTANTS)); 297 } catch (IllegalArgumentException e) { 298 // Failed to parse the settings string, log this and move on 299 // with defaults. 300 Slog.e(TAG, "Bad alarm manager settings", e); 301 } 302 303 MIN_FUTURITY = mParser.getLong(KEY_MIN_FUTURITY, DEFAULT_MIN_FUTURITY); 304 MIN_INTERVAL = mParser.getLong(KEY_MIN_INTERVAL, DEFAULT_MIN_INTERVAL); 305 ALLOW_WHILE_IDLE_SHORT_TIME = mParser.getLong(KEY_ALLOW_WHILE_IDLE_SHORT_TIME, 306 DEFAULT_ALLOW_WHILE_IDLE_SHORT_TIME); 307 ALLOW_WHILE_IDLE_LONG_TIME = mParser.getLong(KEY_ALLOW_WHILE_IDLE_LONG_TIME, 308 DEFAULT_ALLOW_WHILE_IDLE_LONG_TIME); 309 ALLOW_WHILE_IDLE_WHITELIST_DURATION = mParser.getLong( 310 KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION, 311 DEFAULT_ALLOW_WHILE_IDLE_WHITELIST_DURATION); 312 LISTENER_TIMEOUT = mParser.getLong(KEY_LISTENER_TIMEOUT, 313 DEFAULT_LISTENER_TIMEOUT); 314 315 updateAllowWhileIdleMinTimeLocked(); 316 updateAllowWhileIdleWhitelistDurationLocked(); 317 } 318 } 319 320 void dump(PrintWriter pw) { 321 pw.println(" Settings:"); 322 323 pw.print(" "); pw.print(KEY_MIN_FUTURITY); pw.print("="); 324 TimeUtils.formatDuration(MIN_FUTURITY, pw); 325 pw.println(); 326 327 pw.print(" "); pw.print(KEY_MIN_INTERVAL); pw.print("="); 328 TimeUtils.formatDuration(MIN_INTERVAL, pw); 329 pw.println(); 330 331 pw.print(" "); pw.print(KEY_LISTENER_TIMEOUT); pw.print("="); 332 TimeUtils.formatDuration(LISTENER_TIMEOUT, pw); 333 pw.println(); 334 335 pw.print(" "); pw.print(KEY_ALLOW_WHILE_IDLE_SHORT_TIME); pw.print("="); 336 TimeUtils.formatDuration(ALLOW_WHILE_IDLE_SHORT_TIME, pw); 337 pw.println(); 338 339 pw.print(" "); pw.print(KEY_ALLOW_WHILE_IDLE_LONG_TIME); pw.print("="); 340 TimeUtils.formatDuration(ALLOW_WHILE_IDLE_LONG_TIME, pw); 341 pw.println(); 342 343 pw.print(" "); pw.print(KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION); pw.print("="); 344 TimeUtils.formatDuration(ALLOW_WHILE_IDLE_WHITELIST_DURATION, pw); 345 pw.println(); 346 } 347 } 348 349 final Constants mConstants; 350 351 // Alarm delivery ordering bookkeeping 352 static final int PRIO_TICK = 0; 353 static final int PRIO_WAKEUP = 1; 354 static final int PRIO_NORMAL = 2; 355 356 final class PriorityClass { 357 int seq; 358 int priority; 359 360 PriorityClass() { 361 seq = mCurrentSeq - 1; 362 priority = PRIO_NORMAL; 363 } 364 } 365 366 final HashMap<String, PriorityClass> mPriorities = new HashMap<>(); 367 int mCurrentSeq = 0; 368 369 static final class WakeupEvent { 370 public long when; 371 public int uid; 372 public String action; 373 374 public WakeupEvent(long theTime, int theUid, String theAction) { 375 when = theTime; 376 uid = theUid; 377 action = theAction; 378 } 379 } 380 381 final LinkedList<WakeupEvent> mRecentWakeups = new LinkedList<WakeupEvent>(); 382 final long RECENT_WAKEUP_PERIOD = 1000L * 60 * 60 * 24; // one day 383 384 final class Batch { 385 long start; // These endpoints are always in ELAPSED 386 long end; 387 int flags; // Flags for alarms, such as FLAG_STANDALONE. 388 389 final ArrayList<Alarm> alarms = new ArrayList<Alarm>(); 390 391 Batch() { 392 start = 0; 393 end = Long.MAX_VALUE; 394 flags = 0; 395 } 396 397 Batch(Alarm seed) { 398 start = seed.whenElapsed; 399 end = seed.maxWhenElapsed; 400 flags = seed.flags; 401 alarms.add(seed); 402 } 403 404 int size() { 405 return alarms.size(); 406 } 407 408 Alarm get(int index) { 409 return alarms.get(index); 410 } 411 412 boolean canHold(long whenElapsed, long maxWhen) { 413 return (end >= whenElapsed) && (start <= maxWhen); 414 } 415 416 boolean add(Alarm alarm) { 417 boolean newStart = false; 418 // narrows the batch if necessary; presumes that canHold(alarm) is true 419 int index = Collections.binarySearch(alarms, alarm, sIncreasingTimeOrder); 420 if (index < 0) { 421 index = 0 - index - 1; 422 } 423 alarms.add(index, alarm); 424 if (DEBUG_BATCH) { 425 Slog.v(TAG, "Adding " + alarm + " to " + this); 426 } 427 if (alarm.whenElapsed > start) { 428 start = alarm.whenElapsed; 429 newStart = true; 430 } 431 if (alarm.maxWhenElapsed < end) { 432 end = alarm.maxWhenElapsed; 433 } 434 flags |= alarm.flags; 435 436 if (DEBUG_BATCH) { 437 Slog.v(TAG, " => now " + this); 438 } 439 return newStart; 440 } 441 442 boolean remove(final PendingIntent operation, final IAlarmListener listener) { 443 if (operation == null && listener == null) { 444 if (localLOGV) { 445 Slog.w(TAG, "requested remove() of null operation", 446 new RuntimeException("here")); 447 } 448 return false; 449 } 450 boolean didRemove = false; 451 long newStart = 0; // recalculate endpoints as we go 452 long newEnd = Long.MAX_VALUE; 453 int newFlags = 0; 454 for (int i = 0; i < alarms.size(); ) { 455 Alarm alarm = alarms.get(i); 456 if (alarm.matches(operation, listener)) { 457 alarms.remove(i); 458 didRemove = true; 459 if (alarm.alarmClock != null) { 460 mNextAlarmClockMayChange = true; 461 } 462 } else { 463 if (alarm.whenElapsed > newStart) { 464 newStart = alarm.whenElapsed; 465 } 466 if (alarm.maxWhenElapsed < newEnd) { 467 newEnd = alarm.maxWhenElapsed; 468 } 469 newFlags |= alarm.flags; 470 i++; 471 } 472 } 473 if (didRemove) { 474 // commit the new batch bounds 475 start = newStart; 476 end = newEnd; 477 flags = newFlags; 478 } 479 return didRemove; 480 } 481 482 boolean remove(final String packageName) { 483 if (packageName == null) { 484 if (localLOGV) { 485 Slog.w(TAG, "requested remove() of null packageName", 486 new RuntimeException("here")); 487 } 488 return false; 489 } 490 boolean didRemove = false; 491 long newStart = 0; // recalculate endpoints as we go 492 long newEnd = Long.MAX_VALUE; 493 int newFlags = 0; 494 for (int i = alarms.size()-1; i >= 0; i--) { 495 Alarm alarm = alarms.get(i); 496 if (alarm.matches(packageName)) { 497 alarms.remove(i); 498 didRemove = true; 499 if (alarm.alarmClock != null) { 500 mNextAlarmClockMayChange = true; 501 } 502 } else { 503 if (alarm.whenElapsed > newStart) { 504 newStart = alarm.whenElapsed; 505 } 506 if (alarm.maxWhenElapsed < newEnd) { 507 newEnd = alarm.maxWhenElapsed; 508 } 509 newFlags |= alarm.flags; 510 } 511 } 512 if (didRemove) { 513 // commit the new batch bounds 514 start = newStart; 515 end = newEnd; 516 flags = newFlags; 517 } 518 return didRemove; 519 } 520 521 boolean removeForStopped(final int uid) { 522 boolean didRemove = false; 523 long newStart = 0; // recalculate endpoints as we go 524 long newEnd = Long.MAX_VALUE; 525 int newFlags = 0; 526 for (int i = alarms.size()-1; i >= 0; i--) { 527 Alarm alarm = alarms.get(i); 528 try { 529 if (alarm.uid == uid && ActivityManager.getService().isAppStartModeDisabled( 530 uid, alarm.packageName)) { 531 alarms.remove(i); 532 didRemove = true; 533 if (alarm.alarmClock != null) { 534 mNextAlarmClockMayChange = true; 535 } 536 } else { 537 if (alarm.whenElapsed > newStart) { 538 newStart = alarm.whenElapsed; 539 } 540 if (alarm.maxWhenElapsed < newEnd) { 541 newEnd = alarm.maxWhenElapsed; 542 } 543 newFlags |= alarm.flags; 544 } 545 } catch (RemoteException e) { 546 } 547 } 548 if (didRemove) { 549 // commit the new batch bounds 550 start = newStart; 551 end = newEnd; 552 flags = newFlags; 553 } 554 return didRemove; 555 } 556 557 boolean remove(final int userHandle) { 558 boolean didRemove = false; 559 long newStart = 0; // recalculate endpoints as we go 560 long newEnd = Long.MAX_VALUE; 561 for (int i = 0; i < alarms.size(); ) { 562 Alarm alarm = alarms.get(i); 563 if (UserHandle.getUserId(alarm.creatorUid) == userHandle) { 564 alarms.remove(i); 565 didRemove = true; 566 if (alarm.alarmClock != null) { 567 mNextAlarmClockMayChange = true; 568 } 569 } else { 570 if (alarm.whenElapsed > newStart) { 571 newStart = alarm.whenElapsed; 572 } 573 if (alarm.maxWhenElapsed < newEnd) { 574 newEnd = alarm.maxWhenElapsed; 575 } 576 i++; 577 } 578 } 579 if (didRemove) { 580 // commit the new batch bounds 581 start = newStart; 582 end = newEnd; 583 } 584 return didRemove; 585 } 586 587 boolean hasPackage(final String packageName) { 588 final int N = alarms.size(); 589 for (int i = 0; i < N; i++) { 590 Alarm a = alarms.get(i); 591 if (a.matches(packageName)) { 592 return true; 593 } 594 } 595 return false; 596 } 597 598 boolean hasWakeups() { 599 final int N = alarms.size(); 600 for (int i = 0; i < N; i++) { 601 Alarm a = alarms.get(i); 602 // non-wakeup alarms are types 1 and 3, i.e. have the low bit set 603 if ((a.type & TYPE_NONWAKEUP_MASK) == 0) { 604 return true; 605 } 606 } 607 return false; 608 } 609 610 @Override 611 public String toString() { 612 StringBuilder b = new StringBuilder(40); 613 b.append("Batch{"); b.append(Integer.toHexString(this.hashCode())); 614 b.append(" num="); b.append(size()); 615 b.append(" start="); b.append(start); 616 b.append(" end="); b.append(end); 617 if (flags != 0) { 618 b.append(" flgs=0x"); 619 b.append(Integer.toHexString(flags)); 620 } 621 b.append('}'); 622 return b.toString(); 623 } 624 } 625 626 static class BatchTimeOrder implements Comparator<Batch> { 627 public int compare(Batch b1, Batch b2) { 628 long when1 = b1.start; 629 long when2 = b2.start; 630 if (when1 > when2) { 631 return 1; 632 } 633 if (when1 < when2) { 634 return -1; 635 } 636 return 0; 637 } 638 } 639 640 final Comparator<Alarm> mAlarmDispatchComparator = new Comparator<Alarm>() { 641 @Override 642 public int compare(Alarm lhs, Alarm rhs) { 643 // priority class trumps everything. TICK < WAKEUP < NORMAL 644 if (lhs.priorityClass.priority < rhs.priorityClass.priority) { 645 return -1; 646 } else if (lhs.priorityClass.priority > rhs.priorityClass.priority) { 647 return 1; 648 } 649 650 // within each class, sort by nominal delivery time 651 if (lhs.whenElapsed < rhs.whenElapsed) { 652 return -1; 653 } else if (lhs.whenElapsed > rhs.whenElapsed) { 654 return 1; 655 } 656 657 // same priority class + same target delivery time 658 return 0; 659 } 660 }; 661 662 void calculateDeliveryPriorities(ArrayList<Alarm> alarms) { 663 final int N = alarms.size(); 664 for (int i = 0; i < N; i++) { 665 Alarm a = alarms.get(i); 666 667 final int alarmPrio; 668 if (a.operation != null 669 && Intent.ACTION_TIME_TICK.equals(a.operation.getIntent().getAction())) { 670 alarmPrio = PRIO_TICK; 671 } else if (a.wakeup) { 672 alarmPrio = PRIO_WAKEUP; 673 } else { 674 alarmPrio = PRIO_NORMAL; 675 } 676 677 PriorityClass packagePrio = a.priorityClass; 678 String alarmPackage = (a.operation != null) 679 ? a.operation.getCreatorPackage() 680 : a.packageName; 681 if (packagePrio == null) packagePrio = mPriorities.get(alarmPackage); 682 if (packagePrio == null) { 683 packagePrio = a.priorityClass = new PriorityClass(); // lowest prio & stale sequence 684 mPriorities.put(alarmPackage, packagePrio); 685 } 686 a.priorityClass = packagePrio; 687 688 if (packagePrio.seq != mCurrentSeq) { 689 // first alarm we've seen in the current delivery generation from this package 690 packagePrio.priority = alarmPrio; 691 packagePrio.seq = mCurrentSeq; 692 } else { 693 // Multiple alarms from this package being delivered in this generation; 694 // bump the package's delivery class if it's warranted. 695 // TICK < WAKEUP < NORMAL 696 if (alarmPrio < packagePrio.priority) { 697 packagePrio.priority = alarmPrio; 698 } 699 } 700 } 701 } 702 703 // minimum recurrence period or alarm futurity for us to be able to fuzz it 704 static final long MIN_FUZZABLE_INTERVAL = 10000; 705 static final BatchTimeOrder sBatchOrder = new BatchTimeOrder(); 706 final ArrayList<Batch> mAlarmBatches = new ArrayList<>(); 707 708 // set to null if in idle mode; while in this mode, any alarms we don't want 709 // to run during this time are placed in mPendingWhileIdleAlarms 710 Alarm mPendingIdleUntil = null; 711 Alarm mNextWakeFromIdle = null; 712 ArrayList<Alarm> mPendingWhileIdleAlarms = new ArrayList<>(); 713 714 public AlarmManagerService(Context context) { 715 super(context); 716 mConstants = new Constants(mHandler); 717 } 718 719 static long convertToElapsed(long when, int type) { 720 final boolean isRtc = (type == RTC || type == RTC_WAKEUP); 721 if (isRtc) { 722 when -= System.currentTimeMillis() - SystemClock.elapsedRealtime(); 723 } 724 return when; 725 } 726 727 // Apply a heuristic to { recurrence interval, futurity of the trigger time } to 728 // calculate the end of our nominal delivery window for the alarm. 729 static long maxTriggerTime(long now, long triggerAtTime, long interval) { 730 // Current heuristic: batchable window is 75% of either the recurrence interval 731 // [for a periodic alarm] or of the time from now to the desired delivery time, 732 // with a minimum delay/interval of 10 seconds, under which we will simply not 733 // defer the alarm. 734 long futurity = (interval == 0) 735 ? (triggerAtTime - now) 736 : interval; 737 if (futurity < MIN_FUZZABLE_INTERVAL) { 738 futurity = 0; 739 } 740 return triggerAtTime + (long)(.75 * futurity); 741 } 742 743 // returns true if the batch was added at the head 744 static boolean addBatchLocked(ArrayList<Batch> list, Batch newBatch) { 745 int index = Collections.binarySearch(list, newBatch, sBatchOrder); 746 if (index < 0) { 747 index = 0 - index - 1; 748 } 749 list.add(index, newBatch); 750 return (index == 0); 751 } 752 753 // Return the index of the matching batch, or -1 if none found. 754 int attemptCoalesceLocked(long whenElapsed, long maxWhen) { 755 final int N = mAlarmBatches.size(); 756 for (int i = 0; i < N; i++) { 757 Batch b = mAlarmBatches.get(i); 758 if ((b.flags&AlarmManager.FLAG_STANDALONE) == 0 && b.canHold(whenElapsed, maxWhen)) { 759 return i; 760 } 761 } 762 return -1; 763 } 764 765 // The RTC clock has moved arbitrarily, so we need to recalculate all the batching 766 void rebatchAllAlarms() { 767 synchronized (mLock) { 768 rebatchAllAlarmsLocked(true); 769 } 770 } 771 772 void rebatchAllAlarmsLocked(boolean doValidate) { 773 ArrayList<Batch> oldSet = (ArrayList<Batch>) mAlarmBatches.clone(); 774 mAlarmBatches.clear(); 775 Alarm oldPendingIdleUntil = mPendingIdleUntil; 776 final long nowElapsed = SystemClock.elapsedRealtime(); 777 final int oldBatches = oldSet.size(); 778 for (int batchNum = 0; batchNum < oldBatches; batchNum++) { 779 Batch batch = oldSet.get(batchNum); 780 final int N = batch.size(); 781 for (int i = 0; i < N; i++) { 782 reAddAlarmLocked(batch.get(i), nowElapsed, doValidate); 783 } 784 } 785 if (oldPendingIdleUntil != null && oldPendingIdleUntil != mPendingIdleUntil) { 786 Slog.wtf(TAG, "Rebatching: idle until changed from " + oldPendingIdleUntil 787 + " to " + mPendingIdleUntil); 788 if (mPendingIdleUntil == null) { 789 // Somehow we lost this... we need to restore all of the pending alarms. 790 restorePendingWhileIdleAlarmsLocked(); 791 } 792 } 793 rescheduleKernelAlarmsLocked(); 794 updateNextAlarmClockLocked(); 795 } 796 797 void reAddAlarmLocked(Alarm a, long nowElapsed, boolean doValidate) { 798 a.when = a.origWhen; 799 long whenElapsed = convertToElapsed(a.when, a.type); 800 final long maxElapsed; 801 if (a.windowLength == AlarmManager.WINDOW_EXACT) { 802 // Exact 803 maxElapsed = whenElapsed; 804 } else { 805 // Not exact. Preserve any explicit window, otherwise recalculate 806 // the window based on the alarm's new futurity. Note that this 807 // reflects a policy of preferring timely to deferred delivery. 808 maxElapsed = (a.windowLength > 0) 809 ? (whenElapsed + a.windowLength) 810 : maxTriggerTime(nowElapsed, whenElapsed, a.repeatInterval); 811 } 812 a.whenElapsed = whenElapsed; 813 a.maxWhenElapsed = maxElapsed; 814 setImplLocked(a, true, doValidate); 815 } 816 817 void restorePendingWhileIdleAlarmsLocked() { 818 if (RECORD_DEVICE_IDLE_ALARMS) { 819 IdleDispatchEntry ent = new IdleDispatchEntry(); 820 ent.uid = 0; 821 ent.pkg = "FINISH IDLE"; 822 ent.elapsedRealtime = SystemClock.elapsedRealtime(); 823 mAllowWhileIdleDispatches.add(ent); 824 } 825 826 // Bring pending alarms back into the main list. 827 if (mPendingWhileIdleAlarms.size() > 0) { 828 ArrayList<Alarm> alarms = mPendingWhileIdleAlarms; 829 mPendingWhileIdleAlarms = new ArrayList<>(); 830 final long nowElapsed = SystemClock.elapsedRealtime(); 831 for (int i=alarms.size() - 1; i >= 0; i--) { 832 Alarm a = alarms.get(i); 833 reAddAlarmLocked(a, nowElapsed, false); 834 } 835 } 836 837 // Make sure we are using the correct ALLOW_WHILE_IDLE min time. 838 mConstants.updateAllowWhileIdleMinTimeLocked(); 839 840 // Reschedule everything. 841 rescheduleKernelAlarmsLocked(); 842 updateNextAlarmClockLocked(); 843 844 // And send a TIME_TICK right now, since it is important to get the UI updated. 845 try { 846 mTimeTickSender.send(); 847 } catch (PendingIntent.CanceledException e) { 848 } 849 } 850 851 static final class InFlight { 852 final PendingIntent mPendingIntent; 853 final long mWhenElapsed; 854 final IBinder mListener; 855 final WorkSource mWorkSource; 856 final int mUid; 857 final String mTag; 858 final BroadcastStats mBroadcastStats; 859 final FilterStats mFilterStats; 860 final int mAlarmType; 861 862 InFlight(AlarmManagerService service, PendingIntent pendingIntent, IAlarmListener listener, 863 WorkSource workSource, int uid, String alarmPkg, int alarmType, String tag, 864 long nowELAPSED) { 865 mPendingIntent = pendingIntent; 866 mWhenElapsed = nowELAPSED; 867 mListener = listener != null ? listener.asBinder() : null; 868 mWorkSource = workSource; 869 mUid = uid; 870 mTag = tag; 871 mBroadcastStats = (pendingIntent != null) 872 ? service.getStatsLocked(pendingIntent) 873 : service.getStatsLocked(uid, alarmPkg); 874 FilterStats fs = mBroadcastStats.filterStats.get(mTag); 875 if (fs == null) { 876 fs = new FilterStats(mBroadcastStats, mTag); 877 mBroadcastStats.filterStats.put(mTag, fs); 878 } 879 fs.lastTime = nowELAPSED; 880 mFilterStats = fs; 881 mAlarmType = alarmType; 882 } 883 884 @Override 885 public String toString() { 886 return "InFlight{" 887 + "pendingIntent=" + mPendingIntent 888 + ", when=" + mWhenElapsed 889 + ", workSource=" + mWorkSource 890 + ", uid=" + mUid 891 + ", tag=" + mTag 892 + ", broadcastStats=" + mBroadcastStats 893 + ", filterStats=" + mFilterStats 894 + ", alarmType=" + mAlarmType 895 + "}"; 896 } 897 } 898 899 static final class FilterStats { 900 final BroadcastStats mBroadcastStats; 901 final String mTag; 902 903 long lastTime; 904 long aggregateTime; 905 int count; 906 int numWakeup; 907 long startTime; 908 int nesting; 909 910 FilterStats(BroadcastStats broadcastStats, String tag) { 911 mBroadcastStats = broadcastStats; 912 mTag = tag; 913 } 914 915 @Override 916 public String toString() { 917 return "FilterStats{" 918 + "tag=" + mTag 919 + ", lastTime=" + lastTime 920 + ", aggregateTime=" + aggregateTime 921 + ", count=" + count 922 + ", numWakeup=" + numWakeup 923 + ", startTime=" + startTime 924 + ", nesting=" + nesting 925 + "}"; 926 } 927 } 928 929 static final class BroadcastStats { 930 final int mUid; 931 final String mPackageName; 932 933 long aggregateTime; 934 int count; 935 int numWakeup; 936 long startTime; 937 int nesting; 938 final ArrayMap<String, FilterStats> filterStats = new ArrayMap<String, FilterStats>(); 939 940 BroadcastStats(int uid, String packageName) { 941 mUid = uid; 942 mPackageName = packageName; 943 } 944 945 @Override 946 public String toString() { 947 return "BroadcastStats{" 948 + "uid=" + mUid 949 + ", packageName=" + mPackageName 950 + ", aggregateTime=" + aggregateTime 951 + ", count=" + count 952 + ", numWakeup=" + numWakeup 953 + ", startTime=" + startTime 954 + ", nesting=" + nesting 955 + "}"; 956 } 957 } 958 959 final SparseArray<ArrayMap<String, BroadcastStats>> mBroadcastStats 960 = new SparseArray<ArrayMap<String, BroadcastStats>>(); 961 962 int mNumDelayedAlarms = 0; 963 long mTotalDelayTime = 0; 964 long mMaxDelayTime = 0; 965 966 @Override 967 public void onStart() { 968 mNativeData = init(); 969 mNextWakeup = mNextNonWakeup = 0; 970 971 // We have to set current TimeZone info to kernel 972 // because kernel doesn't keep this after reboot 973 setTimeZoneImpl(SystemProperties.get(TIMEZONE_PROPERTY)); 974 975 // Also sure that we're booting with a halfway sensible current time 976 if (mNativeData != 0) { 977 final long systemBuildTime = Environment.getRootDirectory().lastModified(); 978 if (System.currentTimeMillis() < systemBuildTime) { 979 Slog.i(TAG, "Current time only " + System.currentTimeMillis() 980 + ", advancing to build time " + systemBuildTime); 981 setKernelTime(mNativeData, systemBuildTime); 982 } 983 } 984 985 // Determine SysUI's uid 986 final PackageManager packMan = getContext().getPackageManager(); 987 try { 988 PermissionInfo sysUiPerm = packMan.getPermissionInfo(SYSTEM_UI_SELF_PERMISSION, 0); 989 ApplicationInfo sysUi = packMan.getApplicationInfo(sysUiPerm.packageName, 0); 990 if ((sysUi.privateFlags&ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) { 991 mSystemUiUid = sysUi.uid; 992 } else { 993 Slog.e(TAG, "SysUI permission " + SYSTEM_UI_SELF_PERMISSION 994 + " defined by non-privileged app " + sysUi.packageName 995 + " - ignoring"); 996 } 997 } catch (NameNotFoundException e) { 998 } 999 1000 if (mSystemUiUid <= 0) { 1001 Slog.wtf(TAG, "SysUI package not found!"); 1002 } 1003 1004 PowerManager pm = (PowerManager) getContext().getSystemService(Context.POWER_SERVICE); 1005 mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*alarm*"); 1006 1007 mTimeTickSender = PendingIntent.getBroadcastAsUser(getContext(), 0, 1008 new Intent(Intent.ACTION_TIME_TICK).addFlags( 1009 Intent.FLAG_RECEIVER_REGISTERED_ONLY 1010 | Intent.FLAG_RECEIVER_FOREGROUND 1011 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS), 0, 1012 UserHandle.ALL); 1013 Intent intent = new Intent(Intent.ACTION_DATE_CHANGED); 1014 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING 1015 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); 1016 mDateChangeSender = PendingIntent.getBroadcastAsUser(getContext(), 0, intent, 1017 Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT, UserHandle.ALL); 1018 1019 // now that we have initied the driver schedule the alarm 1020 mClockReceiver = new ClockReceiver(); 1021 mClockReceiver.scheduleTimeTickEvent(); 1022 mClockReceiver.scheduleDateChangedEvent(); 1023 mInteractiveStateReceiver = new InteractiveStateReceiver(); 1024 mUninstallReceiver = new UninstallReceiver(); 1025 1026 if (mNativeData != 0) { 1027 AlarmThread waitThread = new AlarmThread(); 1028 waitThread.start(); 1029 } else { 1030 Slog.w(TAG, "Failed to open alarm driver. Falling back to a handler."); 1031 } 1032 1033 try { 1034 ActivityManager.getService().registerUidObserver(new UidObserver(), 1035 ActivityManager.UID_OBSERVER_IDLE, ActivityManager.PROCESS_STATE_UNKNOWN, null); 1036 } catch (RemoteException e) { 1037 // ignored; both services live in system_server 1038 } 1039 1040 publishBinderService(Context.ALARM_SERVICE, mService); 1041 publishLocalService(LocalService.class, new LocalService()); 1042 } 1043 1044 @Override 1045 public void onBootPhase(int phase) { 1046 if (phase == PHASE_SYSTEM_SERVICES_READY) { 1047 mConstants.start(getContext().getContentResolver()); 1048 mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE); 1049 mLocalDeviceIdleController 1050 = LocalServices.getService(DeviceIdleController.LocalService.class); 1051 } 1052 } 1053 1054 @Override 1055 protected void finalize() throws Throwable { 1056 try { 1057 close(mNativeData); 1058 } finally { 1059 super.finalize(); 1060 } 1061 } 1062 1063 void setTimeZoneImpl(String tz) { 1064 if (TextUtils.isEmpty(tz)) { 1065 return; 1066 } 1067 1068 TimeZone zone = TimeZone.getTimeZone(tz); 1069 // Prevent reentrant calls from stepping on each other when writing 1070 // the time zone property 1071 boolean timeZoneWasChanged = false; 1072 synchronized (this) { 1073 String current = SystemProperties.get(TIMEZONE_PROPERTY); 1074 if (current == null || !current.equals(zone.getID())) { 1075 if (localLOGV) { 1076 Slog.v(TAG, "timezone changed: " + current + ", new=" + zone.getID()); 1077 } 1078 timeZoneWasChanged = true; 1079 SystemProperties.set(TIMEZONE_PROPERTY, zone.getID()); 1080 } 1081 1082 // Update the kernel timezone information 1083 // Kernel tracks time offsets as 'minutes west of GMT' 1084 int gmtOffset = zone.getOffset(System.currentTimeMillis()); 1085 setKernelTimezone(mNativeData, -(gmtOffset / 60000)); 1086 } 1087 1088 TimeZone.setDefault(null); 1089 1090 if (timeZoneWasChanged) { 1091 Intent intent = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 1092 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING 1093 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND 1094 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); 1095 intent.putExtra("time-zone", zone.getID()); 1096 getContext().sendBroadcastAsUser(intent, UserHandle.ALL); 1097 } 1098 } 1099 1100 void removeImpl(PendingIntent operation) { 1101 if (operation == null) { 1102 return; 1103 } 1104 synchronized (mLock) { 1105 removeLocked(operation, null); 1106 } 1107 } 1108 1109 void setImpl(int type, long triggerAtTime, long windowLength, long interval, 1110 PendingIntent operation, IAlarmListener directReceiver, String listenerTag, 1111 int flags, WorkSource workSource, AlarmManager.AlarmClockInfo alarmClock, 1112 int callingUid, String callingPackage) { 1113 // must be *either* PendingIntent or AlarmReceiver, but not both 1114 if ((operation == null && directReceiver == null) 1115 || (operation != null && directReceiver != null)) { 1116 Slog.w(TAG, "Alarms must either supply a PendingIntent or an AlarmReceiver"); 1117 // NB: previous releases failed silently here, so we are continuing to do the same 1118 // rather than throw an IllegalArgumentException. 1119 return; 1120 } 1121 1122 // Sanity check the window length. This will catch people mistakenly 1123 // trying to pass an end-of-window timestamp rather than a duration. 1124 if (windowLength > AlarmManager.INTERVAL_HALF_DAY) { 1125 Slog.w(TAG, "Window length " + windowLength 1126 + "ms suspiciously long; limiting to 1 hour"); 1127 windowLength = AlarmManager.INTERVAL_HOUR; 1128 } 1129 1130 // Sanity check the recurrence interval. This will catch people who supply 1131 // seconds when the API expects milliseconds. 1132 final long minInterval = mConstants.MIN_INTERVAL; 1133 if (interval > 0 && interval < minInterval) { 1134 Slog.w(TAG, "Suspiciously short interval " + interval 1135 + " millis; expanding to " + (minInterval/1000) 1136 + " seconds"); 1137 interval = minInterval; 1138 } 1139 1140 if (type < RTC_WAKEUP || type > ELAPSED_REALTIME) { 1141 throw new IllegalArgumentException("Invalid alarm type " + type); 1142 } 1143 1144 if (triggerAtTime < 0) { 1145 final long what = Binder.getCallingPid(); 1146 Slog.w(TAG, "Invalid alarm trigger time! " + triggerAtTime + " from uid=" + callingUid 1147 + " pid=" + what); 1148 triggerAtTime = 0; 1149 } 1150 1151 final long nowElapsed = SystemClock.elapsedRealtime(); 1152 final long nominalTrigger = convertToElapsed(triggerAtTime, type); 1153 // Try to prevent spamming by making sure we aren't firing alarms in the immediate future 1154 final long minTrigger = nowElapsed + mConstants.MIN_FUTURITY; 1155 final long triggerElapsed = (nominalTrigger > minTrigger) ? nominalTrigger : minTrigger; 1156 1157 final long maxElapsed; 1158 if (windowLength == AlarmManager.WINDOW_EXACT) { 1159 maxElapsed = triggerElapsed; 1160 } else if (windowLength < 0) { 1161 maxElapsed = maxTriggerTime(nowElapsed, triggerElapsed, interval); 1162 // Fix this window in place, so that as time approaches we don't collapse it. 1163 windowLength = maxElapsed - triggerElapsed; 1164 } else { 1165 maxElapsed = triggerElapsed + windowLength; 1166 } 1167 1168 synchronized (mLock) { 1169 if (DEBUG_BATCH) { 1170 Slog.v(TAG, "set(" + operation + ") : type=" + type 1171 + " triggerAtTime=" + triggerAtTime + " win=" + windowLength 1172 + " tElapsed=" + triggerElapsed + " maxElapsed=" + maxElapsed 1173 + " interval=" + interval + " flags=0x" + Integer.toHexString(flags)); 1174 } 1175 setImplLocked(type, triggerAtTime, triggerElapsed, windowLength, maxElapsed, 1176 interval, operation, directReceiver, listenerTag, flags, true, workSource, 1177 alarmClock, callingUid, callingPackage); 1178 } 1179 } 1180 1181 private void setImplLocked(int type, long when, long whenElapsed, long windowLength, 1182 long maxWhen, long interval, PendingIntent operation, IAlarmListener directReceiver, 1183 String listenerTag, int flags, boolean doValidate, WorkSource workSource, 1184 AlarmManager.AlarmClockInfo alarmClock, int callingUid, String callingPackage) { 1185 Alarm a = new Alarm(type, when, whenElapsed, windowLength, maxWhen, interval, 1186 operation, directReceiver, listenerTag, workSource, flags, alarmClock, 1187 callingUid, callingPackage); 1188 try { 1189 if (ActivityManager.getService().isAppStartModeDisabled(callingUid, callingPackage)) { 1190 Slog.w(TAG, "Not setting alarm from " + callingUid + ":" + a 1191 + " -- package not allowed to start"); 1192 return; 1193 } 1194 } catch (RemoteException e) { 1195 } 1196 removeLocked(operation, directReceiver); 1197 setImplLocked(a, false, doValidate); 1198 } 1199 1200 private void setImplLocked(Alarm a, boolean rebatching, boolean doValidate) { 1201 if ((a.flags&AlarmManager.FLAG_IDLE_UNTIL) != 0) { 1202 // This is a special alarm that will put the system into idle until it goes off. 1203 // The caller has given the time they want this to happen at, however we need 1204 // to pull that earlier if there are existing alarms that have requested to 1205 // bring us out of idle at an earlier time. 1206 if (mNextWakeFromIdle != null && a.whenElapsed > mNextWakeFromIdle.whenElapsed) { 1207 a.when = a.whenElapsed = a.maxWhenElapsed = mNextWakeFromIdle.whenElapsed; 1208 } 1209 // Add fuzz to make the alarm go off some time before the actual desired time. 1210 final long nowElapsed = SystemClock.elapsedRealtime(); 1211 final int fuzz = fuzzForDuration(a.whenElapsed-nowElapsed); 1212 if (fuzz > 0) { 1213 if (mRandom == null) { 1214 mRandom = new Random(); 1215 } 1216 final int delta = mRandom.nextInt(fuzz); 1217 a.whenElapsed -= delta; 1218 if (false) { 1219 Slog.d(TAG, "Alarm when: " + a.whenElapsed); 1220 Slog.d(TAG, "Delta until alarm: " + (a.whenElapsed-nowElapsed)); 1221 Slog.d(TAG, "Applied fuzz: " + fuzz); 1222 Slog.d(TAG, "Final delta: " + delta); 1223 Slog.d(TAG, "Final when: " + a.whenElapsed); 1224 } 1225 a.when = a.maxWhenElapsed = a.whenElapsed; 1226 } 1227 1228 } else if (mPendingIdleUntil != null) { 1229 // We currently have an idle until alarm scheduled; if the new alarm has 1230 // not explicitly stated it wants to run while idle, then put it on hold. 1231 if ((a.flags&(AlarmManager.FLAG_ALLOW_WHILE_IDLE 1232 | AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED 1233 | AlarmManager.FLAG_WAKE_FROM_IDLE)) 1234 == 0) { 1235 mPendingWhileIdleAlarms.add(a); 1236 return; 1237 } 1238 } 1239 1240 if (RECORD_DEVICE_IDLE_ALARMS) { 1241 if ((a.flags & AlarmManager.FLAG_ALLOW_WHILE_IDLE) != 0) { 1242 IdleDispatchEntry ent = new IdleDispatchEntry(); 1243 ent.uid = a.uid; 1244 ent.pkg = a.operation.getCreatorPackage(); 1245 ent.tag = a.operation.getTag(""); 1246 ent.op = "SET"; 1247 ent.elapsedRealtime = SystemClock.elapsedRealtime(); 1248 ent.argRealtime = a.whenElapsed; 1249 mAllowWhileIdleDispatches.add(ent); 1250 } 1251 } 1252 1253 int whichBatch = ((a.flags&AlarmManager.FLAG_STANDALONE) != 0) 1254 ? -1 : attemptCoalesceLocked(a.whenElapsed, a.maxWhenElapsed); 1255 if (whichBatch < 0) { 1256 Batch batch = new Batch(a); 1257 addBatchLocked(mAlarmBatches, batch); 1258 } else { 1259 Batch batch = mAlarmBatches.get(whichBatch); 1260 if (batch.add(a)) { 1261 // The start time of this batch advanced, so batch ordering may 1262 // have just been broken. Move it to where it now belongs. 1263 mAlarmBatches.remove(whichBatch); 1264 addBatchLocked(mAlarmBatches, batch); 1265 } 1266 } 1267 1268 if (a.alarmClock != null) { 1269 mNextAlarmClockMayChange = true; 1270 } 1271 1272 boolean needRebatch = false; 1273 1274 if ((a.flags&AlarmManager.FLAG_IDLE_UNTIL) != 0) { 1275 if (RECORD_DEVICE_IDLE_ALARMS) { 1276 if (mPendingIdleUntil == null) { 1277 IdleDispatchEntry ent = new IdleDispatchEntry(); 1278 ent.uid = 0; 1279 ent.pkg = "START IDLE"; 1280 ent.elapsedRealtime = SystemClock.elapsedRealtime(); 1281 mAllowWhileIdleDispatches.add(ent); 1282 } 1283 } 1284 if ((mPendingIdleUntil != a) && (mPendingIdleUntil != null)) { 1285 Slog.wtfStack(TAG, "setImplLocked: idle until changed from " + mPendingIdleUntil 1286 + " to " + a); 1287 } 1288 1289 mPendingIdleUntil = a; 1290 mConstants.updateAllowWhileIdleMinTimeLocked(); 1291 needRebatch = true; 1292 } else if ((a.flags&AlarmManager.FLAG_WAKE_FROM_IDLE) != 0) { 1293 if (mNextWakeFromIdle == null || mNextWakeFromIdle.whenElapsed > a.whenElapsed) { 1294 mNextWakeFromIdle = a; 1295 // If this wake from idle is earlier than whatever was previously scheduled, 1296 // and we are currently idling, then we need to rebatch alarms in case the idle 1297 // until time needs to be updated. 1298 if (mPendingIdleUntil != null) { 1299 needRebatch = true; 1300 } 1301 } 1302 } 1303 1304 if (!rebatching) { 1305 if (DEBUG_VALIDATE) { 1306 if (doValidate && !validateConsistencyLocked()) { 1307 Slog.v(TAG, "Tipping-point operation: type=" + a.type + " when=" + a.when 1308 + " when(hex)=" + Long.toHexString(a.when) 1309 + " whenElapsed=" + a.whenElapsed 1310 + " maxWhenElapsed=" + a.maxWhenElapsed 1311 + " interval=" + a.repeatInterval + " op=" + a.operation 1312 + " flags=0x" + Integer.toHexString(a.flags)); 1313 rebatchAllAlarmsLocked(false); 1314 needRebatch = false; 1315 } 1316 } 1317 1318 if (needRebatch) { 1319 rebatchAllAlarmsLocked(false); 1320 } 1321 1322 rescheduleKernelAlarmsLocked(); 1323 updateNextAlarmClockLocked(); 1324 } 1325 } 1326 1327 private final IBinder mService = new IAlarmManager.Stub() { 1328 @Override 1329 public void set(String callingPackage, 1330 int type, long triggerAtTime, long windowLength, long interval, int flags, 1331 PendingIntent operation, IAlarmListener directReceiver, String listenerTag, 1332 WorkSource workSource, AlarmManager.AlarmClockInfo alarmClock) { 1333 final int callingUid = Binder.getCallingUid(); 1334 1335 // make sure the caller is not lying about which package should be blamed for 1336 // wakelock time spent in alarm delivery 1337 mAppOps.checkPackage(callingUid, callingPackage); 1338 1339 // Repeating alarms must use PendingIntent, not direct listener 1340 if (interval != 0) { 1341 if (directReceiver != null) { 1342 throw new IllegalArgumentException("Repeating alarms cannot use AlarmReceivers"); 1343 } 1344 } 1345 1346 if (workSource != null) { 1347 getContext().enforcePermission( 1348 android.Manifest.permission.UPDATE_DEVICE_STATS, 1349 Binder.getCallingPid(), callingUid, "AlarmManager.set"); 1350 } 1351 1352 // No incoming callers can request either WAKE_FROM_IDLE or 1353 // ALLOW_WHILE_IDLE_UNRESTRICTED -- we will apply those later as appropriate. 1354 flags &= ~(AlarmManager.FLAG_WAKE_FROM_IDLE 1355 | AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED); 1356 1357 // Only the system can use FLAG_IDLE_UNTIL -- this is used to tell the alarm 1358 // manager when to come out of idle mode, which is only for DeviceIdleController. 1359 if (callingUid != Process.SYSTEM_UID) { 1360 flags &= ~AlarmManager.FLAG_IDLE_UNTIL; 1361 } 1362 1363 // If this is an exact time alarm, then it can't be batched with other alarms. 1364 if (windowLength == AlarmManager.WINDOW_EXACT) { 1365 flags |= AlarmManager.FLAG_STANDALONE; 1366 } 1367 1368 // If this alarm is for an alarm clock, then it must be standalone and we will 1369 // use it to wake early from idle if needed. 1370 if (alarmClock != null) { 1371 flags |= AlarmManager.FLAG_WAKE_FROM_IDLE | AlarmManager.FLAG_STANDALONE; 1372 1373 // If the caller is a core system component or on the user's whitelist, and not calling 1374 // to do work on behalf of someone else, then always set ALLOW_WHILE_IDLE_UNRESTRICTED. 1375 // This means we will allow these alarms to go off as normal even while idle, with no 1376 // timing restrictions. 1377 } else if (workSource == null && (callingUid < Process.FIRST_APPLICATION_UID 1378 || callingUid == mSystemUiUid 1379 || Arrays.binarySearch(mDeviceIdleUserWhitelist, 1380 UserHandle.getAppId(callingUid)) >= 0)) { 1381 flags |= AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED; 1382 flags &= ~AlarmManager.FLAG_ALLOW_WHILE_IDLE; 1383 } 1384 1385 setImpl(type, triggerAtTime, windowLength, interval, operation, directReceiver, 1386 listenerTag, flags, workSource, alarmClock, callingUid, callingPackage); 1387 } 1388 1389 @Override 1390 public boolean setTime(long millis) { 1391 getContext().enforceCallingOrSelfPermission( 1392 "android.permission.SET_TIME", 1393 "setTime"); 1394 1395 if (mNativeData == 0) { 1396 Slog.w(TAG, "Not setting time since no alarm driver is available."); 1397 return false; 1398 } 1399 1400 synchronized (mLock) { 1401 return setKernelTime(mNativeData, millis) == 0; 1402 } 1403 } 1404 1405 @Override 1406 public void setTimeZone(String tz) { 1407 getContext().enforceCallingOrSelfPermission( 1408 "android.permission.SET_TIME_ZONE", 1409 "setTimeZone"); 1410 1411 final long oldId = Binder.clearCallingIdentity(); 1412 try { 1413 setTimeZoneImpl(tz); 1414 } finally { 1415 Binder.restoreCallingIdentity(oldId); 1416 } 1417 } 1418 1419 @Override 1420 public void remove(PendingIntent operation, IAlarmListener listener) { 1421 if (operation == null && listener == null) { 1422 Slog.w(TAG, "remove() with no intent or listener"); 1423 return; 1424 } 1425 1426 synchronized (mLock) { 1427 removeLocked(operation, listener); 1428 } 1429 } 1430 1431 @Override 1432 public long getNextWakeFromIdleTime() { 1433 return getNextWakeFromIdleTimeImpl(); 1434 } 1435 1436 @Override 1437 public AlarmManager.AlarmClockInfo getNextAlarmClock(int userId) { 1438 userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), 1439 Binder.getCallingUid(), userId, false /* allowAll */, false /* requireFull */, 1440 "getNextAlarmClock", null); 1441 1442 return getNextAlarmClockImpl(userId); 1443 } 1444 1445 @Override 1446 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1447 if (!DumpUtils.checkDumpAndUsageStatsPermission(getContext(), TAG, pw)) return; 1448 dumpImpl(pw); 1449 } 1450 }; 1451 1452 public final class LocalService { 1453 public void setDeviceIdleUserWhitelist(int[] appids) { 1454 setDeviceIdleUserWhitelistImpl(appids); 1455 } 1456 } 1457 1458 void dumpImpl(PrintWriter pw) { 1459 synchronized (mLock) { 1460 pw.println("Current Alarm Manager state:"); 1461 mConstants.dump(pw); 1462 pw.println(); 1463 1464 final long nowRTC = System.currentTimeMillis(); 1465 final long nowELAPSED = SystemClock.elapsedRealtime(); 1466 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 1467 1468 pw.print(" nowRTC="); pw.print(nowRTC); 1469 pw.print("="); pw.print(sdf.format(new Date(nowRTC))); 1470 pw.print(" nowELAPSED="); pw.print(nowELAPSED); 1471 pw.println(); 1472 pw.print(" mLastTimeChangeClockTime="); pw.print(mLastTimeChangeClockTime); 1473 pw.print("="); pw.println(sdf.format(new Date(mLastTimeChangeClockTime))); 1474 pw.print(" mLastTimeChangeRealtime="); 1475 TimeUtils.formatDuration(mLastTimeChangeRealtime, pw); 1476 pw.println(); 1477 if (!mInteractive) { 1478 pw.print(" Time since non-interactive: "); 1479 TimeUtils.formatDuration(nowELAPSED - mNonInteractiveStartTime, pw); 1480 pw.println(); 1481 pw.print(" Max wakeup delay: "); 1482 TimeUtils.formatDuration(currentNonWakeupFuzzLocked(nowELAPSED), pw); 1483 pw.println(); 1484 pw.print(" Time since last dispatch: "); 1485 TimeUtils.formatDuration(nowELAPSED - mLastAlarmDeliveryTime, pw); 1486 pw.println(); 1487 pw.print(" Next non-wakeup delivery time: "); 1488 TimeUtils.formatDuration(nowELAPSED - mNextNonWakeupDeliveryTime, pw); 1489 pw.println(); 1490 } 1491 1492 long nextWakeupRTC = mNextWakeup + (nowRTC - nowELAPSED); 1493 long nextNonWakeupRTC = mNextNonWakeup + (nowRTC - nowELAPSED); 1494 pw.print(" Next non-wakeup alarm: "); 1495 TimeUtils.formatDuration(mNextNonWakeup, nowELAPSED, pw); 1496 pw.print(" = "); pw.println(sdf.format(new Date(nextNonWakeupRTC))); 1497 pw.print(" Next wakeup: "); TimeUtils.formatDuration(mNextWakeup, nowELAPSED, pw); 1498 pw.print(" = "); pw.println(sdf.format(new Date(nextWakeupRTC))); 1499 pw.print(" Last wakeup: "); TimeUtils.formatDuration(mLastWakeup, nowELAPSED, pw); 1500 pw.print(" set at "); TimeUtils.formatDuration(mLastWakeupSet, nowELAPSED, pw); 1501 pw.println(); 1502 pw.print(" Num time change events: "); pw.println(mNumTimeChanged); 1503 pw.println(" mDeviceIdleUserWhitelist=" + Arrays.toString(mDeviceIdleUserWhitelist)); 1504 1505 pw.println(); 1506 pw.println(" Next alarm clock information: "); 1507 final TreeSet<Integer> users = new TreeSet<>(); 1508 for (int i = 0; i < mNextAlarmClockForUser.size(); i++) { 1509 users.add(mNextAlarmClockForUser.keyAt(i)); 1510 } 1511 for (int i = 0; i < mPendingSendNextAlarmClockChangedForUser.size(); i++) { 1512 users.add(mPendingSendNextAlarmClockChangedForUser.keyAt(i)); 1513 } 1514 for (int user : users) { 1515 final AlarmManager.AlarmClockInfo next = mNextAlarmClockForUser.get(user); 1516 final long time = next != null ? next.getTriggerTime() : 0; 1517 final boolean pendingSend = mPendingSendNextAlarmClockChangedForUser.get(user); 1518 pw.print(" user:"); pw.print(user); 1519 pw.print(" pendingSend:"); pw.print(pendingSend); 1520 pw.print(" time:"); pw.print(time); 1521 if (time > 0) { 1522 pw.print(" = "); pw.print(sdf.format(new Date(time))); 1523 pw.print(" = "); TimeUtils.formatDuration(time, nowRTC, pw); 1524 } 1525 pw.println(); 1526 } 1527 if (mAlarmBatches.size() > 0) { 1528 pw.println(); 1529 pw.print(" Pending alarm batches: "); 1530 pw.println(mAlarmBatches.size()); 1531 for (Batch b : mAlarmBatches) { 1532 pw.print(b); pw.println(':'); 1533 dumpAlarmList(pw, b.alarms, " ", nowELAPSED, nowRTC, sdf); 1534 } 1535 } 1536 if (mPendingIdleUntil != null || mPendingWhileIdleAlarms.size() > 0) { 1537 pw.println(); 1538 pw.println(" Idle mode state:"); 1539 pw.print(" Idling until: "); 1540 if (mPendingIdleUntil != null) { 1541 pw.println(mPendingIdleUntil); 1542 mPendingIdleUntil.dump(pw, " ", nowRTC, nowELAPSED, sdf); 1543 } else { 1544 pw.println("null"); 1545 } 1546 pw.println(" Pending alarms:"); 1547 dumpAlarmList(pw, mPendingWhileIdleAlarms, " ", nowELAPSED, nowRTC, sdf); 1548 } 1549 if (mNextWakeFromIdle != null) { 1550 pw.println(); 1551 pw.print(" Next wake from idle: "); pw.println(mNextWakeFromIdle); 1552 mNextWakeFromIdle.dump(pw, " ", nowRTC, nowELAPSED, sdf); 1553 } 1554 1555 pw.println(); 1556 pw.print(" Past-due non-wakeup alarms: "); 1557 if (mPendingNonWakeupAlarms.size() > 0) { 1558 pw.println(mPendingNonWakeupAlarms.size()); 1559 dumpAlarmList(pw, mPendingNonWakeupAlarms, " ", nowELAPSED, nowRTC, sdf); 1560 } else { 1561 pw.println("(none)"); 1562 } 1563 pw.print(" Number of delayed alarms: "); pw.print(mNumDelayedAlarms); 1564 pw.print(", total delay time: "); TimeUtils.formatDuration(mTotalDelayTime, pw); 1565 pw.println(); 1566 pw.print(" Max delay time: "); TimeUtils.formatDuration(mMaxDelayTime, pw); 1567 pw.print(", max non-interactive time: "); 1568 TimeUtils.formatDuration(mNonInteractiveTime, pw); 1569 pw.println(); 1570 1571 pw.println(); 1572 pw.print(" Broadcast ref count: "); pw.println(mBroadcastRefCount); 1573 pw.print(" PendingIntent send count: "); pw.println(mSendCount); 1574 pw.print(" PendingIntent finish count: "); pw.println(mSendFinishCount); 1575 pw.print(" Listener send count: "); pw.println(mListenerCount); 1576 pw.print(" Listener finish count: "); pw.println(mListenerFinishCount); 1577 pw.println(); 1578 1579 if (mInFlight.size() > 0) { 1580 pw.println("Outstanding deliveries:"); 1581 for (int i = 0; i < mInFlight.size(); i++) { 1582 pw.print(" #"); pw.print(i); pw.print(": "); 1583 pw.println(mInFlight.get(i)); 1584 } 1585 pw.println(); 1586 } 1587 1588 pw.print(" mAllowWhileIdleMinTime="); 1589 TimeUtils.formatDuration(mAllowWhileIdleMinTime, pw); 1590 pw.println(); 1591 if (mLastAllowWhileIdleDispatch.size() > 0) { 1592 pw.println(" Last allow while idle dispatch times:"); 1593 for (int i=0; i<mLastAllowWhileIdleDispatch.size(); i++) { 1594 pw.print(" UID "); 1595 UserHandle.formatUid(pw, mLastAllowWhileIdleDispatch.keyAt(i)); 1596 pw.print(": "); 1597 TimeUtils.formatDuration(mLastAllowWhileIdleDispatch.valueAt(i), 1598 nowELAPSED, pw); 1599 pw.println(); 1600 } 1601 } 1602 pw.println(); 1603 1604 if (mLog.dump(pw, " Recent problems", " ")) { 1605 pw.println(); 1606 } 1607 1608 final FilterStats[] topFilters = new FilterStats[10]; 1609 final Comparator<FilterStats> comparator = new Comparator<FilterStats>() { 1610 @Override 1611 public int compare(FilterStats lhs, FilterStats rhs) { 1612 if (lhs.aggregateTime < rhs.aggregateTime) { 1613 return 1; 1614 } else if (lhs.aggregateTime > rhs.aggregateTime) { 1615 return -1; 1616 } 1617 return 0; 1618 } 1619 }; 1620 int len = 0; 1621 for (int iu=0; iu<mBroadcastStats.size(); iu++) { 1622 ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(iu); 1623 for (int ip=0; ip<uidStats.size(); ip++) { 1624 BroadcastStats bs = uidStats.valueAt(ip); 1625 for (int is=0; is<bs.filterStats.size(); is++) { 1626 FilterStats fs = bs.filterStats.valueAt(is); 1627 int pos = len > 0 1628 ? Arrays.binarySearch(topFilters, 0, len, fs, comparator) : 0; 1629 if (pos < 0) { 1630 pos = -pos - 1; 1631 } 1632 if (pos < topFilters.length) { 1633 int copylen = topFilters.length - pos - 1; 1634 if (copylen > 0) { 1635 System.arraycopy(topFilters, pos, topFilters, pos+1, copylen); 1636 } 1637 topFilters[pos] = fs; 1638 if (len < topFilters.length) { 1639 len++; 1640 } 1641 } 1642 } 1643 } 1644 } 1645 if (len > 0) { 1646 pw.println(" Top Alarms:"); 1647 for (int i=0; i<len; i++) { 1648 FilterStats fs = topFilters[i]; 1649 pw.print(" "); 1650 if (fs.nesting > 0) pw.print("*ACTIVE* "); 1651 TimeUtils.formatDuration(fs.aggregateTime, pw); 1652 pw.print(" running, "); pw.print(fs.numWakeup); 1653 pw.print(" wakeups, "); pw.print(fs.count); 1654 pw.print(" alarms: "); UserHandle.formatUid(pw, fs.mBroadcastStats.mUid); 1655 pw.print(":"); pw.print(fs.mBroadcastStats.mPackageName); 1656 pw.println(); 1657 pw.print(" "); pw.print(fs.mTag); 1658 pw.println(); 1659 } 1660 } 1661 1662 pw.println(" "); 1663 pw.println(" Alarm Stats:"); 1664 final ArrayList<FilterStats> tmpFilters = new ArrayList<FilterStats>(); 1665 for (int iu=0; iu<mBroadcastStats.size(); iu++) { 1666 ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(iu); 1667 for (int ip=0; ip<uidStats.size(); ip++) { 1668 BroadcastStats bs = uidStats.valueAt(ip); 1669 pw.print(" "); 1670 if (bs.nesting > 0) pw.print("*ACTIVE* "); 1671 UserHandle.formatUid(pw, bs.mUid); 1672 pw.print(":"); 1673 pw.print(bs.mPackageName); 1674 pw.print(" "); TimeUtils.formatDuration(bs.aggregateTime, pw); 1675 pw.print(" running, "); pw.print(bs.numWakeup); 1676 pw.println(" wakeups:"); 1677 tmpFilters.clear(); 1678 for (int is=0; is<bs.filterStats.size(); is++) { 1679 tmpFilters.add(bs.filterStats.valueAt(is)); 1680 } 1681 Collections.sort(tmpFilters, comparator); 1682 for (int i=0; i<tmpFilters.size(); i++) { 1683 FilterStats fs = tmpFilters.get(i); 1684 pw.print(" "); 1685 if (fs.nesting > 0) pw.print("*ACTIVE* "); 1686 TimeUtils.formatDuration(fs.aggregateTime, pw); 1687 pw.print(" "); pw.print(fs.numWakeup); 1688 pw.print(" wakes " ); pw.print(fs.count); 1689 pw.print(" alarms, last "); 1690 TimeUtils.formatDuration(fs.lastTime, nowELAPSED, pw); 1691 pw.println(":"); 1692 pw.print(" "); 1693 pw.print(fs.mTag); 1694 pw.println(); 1695 } 1696 } 1697 } 1698 1699 if (RECORD_DEVICE_IDLE_ALARMS) { 1700 pw.println(); 1701 pw.println(" Allow while idle dispatches:"); 1702 for (int i = 0; i < mAllowWhileIdleDispatches.size(); i++) { 1703 IdleDispatchEntry ent = mAllowWhileIdleDispatches.get(i); 1704 pw.print(" "); 1705 TimeUtils.formatDuration(ent.elapsedRealtime, nowELAPSED, pw); 1706 pw.print(": "); 1707 UserHandle.formatUid(pw, ent.uid); 1708 pw.print(":"); 1709 pw.println(ent.pkg); 1710 if (ent.op != null) { 1711 pw.print(" "); 1712 pw.print(ent.op); 1713 pw.print(" / "); 1714 pw.print(ent.tag); 1715 if (ent.argRealtime != 0) { 1716 pw.print(" ("); 1717 TimeUtils.formatDuration(ent.argRealtime, nowELAPSED, pw); 1718 pw.print(")"); 1719 } 1720 pw.println(); 1721 } 1722 } 1723 } 1724 1725 if (WAKEUP_STATS) { 1726 pw.println(); 1727 pw.println(" Recent Wakeup History:"); 1728 long last = -1; 1729 for (WakeupEvent event : mRecentWakeups) { 1730 pw.print(" "); pw.print(sdf.format(new Date(event.when))); 1731 pw.print('|'); 1732 if (last < 0) { 1733 pw.print('0'); 1734 } else { 1735 pw.print(event.when - last); 1736 } 1737 last = event.when; 1738 pw.print('|'); pw.print(event.uid); 1739 pw.print('|'); pw.print(event.action); 1740 pw.println(); 1741 } 1742 pw.println(); 1743 } 1744 } 1745 } 1746 1747 private void logBatchesLocked(SimpleDateFormat sdf) { 1748 ByteArrayOutputStream bs = new ByteArrayOutputStream(2048); 1749 PrintWriter pw = new PrintWriter(bs); 1750 final long nowRTC = System.currentTimeMillis(); 1751 final long nowELAPSED = SystemClock.elapsedRealtime(); 1752 final int NZ = mAlarmBatches.size(); 1753 for (int iz = 0; iz < NZ; iz++) { 1754 Batch bz = mAlarmBatches.get(iz); 1755 pw.append("Batch "); pw.print(iz); pw.append(": "); pw.println(bz); 1756 dumpAlarmList(pw, bz.alarms, " ", nowELAPSED, nowRTC, sdf); 1757 pw.flush(); 1758 Slog.v(TAG, bs.toString()); 1759 bs.reset(); 1760 } 1761 } 1762 1763 private boolean validateConsistencyLocked() { 1764 if (DEBUG_VALIDATE) { 1765 long lastTime = Long.MIN_VALUE; 1766 final int N = mAlarmBatches.size(); 1767 for (int i = 0; i < N; i++) { 1768 Batch b = mAlarmBatches.get(i); 1769 if (b.start >= lastTime) { 1770 // duplicate start times are okay because of standalone batches 1771 lastTime = b.start; 1772 } else { 1773 Slog.e(TAG, "CONSISTENCY FAILURE: Batch " + i + " is out of order"); 1774 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 1775 logBatchesLocked(sdf); 1776 return false; 1777 } 1778 } 1779 } 1780 return true; 1781 } 1782 1783 private Batch findFirstWakeupBatchLocked() { 1784 final int N = mAlarmBatches.size(); 1785 for (int i = 0; i < N; i++) { 1786 Batch b = mAlarmBatches.get(i); 1787 if (b.hasWakeups()) { 1788 return b; 1789 } 1790 } 1791 return null; 1792 } 1793 1794 long getNextWakeFromIdleTimeImpl() { 1795 synchronized (mLock) { 1796 return mNextWakeFromIdle != null ? mNextWakeFromIdle.whenElapsed : Long.MAX_VALUE; 1797 } 1798 } 1799 1800 void setDeviceIdleUserWhitelistImpl(int[] appids) { 1801 synchronized (mLock) { 1802 mDeviceIdleUserWhitelist = appids; 1803 } 1804 } 1805 1806 AlarmManager.AlarmClockInfo getNextAlarmClockImpl(int userId) { 1807 synchronized (mLock) { 1808 return mNextAlarmClockForUser.get(userId); 1809 } 1810 } 1811 1812 /** 1813 * Recomputes the next alarm clock for all users. 1814 */ 1815 private void updateNextAlarmClockLocked() { 1816 if (!mNextAlarmClockMayChange) { 1817 return; 1818 } 1819 mNextAlarmClockMayChange = false; 1820 1821 SparseArray<AlarmManager.AlarmClockInfo> nextForUser = mTmpSparseAlarmClockArray; 1822 nextForUser.clear(); 1823 1824 final int N = mAlarmBatches.size(); 1825 for (int i = 0; i < N; i++) { 1826 ArrayList<Alarm> alarms = mAlarmBatches.get(i).alarms; 1827 final int M = alarms.size(); 1828 1829 for (int j = 0; j < M; j++) { 1830 Alarm a = alarms.get(j); 1831 if (a.alarmClock != null) { 1832 final int userId = UserHandle.getUserId(a.uid); 1833 AlarmManager.AlarmClockInfo current = mNextAlarmClockForUser.get(userId); 1834 1835 if (DEBUG_ALARM_CLOCK) { 1836 Log.v(TAG, "Found AlarmClockInfo " + a.alarmClock + " at " + 1837 formatNextAlarm(getContext(), a.alarmClock, userId) + 1838 " for user " + userId); 1839 } 1840 1841 // Alarms and batches are sorted by time, no need to compare times here. 1842 if (nextForUser.get(userId) == null) { 1843 nextForUser.put(userId, a.alarmClock); 1844 } else if (a.alarmClock.equals(current) 1845 && current.getTriggerTime() <= nextForUser.get(userId).getTriggerTime()) { 1846 // same/earlier time and it's the one we cited before, so stick with it 1847 nextForUser.put(userId, current); 1848 } 1849 } 1850 } 1851 } 1852 1853 // Update mNextAlarmForUser with new values. 1854 final int NN = nextForUser.size(); 1855 for (int i = 0; i < NN; i++) { 1856 AlarmManager.AlarmClockInfo newAlarm = nextForUser.valueAt(i); 1857 int userId = nextForUser.keyAt(i); 1858 AlarmManager.AlarmClockInfo currentAlarm = mNextAlarmClockForUser.get(userId); 1859 if (!newAlarm.equals(currentAlarm)) { 1860 updateNextAlarmInfoForUserLocked(userId, newAlarm); 1861 } 1862 } 1863 1864 // Remove users without any alarm clocks scheduled. 1865 final int NNN = mNextAlarmClockForUser.size(); 1866 for (int i = NNN - 1; i >= 0; i--) { 1867 int userId = mNextAlarmClockForUser.keyAt(i); 1868 if (nextForUser.get(userId) == null) { 1869 updateNextAlarmInfoForUserLocked(userId, null); 1870 } 1871 } 1872 } 1873 1874 private void updateNextAlarmInfoForUserLocked(int userId, 1875 AlarmManager.AlarmClockInfo alarmClock) { 1876 if (alarmClock != null) { 1877 if (DEBUG_ALARM_CLOCK) { 1878 Log.v(TAG, "Next AlarmClockInfoForUser(" + userId + "): " + 1879 formatNextAlarm(getContext(), alarmClock, userId)); 1880 } 1881 mNextAlarmClockForUser.put(userId, alarmClock); 1882 } else { 1883 if (DEBUG_ALARM_CLOCK) { 1884 Log.v(TAG, "Next AlarmClockInfoForUser(" + userId + "): None"); 1885 } 1886 mNextAlarmClockForUser.remove(userId); 1887 } 1888 1889 mPendingSendNextAlarmClockChangedForUser.put(userId, true); 1890 mHandler.removeMessages(AlarmHandler.SEND_NEXT_ALARM_CLOCK_CHANGED); 1891 mHandler.sendEmptyMessage(AlarmHandler.SEND_NEXT_ALARM_CLOCK_CHANGED); 1892 } 1893 1894 /** 1895 * Updates NEXT_ALARM_FORMATTED and sends NEXT_ALARM_CLOCK_CHANGED_INTENT for all users 1896 * for which alarm clocks have changed since the last call to this. 1897 * 1898 * Do not call with a lock held. Only call from mHandler's thread. 1899 * 1900 * @see AlarmHandler#SEND_NEXT_ALARM_CLOCK_CHANGED 1901 */ 1902 private void sendNextAlarmClockChanged() { 1903 SparseArray<AlarmManager.AlarmClockInfo> pendingUsers = mHandlerSparseAlarmClockArray; 1904 pendingUsers.clear(); 1905 1906 synchronized (mLock) { 1907 final int N = mPendingSendNextAlarmClockChangedForUser.size(); 1908 for (int i = 0; i < N; i++) { 1909 int userId = mPendingSendNextAlarmClockChangedForUser.keyAt(i); 1910 pendingUsers.append(userId, mNextAlarmClockForUser.get(userId)); 1911 } 1912 mPendingSendNextAlarmClockChangedForUser.clear(); 1913 } 1914 1915 final int N = pendingUsers.size(); 1916 for (int i = 0; i < N; i++) { 1917 int userId = pendingUsers.keyAt(i); 1918 AlarmManager.AlarmClockInfo alarmClock = pendingUsers.valueAt(i); 1919 Settings.System.putStringForUser(getContext().getContentResolver(), 1920 Settings.System.NEXT_ALARM_FORMATTED, 1921 formatNextAlarm(getContext(), alarmClock, userId), 1922 userId); 1923 1924 getContext().sendBroadcastAsUser(NEXT_ALARM_CLOCK_CHANGED_INTENT, 1925 new UserHandle(userId)); 1926 } 1927 } 1928 1929 /** 1930 * Formats an alarm like platform/packages/apps/DeskClock used to. 1931 */ 1932 private static String formatNextAlarm(final Context context, AlarmManager.AlarmClockInfo info, 1933 int userId) { 1934 String skeleton = DateFormat.is24HourFormat(context, userId) ? "EHm" : "Ehma"; 1935 String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton); 1936 return (info == null) ? "" : 1937 DateFormat.format(pattern, info.getTriggerTime()).toString(); 1938 } 1939 1940 void rescheduleKernelAlarmsLocked() { 1941 // Schedule the next upcoming wakeup alarm. If there is a deliverable batch 1942 // prior to that which contains no wakeups, we schedule that as well. 1943 long nextNonWakeup = 0; 1944 if (mAlarmBatches.size() > 0) { 1945 final Batch firstWakeup = findFirstWakeupBatchLocked(); 1946 final Batch firstBatch = mAlarmBatches.get(0); 1947 if (firstWakeup != null && mNextWakeup != firstWakeup.start) { 1948 mNextWakeup = firstWakeup.start; 1949 mLastWakeupSet = SystemClock.elapsedRealtime(); 1950 setLocked(ELAPSED_REALTIME_WAKEUP, firstWakeup.start); 1951 } 1952 if (firstBatch != firstWakeup) { 1953 nextNonWakeup = firstBatch.start; 1954 } 1955 } 1956 if (mPendingNonWakeupAlarms.size() > 0) { 1957 if (nextNonWakeup == 0 || mNextNonWakeupDeliveryTime < nextNonWakeup) { 1958 nextNonWakeup = mNextNonWakeupDeliveryTime; 1959 } 1960 } 1961 if (nextNonWakeup != 0 && mNextNonWakeup != nextNonWakeup) { 1962 mNextNonWakeup = nextNonWakeup; 1963 setLocked(ELAPSED_REALTIME, nextNonWakeup); 1964 } 1965 } 1966 1967 private void removeLocked(PendingIntent operation, IAlarmListener directReceiver) { 1968 boolean didRemove = false; 1969 for (int i = mAlarmBatches.size() - 1; i >= 0; i--) { 1970 Batch b = mAlarmBatches.get(i); 1971 didRemove |= b.remove(operation, directReceiver); 1972 if (b.size() == 0) { 1973 mAlarmBatches.remove(i); 1974 } 1975 } 1976 for (int i = mPendingWhileIdleAlarms.size() - 1; i >= 0; i--) { 1977 if (mPendingWhileIdleAlarms.get(i).matches(operation, directReceiver)) { 1978 // Don't set didRemove, since this doesn't impact the scheduled alarms. 1979 mPendingWhileIdleAlarms.remove(i); 1980 } 1981 } 1982 1983 if (didRemove) { 1984 if (DEBUG_BATCH) { 1985 Slog.v(TAG, "remove(operation) changed bounds; rebatching"); 1986 } 1987 boolean restorePending = false; 1988 if (mPendingIdleUntil != null && mPendingIdleUntil.matches(operation, directReceiver)) { 1989 mPendingIdleUntil = null; 1990 restorePending = true; 1991 } 1992 if (mNextWakeFromIdle != null && mNextWakeFromIdle.matches(operation, directReceiver)) { 1993 mNextWakeFromIdle = null; 1994 } 1995 rebatchAllAlarmsLocked(true); 1996 if (restorePending) { 1997 restorePendingWhileIdleAlarmsLocked(); 1998 } 1999 updateNextAlarmClockLocked(); 2000 } 2001 } 2002 2003 void removeLocked(String packageName) { 2004 boolean didRemove = false; 2005 for (int i = mAlarmBatches.size() - 1; i >= 0; i--) { 2006 Batch b = mAlarmBatches.get(i); 2007 didRemove |= b.remove(packageName); 2008 if (b.size() == 0) { 2009 mAlarmBatches.remove(i); 2010 } 2011 } 2012 for (int i = mPendingWhileIdleAlarms.size() - 1; i >= 0; i--) { 2013 final Alarm a = mPendingWhileIdleAlarms.get(i); 2014 if (a.matches(packageName)) { 2015 // Don't set didRemove, since this doesn't impact the scheduled alarms. 2016 mPendingWhileIdleAlarms.remove(i); 2017 } 2018 } 2019 2020 if (didRemove) { 2021 if (DEBUG_BATCH) { 2022 Slog.v(TAG, "remove(package) changed bounds; rebatching"); 2023 } 2024 rebatchAllAlarmsLocked(true); 2025 rescheduleKernelAlarmsLocked(); 2026 updateNextAlarmClockLocked(); 2027 } 2028 } 2029 2030 void removeForStoppedLocked(int uid) { 2031 boolean didRemove = false; 2032 for (int i = mAlarmBatches.size() - 1; i >= 0; i--) { 2033 Batch b = mAlarmBatches.get(i); 2034 didRemove |= b.removeForStopped(uid); 2035 if (b.size() == 0) { 2036 mAlarmBatches.remove(i); 2037 } 2038 } 2039 for (int i = mPendingWhileIdleAlarms.size() - 1; i >= 0; i--) { 2040 final Alarm a = mPendingWhileIdleAlarms.get(i); 2041 if (a.uid == uid) { 2042 // Don't set didRemove, since this doesn't impact the scheduled alarms. 2043 mPendingWhileIdleAlarms.remove(i); 2044 } 2045 } 2046 2047 if (didRemove) { 2048 if (DEBUG_BATCH) { 2049 Slog.v(TAG, "remove(package) changed bounds; rebatching"); 2050 } 2051 rebatchAllAlarmsLocked(true); 2052 rescheduleKernelAlarmsLocked(); 2053 updateNextAlarmClockLocked(); 2054 } 2055 } 2056 2057 void removeUserLocked(int userHandle) { 2058 boolean didRemove = false; 2059 for (int i = mAlarmBatches.size() - 1; i >= 0; i--) { 2060 Batch b = mAlarmBatches.get(i); 2061 didRemove |= b.remove(userHandle); 2062 if (b.size() == 0) { 2063 mAlarmBatches.remove(i); 2064 } 2065 } 2066 for (int i = mPendingWhileIdleAlarms.size() - 1; i >= 0; i--) { 2067 if (UserHandle.getUserId(mPendingWhileIdleAlarms.get(i).creatorUid) 2068 == userHandle) { 2069 // Don't set didRemove, since this doesn't impact the scheduled alarms. 2070 mPendingWhileIdleAlarms.remove(i); 2071 } 2072 } 2073 for (int i = mLastAllowWhileIdleDispatch.size() - 1; i >= 0; i--) { 2074 if (UserHandle.getUserId(mLastAllowWhileIdleDispatch.keyAt(i)) == userHandle) { 2075 mLastAllowWhileIdleDispatch.removeAt(i); 2076 } 2077 } 2078 2079 if (didRemove) { 2080 if (DEBUG_BATCH) { 2081 Slog.v(TAG, "remove(user) changed bounds; rebatching"); 2082 } 2083 rebatchAllAlarmsLocked(true); 2084 rescheduleKernelAlarmsLocked(); 2085 updateNextAlarmClockLocked(); 2086 } 2087 } 2088 2089 void interactiveStateChangedLocked(boolean interactive) { 2090 if (mInteractive != interactive) { 2091 mInteractive = interactive; 2092 final long nowELAPSED = SystemClock.elapsedRealtime(); 2093 if (interactive) { 2094 if (mPendingNonWakeupAlarms.size() > 0) { 2095 final long thisDelayTime = nowELAPSED - mStartCurrentDelayTime; 2096 mTotalDelayTime += thisDelayTime; 2097 if (mMaxDelayTime < thisDelayTime) { 2098 mMaxDelayTime = thisDelayTime; 2099 } 2100 deliverAlarmsLocked(mPendingNonWakeupAlarms, nowELAPSED); 2101 mPendingNonWakeupAlarms.clear(); 2102 } 2103 if (mNonInteractiveStartTime > 0) { 2104 long dur = nowELAPSED - mNonInteractiveStartTime; 2105 if (dur > mNonInteractiveTime) { 2106 mNonInteractiveTime = dur; 2107 } 2108 } 2109 } else { 2110 mNonInteractiveStartTime = nowELAPSED; 2111 } 2112 } 2113 } 2114 2115 boolean lookForPackageLocked(String packageName) { 2116 for (int i = 0; i < mAlarmBatches.size(); i++) { 2117 Batch b = mAlarmBatches.get(i); 2118 if (b.hasPackage(packageName)) { 2119 return true; 2120 } 2121 } 2122 for (int i = 0; i < mPendingWhileIdleAlarms.size(); i++) { 2123 final Alarm a = mPendingWhileIdleAlarms.get(i); 2124 if (a.matches(packageName)) { 2125 return true; 2126 } 2127 } 2128 return false; 2129 } 2130 2131 private void setLocked(int type, long when) { 2132 if (mNativeData != 0) { 2133 // The kernel never triggers alarms with negative wakeup times 2134 // so we ensure they are positive. 2135 long alarmSeconds, alarmNanoseconds; 2136 if (when < 0) { 2137 alarmSeconds = 0; 2138 alarmNanoseconds = 0; 2139 } else { 2140 alarmSeconds = when / 1000; 2141 alarmNanoseconds = (when % 1000) * 1000 * 1000; 2142 } 2143 2144 set(mNativeData, type, alarmSeconds, alarmNanoseconds); 2145 } else { 2146 Message msg = Message.obtain(); 2147 msg.what = ALARM_EVENT; 2148 2149 mHandler.removeMessages(ALARM_EVENT); 2150 mHandler.sendMessageAtTime(msg, when); 2151 } 2152 } 2153 2154 private static final void dumpAlarmList(PrintWriter pw, ArrayList<Alarm> list, 2155 String prefix, String label, long nowRTC, long nowELAPSED, SimpleDateFormat sdf) { 2156 for (int i=list.size()-1; i>=0; i--) { 2157 Alarm a = list.get(i); 2158 pw.print(prefix); pw.print(label); pw.print(" #"); pw.print(i); 2159 pw.print(": "); pw.println(a); 2160 a.dump(pw, prefix + " ", nowRTC, nowELAPSED, sdf); 2161 } 2162 } 2163 2164 private static final String labelForType(int type) { 2165 switch (type) { 2166 case RTC: return "RTC"; 2167 case RTC_WAKEUP : return "RTC_WAKEUP"; 2168 case ELAPSED_REALTIME : return "ELAPSED"; 2169 case ELAPSED_REALTIME_WAKEUP: return "ELAPSED_WAKEUP"; 2170 default: 2171 break; 2172 } 2173 return "--unknown--"; 2174 } 2175 2176 private static final void dumpAlarmList(PrintWriter pw, ArrayList<Alarm> list, 2177 String prefix, long nowELAPSED, long nowRTC, SimpleDateFormat sdf) { 2178 for (int i=list.size()-1; i>=0; i--) { 2179 Alarm a = list.get(i); 2180 final String label = labelForType(a.type); 2181 pw.print(prefix); pw.print(label); pw.print(" #"); pw.print(i); 2182 pw.print(": "); pw.println(a); 2183 a.dump(pw, prefix + " ", nowRTC, nowELAPSED, sdf); 2184 } 2185 } 2186 2187 private native long init(); 2188 private native void close(long nativeData); 2189 private native void set(long nativeData, int type, long seconds, long nanoseconds); 2190 private native int waitForAlarm(long nativeData); 2191 private native int setKernelTime(long nativeData, long millis); 2192 private native int setKernelTimezone(long nativeData, int minuteswest); 2193 2194 boolean triggerAlarmsLocked(ArrayList<Alarm> triggerList, final long nowELAPSED, 2195 final long nowRTC) { 2196 boolean hasWakeup = false; 2197 // batches are temporally sorted, so we need only pull from the 2198 // start of the list until we either empty it or hit a batch 2199 // that is not yet deliverable 2200 while (mAlarmBatches.size() > 0) { 2201 Batch batch = mAlarmBatches.get(0); 2202 if (batch.start > nowELAPSED) { 2203 // Everything else is scheduled for the future 2204 break; 2205 } 2206 2207 // We will (re)schedule some alarms now; don't let that interfere 2208 // with delivery of this current batch 2209 mAlarmBatches.remove(0); 2210 2211 final int N = batch.size(); 2212 for (int i = 0; i < N; i++) { 2213 Alarm alarm = batch.get(i); 2214 2215 if ((alarm.flags&AlarmManager.FLAG_ALLOW_WHILE_IDLE) != 0) { 2216 // If this is an ALLOW_WHILE_IDLE alarm, we constrain how frequently the app can 2217 // schedule such alarms. 2218 long lastTime = mLastAllowWhileIdleDispatch.get(alarm.uid, 0); 2219 long minTime = lastTime + mAllowWhileIdleMinTime; 2220 if (nowELAPSED < minTime) { 2221 // Whoops, it hasn't been long enough since the last ALLOW_WHILE_IDLE 2222 // alarm went off for this app. Reschedule the alarm to be in the 2223 // correct time period. 2224 alarm.whenElapsed = minTime; 2225 if (alarm.maxWhenElapsed < minTime) { 2226 alarm.maxWhenElapsed = minTime; 2227 } 2228 if (RECORD_DEVICE_IDLE_ALARMS) { 2229 IdleDispatchEntry ent = new IdleDispatchEntry(); 2230 ent.uid = alarm.uid; 2231 ent.pkg = alarm.operation.getCreatorPackage(); 2232 ent.tag = alarm.operation.getTag(""); 2233 ent.op = "RESCHEDULE"; 2234 ent.elapsedRealtime = nowELAPSED; 2235 ent.argRealtime = lastTime; 2236 mAllowWhileIdleDispatches.add(ent); 2237 } 2238 setImplLocked(alarm, true, false); 2239 continue; 2240 } 2241 } 2242 2243 alarm.count = 1; 2244 triggerList.add(alarm); 2245 if ((alarm.flags&AlarmManager.FLAG_WAKE_FROM_IDLE) != 0) { 2246 EventLogTags.writeDeviceIdleWakeFromIdle(mPendingIdleUntil != null ? 1 : 0, 2247 alarm.statsTag); 2248 } 2249 if (mPendingIdleUntil == alarm) { 2250 mPendingIdleUntil = null; 2251 rebatchAllAlarmsLocked(false); 2252 restorePendingWhileIdleAlarmsLocked(); 2253 } 2254 if (mNextWakeFromIdle == alarm) { 2255 mNextWakeFromIdle = null; 2256 rebatchAllAlarmsLocked(false); 2257 } 2258 2259 // Recurring alarms may have passed several alarm intervals while the 2260 // phone was asleep or off, so pass a trigger count when sending them. 2261 if (alarm.repeatInterval > 0) { 2262 // this adjustment will be zero if we're late by 2263 // less than one full repeat interval 2264 alarm.count += (nowELAPSED - alarm.whenElapsed) / alarm.repeatInterval; 2265 2266 // Also schedule its next recurrence 2267 final long delta = alarm.count * alarm.repeatInterval; 2268 final long nextElapsed = alarm.whenElapsed + delta; 2269 setImplLocked(alarm.type, alarm.when + delta, nextElapsed, alarm.windowLength, 2270 maxTriggerTime(nowELAPSED, nextElapsed, alarm.repeatInterval), 2271 alarm.repeatInterval, alarm.operation, null, null, alarm.flags, true, 2272 alarm.workSource, alarm.alarmClock, alarm.uid, alarm.packageName); 2273 } 2274 2275 if (alarm.wakeup) { 2276 hasWakeup = true; 2277 } 2278 2279 // We removed an alarm clock. Let the caller recompute the next alarm clock. 2280 if (alarm.alarmClock != null) { 2281 mNextAlarmClockMayChange = true; 2282 } 2283 } 2284 } 2285 2286 // This is a new alarm delivery set; bump the sequence number to indicate that 2287 // all apps' alarm delivery classes should be recalculated. 2288 mCurrentSeq++; 2289 calculateDeliveryPriorities(triggerList); 2290 Collections.sort(triggerList, mAlarmDispatchComparator); 2291 2292 if (localLOGV) { 2293 for (int i=0; i<triggerList.size(); i++) { 2294 Slog.v(TAG, "Triggering alarm #" + i + ": " + triggerList.get(i)); 2295 } 2296 } 2297 2298 return hasWakeup; 2299 } 2300 2301 /** 2302 * This Comparator sorts Alarms into increasing time order. 2303 */ 2304 public static class IncreasingTimeOrder implements Comparator<Alarm> { 2305 public int compare(Alarm a1, Alarm a2) { 2306 long when1 = a1.whenElapsed; 2307 long when2 = a2.whenElapsed; 2308 if (when1 > when2) { 2309 return 1; 2310 } 2311 if (when1 < when2) { 2312 return -1; 2313 } 2314 return 0; 2315 } 2316 } 2317 2318 private static class Alarm { 2319 public final int type; 2320 public final long origWhen; 2321 public final boolean wakeup; 2322 public final PendingIntent operation; 2323 public final IAlarmListener listener; 2324 public final String listenerTag; 2325 public final String statsTag; 2326 public final WorkSource workSource; 2327 public final int flags; 2328 public final AlarmManager.AlarmClockInfo alarmClock; 2329 public final int uid; 2330 public final int creatorUid; 2331 public final String packageName; 2332 public int count; 2333 public long when; 2334 public long windowLength; 2335 public long whenElapsed; // 'when' in the elapsed time base 2336 public long maxWhenElapsed; // also in the elapsed time base 2337 public long repeatInterval; 2338 public PriorityClass priorityClass; 2339 2340 public Alarm(int _type, long _when, long _whenElapsed, long _windowLength, long _maxWhen, 2341 long _interval, PendingIntent _op, IAlarmListener _rec, String _listenerTag, 2342 WorkSource _ws, int _flags, AlarmManager.AlarmClockInfo _info, 2343 int _uid, String _pkgName) { 2344 type = _type; 2345 origWhen = _when; 2346 wakeup = _type == AlarmManager.ELAPSED_REALTIME_WAKEUP 2347 || _type == AlarmManager.RTC_WAKEUP; 2348 when = _when; 2349 whenElapsed = _whenElapsed; 2350 windowLength = _windowLength; 2351 maxWhenElapsed = _maxWhen; 2352 repeatInterval = _interval; 2353 operation = _op; 2354 listener = _rec; 2355 listenerTag = _listenerTag; 2356 statsTag = makeTag(_op, _listenerTag, _type); 2357 workSource = _ws; 2358 flags = _flags; 2359 alarmClock = _info; 2360 uid = _uid; 2361 packageName = _pkgName; 2362 2363 creatorUid = (operation != null) ? operation.getCreatorUid() : uid; 2364 } 2365 2366 public static String makeTag(PendingIntent pi, String tag, int type) { 2367 final String alarmString = type == ELAPSED_REALTIME_WAKEUP || type == RTC_WAKEUP 2368 ? "*walarm*:" : "*alarm*:"; 2369 return (pi != null) ? pi.getTag(alarmString) : (alarmString + tag); 2370 } 2371 2372 public WakeupEvent makeWakeupEvent(long nowRTC) { 2373 return new WakeupEvent(nowRTC, creatorUid, 2374 (operation != null) 2375 ? operation.getIntent().getAction() 2376 : ("<listener>:" + listenerTag)); 2377 } 2378 2379 // Returns true if either matches 2380 public boolean matches(PendingIntent pi, IAlarmListener rec) { 2381 return (operation != null) 2382 ? operation.equals(pi) 2383 : rec != null && listener.asBinder().equals(rec.asBinder()); 2384 } 2385 2386 public boolean matches(String packageName) { 2387 return (operation != null) 2388 ? packageName.equals(operation.getTargetPackage()) 2389 : packageName.equals(this.packageName); 2390 } 2391 2392 @Override 2393 public String toString() { 2394 StringBuilder sb = new StringBuilder(128); 2395 sb.append("Alarm{"); 2396 sb.append(Integer.toHexString(System.identityHashCode(this))); 2397 sb.append(" type "); 2398 sb.append(type); 2399 sb.append(" when "); 2400 sb.append(when); 2401 sb.append(" "); 2402 if (operation != null) { 2403 sb.append(operation.getTargetPackage()); 2404 } else { 2405 sb.append(packageName); 2406 } 2407 sb.append('}'); 2408 return sb.toString(); 2409 } 2410 2411 public void dump(PrintWriter pw, String prefix, long nowRTC, long nowELAPSED, 2412 SimpleDateFormat sdf) { 2413 final boolean isRtc = (type == RTC || type == RTC_WAKEUP); 2414 pw.print(prefix); pw.print("tag="); pw.println(statsTag); 2415 pw.print(prefix); pw.print("type="); pw.print(type); 2416 pw.print(" whenElapsed="); TimeUtils.formatDuration(whenElapsed, 2417 nowELAPSED, pw); 2418 pw.print(" when="); 2419 if (isRtc) { 2420 pw.print(sdf.format(new Date(when))); 2421 } else { 2422 TimeUtils.formatDuration(when, nowELAPSED, pw); 2423 } 2424 pw.println(); 2425 pw.print(prefix); pw.print("window="); TimeUtils.formatDuration(windowLength, pw); 2426 pw.print(" repeatInterval="); pw.print(repeatInterval); 2427 pw.print(" count="); pw.print(count); 2428 pw.print(" flags=0x"); pw.println(Integer.toHexString(flags)); 2429 if (alarmClock != null) { 2430 pw.print(prefix); pw.println("Alarm clock:"); 2431 pw.print(prefix); pw.print(" triggerTime="); 2432 pw.println(sdf.format(new Date(alarmClock.getTriggerTime()))); 2433 pw.print(prefix); pw.print(" showIntent="); pw.println(alarmClock.getShowIntent()); 2434 } 2435 pw.print(prefix); pw.print("operation="); pw.println(operation); 2436 if (listener != null) { 2437 pw.print(prefix); pw.print("listener="); pw.println(listener.asBinder()); 2438 } 2439 } 2440 } 2441 2442 void recordWakeupAlarms(ArrayList<Batch> batches, long nowELAPSED, long nowRTC) { 2443 final int numBatches = batches.size(); 2444 for (int nextBatch = 0; nextBatch < numBatches; nextBatch++) { 2445 Batch b = batches.get(nextBatch); 2446 if (b.start > nowELAPSED) { 2447 break; 2448 } 2449 2450 final int numAlarms = b.alarms.size(); 2451 for (int nextAlarm = 0; nextAlarm < numAlarms; nextAlarm++) { 2452 Alarm a = b.alarms.get(nextAlarm); 2453 mRecentWakeups.add(a.makeWakeupEvent(nowRTC)); 2454 } 2455 } 2456 } 2457 2458 long currentNonWakeupFuzzLocked(long nowELAPSED) { 2459 long timeSinceOn = nowELAPSED - mNonInteractiveStartTime; 2460 if (timeSinceOn < 5*60*1000) { 2461 // If the screen has been off for 5 minutes, only delay by at most two minutes. 2462 return 2*60*1000; 2463 } else if (timeSinceOn < 30*60*1000) { 2464 // If the screen has been off for 30 minutes, only delay by at most 15 minutes. 2465 return 15*60*1000; 2466 } else { 2467 // Otherwise, we will delay by at most an hour. 2468 return 60*60*1000; 2469 } 2470 } 2471 2472 static int fuzzForDuration(long duration) { 2473 if (duration < 15*60*1000) { 2474 // If the duration until the time is less than 15 minutes, the maximum fuzz 2475 // is the duration. 2476 return (int)duration; 2477 } else if (duration < 90*60*1000) { 2478 // If duration is less than 1 1/2 hours, the maximum fuzz is 15 minutes, 2479 return 15*60*1000; 2480 } else { 2481 // Otherwise, we will fuzz by at most half an hour. 2482 return 30*60*1000; 2483 } 2484 } 2485 2486 boolean checkAllowNonWakeupDelayLocked(long nowELAPSED) { 2487 if (mInteractive) { 2488 return false; 2489 } 2490 if (mLastAlarmDeliveryTime <= 0) { 2491 return false; 2492 } 2493 if (mPendingNonWakeupAlarms.size() > 0 && mNextNonWakeupDeliveryTime < nowELAPSED) { 2494 // This is just a little paranoia, if somehow we have pending non-wakeup alarms 2495 // and the next delivery time is in the past, then just deliver them all. This 2496 // avoids bugs where we get stuck in a loop trying to poll for alarms. 2497 return false; 2498 } 2499 long timeSinceLast = nowELAPSED - mLastAlarmDeliveryTime; 2500 return timeSinceLast <= currentNonWakeupFuzzLocked(nowELAPSED); 2501 } 2502 2503 void deliverAlarmsLocked(ArrayList<Alarm> triggerList, long nowELAPSED) { 2504 mLastAlarmDeliveryTime = nowELAPSED; 2505 for (int i=0; i<triggerList.size(); i++) { 2506 Alarm alarm = triggerList.get(i); 2507 final boolean allowWhileIdle = (alarm.flags&AlarmManager.FLAG_ALLOW_WHILE_IDLE) != 0; 2508 try { 2509 if (localLOGV) { 2510 Slog.v(TAG, "sending alarm " + alarm); 2511 } 2512 if (RECORD_ALARMS_IN_HISTORY) { 2513 if (alarm.workSource != null && alarm.workSource.size() > 0) { 2514 for (int wi=0; wi<alarm.workSource.size(); wi++) { 2515 ActivityManager.noteAlarmStart( 2516 alarm.operation, alarm.workSource.get(wi), alarm.statsTag); 2517 } 2518 } else { 2519 ActivityManager.noteAlarmStart( 2520 alarm.operation, alarm.uid, alarm.statsTag); 2521 } 2522 } 2523 mDeliveryTracker.deliverLocked(alarm, nowELAPSED, allowWhileIdle); 2524 } catch (RuntimeException e) { 2525 Slog.w(TAG, "Failure sending alarm.", e); 2526 } 2527 } 2528 } 2529 2530 private class AlarmThread extends Thread 2531 { 2532 public AlarmThread() 2533 { 2534 super("AlarmManager"); 2535 } 2536 2537 public void run() 2538 { 2539 ArrayList<Alarm> triggerList = new ArrayList<Alarm>(); 2540 2541 while (true) 2542 { 2543 int result = waitForAlarm(mNativeData); 2544 mLastWakeup = SystemClock.elapsedRealtime(); 2545 2546 triggerList.clear(); 2547 2548 final long nowRTC = System.currentTimeMillis(); 2549 final long nowELAPSED = SystemClock.elapsedRealtime(); 2550 2551 if ((result & TIME_CHANGED_MASK) != 0) { 2552 // The kernel can give us spurious time change notifications due to 2553 // small adjustments it makes internally; we want to filter those out. 2554 final long lastTimeChangeClockTime; 2555 final long expectedClockTime; 2556 synchronized (mLock) { 2557 lastTimeChangeClockTime = mLastTimeChangeClockTime; 2558 expectedClockTime = lastTimeChangeClockTime 2559 + (nowELAPSED - mLastTimeChangeRealtime); 2560 } 2561 if (lastTimeChangeClockTime == 0 || nowRTC < (expectedClockTime-1000) 2562 || nowRTC > (expectedClockTime+1000)) { 2563 // The change is by at least +/- 1000 ms (or this is the first change), 2564 // let's do it! 2565 if (DEBUG_BATCH) { 2566 Slog.v(TAG, "Time changed notification from kernel; rebatching"); 2567 } 2568 removeImpl(mTimeTickSender); 2569 removeImpl(mDateChangeSender); 2570 rebatchAllAlarms(); 2571 mClockReceiver.scheduleTimeTickEvent(); 2572 mClockReceiver.scheduleDateChangedEvent(); 2573 synchronized (mLock) { 2574 mNumTimeChanged++; 2575 mLastTimeChangeClockTime = nowRTC; 2576 mLastTimeChangeRealtime = nowELAPSED; 2577 } 2578 Intent intent = new Intent(Intent.ACTION_TIME_CHANGED); 2579 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING 2580 | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT 2581 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND 2582 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); 2583 getContext().sendBroadcastAsUser(intent, UserHandle.ALL); 2584 2585 // The world has changed on us, so we need to re-evaluate alarms 2586 // regardless of whether the kernel has told us one went off. 2587 result |= IS_WAKEUP_MASK; 2588 } 2589 } 2590 2591 if (result != TIME_CHANGED_MASK) { 2592 // If this was anything besides just a time change, then figure what if 2593 // anything to do about alarms. 2594 synchronized (mLock) { 2595 if (localLOGV) Slog.v( 2596 TAG, "Checking for alarms... rtc=" + nowRTC 2597 + ", elapsed=" + nowELAPSED); 2598 2599 if (WAKEUP_STATS) { 2600 if ((result & IS_WAKEUP_MASK) != 0) { 2601 long newEarliest = nowRTC - RECENT_WAKEUP_PERIOD; 2602 int n = 0; 2603 for (WakeupEvent event : mRecentWakeups) { 2604 if (event.when > newEarliest) break; 2605 n++; // number of now-stale entries at the list head 2606 } 2607 for (int i = 0; i < n; i++) { 2608 mRecentWakeups.remove(); 2609 } 2610 2611 recordWakeupAlarms(mAlarmBatches, nowELAPSED, nowRTC); 2612 } 2613 } 2614 2615 boolean hasWakeup = triggerAlarmsLocked(triggerList, nowELAPSED, nowRTC); 2616 if (!hasWakeup && checkAllowNonWakeupDelayLocked(nowELAPSED)) { 2617 // if there are no wakeup alarms and the screen is off, we can 2618 // delay what we have so far until the future. 2619 if (mPendingNonWakeupAlarms.size() == 0) { 2620 mStartCurrentDelayTime = nowELAPSED; 2621 mNextNonWakeupDeliveryTime = nowELAPSED 2622 + ((currentNonWakeupFuzzLocked(nowELAPSED)*3)/2); 2623 } 2624 mPendingNonWakeupAlarms.addAll(triggerList); 2625 mNumDelayedAlarms += triggerList.size(); 2626 rescheduleKernelAlarmsLocked(); 2627 updateNextAlarmClockLocked(); 2628 } else { 2629 // now deliver the alarm intents; if there are pending non-wakeup 2630 // alarms, we need to merge them in to the list. note we don't 2631 // just deliver them first because we generally want non-wakeup 2632 // alarms delivered after wakeup alarms. 2633 rescheduleKernelAlarmsLocked(); 2634 updateNextAlarmClockLocked(); 2635 if (mPendingNonWakeupAlarms.size() > 0) { 2636 calculateDeliveryPriorities(mPendingNonWakeupAlarms); 2637 triggerList.addAll(mPendingNonWakeupAlarms); 2638 Collections.sort(triggerList, mAlarmDispatchComparator); 2639 final long thisDelayTime = nowELAPSED - mStartCurrentDelayTime; 2640 mTotalDelayTime += thisDelayTime; 2641 if (mMaxDelayTime < thisDelayTime) { 2642 mMaxDelayTime = thisDelayTime; 2643 } 2644 mPendingNonWakeupAlarms.clear(); 2645 } 2646 deliverAlarmsLocked(triggerList, nowELAPSED); 2647 } 2648 } 2649 2650 } else { 2651 // Just in case -- even though no wakeup flag was set, make sure 2652 // we have updated the kernel to the next alarm time. 2653 synchronized (mLock) { 2654 rescheduleKernelAlarmsLocked(); 2655 } 2656 } 2657 } 2658 } 2659 } 2660 2661 /** 2662 * Attribute blame for a WakeLock. 2663 * @param pi PendingIntent to attribute blame to if ws is null. 2664 * @param ws WorkSource to attribute blame. 2665 * @param knownUid attribution uid; < 0 if we need to derive it from the PendingIntent sender 2666 */ 2667 void setWakelockWorkSource(PendingIntent pi, WorkSource ws, int type, String tag, 2668 int knownUid, boolean first) { 2669 try { 2670 final boolean unimportant = pi == mTimeTickSender; 2671 mWakeLock.setUnimportantForLogging(unimportant); 2672 if (first || mLastWakeLockUnimportantForLogging) { 2673 mWakeLock.setHistoryTag(tag); 2674 } else { 2675 mWakeLock.setHistoryTag(null); 2676 } 2677 mLastWakeLockUnimportantForLogging = unimportant; 2678 if (ws != null) { 2679 mWakeLock.setWorkSource(ws); 2680 return; 2681 } 2682 2683 final int uid = (knownUid >= 0) 2684 ? knownUid 2685 : ActivityManager.getService().getUidForIntentSender(pi.getTarget()); 2686 if (uid >= 0) { 2687 mWakeLock.setWorkSource(new WorkSource(uid)); 2688 return; 2689 } 2690 } catch (Exception e) { 2691 } 2692 2693 // Something went wrong; fall back to attributing the lock to the OS 2694 mWakeLock.setWorkSource(null); 2695 } 2696 2697 private class AlarmHandler extends Handler { 2698 public static final int ALARM_EVENT = 1; 2699 public static final int SEND_NEXT_ALARM_CLOCK_CHANGED = 2; 2700 public static final int LISTENER_TIMEOUT = 3; 2701 public static final int REPORT_ALARMS_ACTIVE = 4; 2702 2703 public AlarmHandler() { 2704 } 2705 2706 public void handleMessage(Message msg) { 2707 switch (msg.what) { 2708 case ALARM_EVENT: { 2709 ArrayList<Alarm> triggerList = new ArrayList<Alarm>(); 2710 synchronized (mLock) { 2711 final long nowRTC = System.currentTimeMillis(); 2712 final long nowELAPSED = SystemClock.elapsedRealtime(); 2713 triggerAlarmsLocked(triggerList, nowELAPSED, nowRTC); 2714 updateNextAlarmClockLocked(); 2715 } 2716 2717 // now trigger the alarms without the lock held 2718 for (int i=0; i<triggerList.size(); i++) { 2719 Alarm alarm = triggerList.get(i); 2720 try { 2721 alarm.operation.send(); 2722 } catch (PendingIntent.CanceledException e) { 2723 if (alarm.repeatInterval > 0) { 2724 // This IntentSender is no longer valid, but this 2725 // is a repeating alarm, so toss the hoser. 2726 removeImpl(alarm.operation); 2727 } 2728 } 2729 } 2730 break; 2731 } 2732 2733 case SEND_NEXT_ALARM_CLOCK_CHANGED: 2734 sendNextAlarmClockChanged(); 2735 break; 2736 2737 case LISTENER_TIMEOUT: 2738 mDeliveryTracker.alarmTimedOut((IBinder) msg.obj); 2739 break; 2740 2741 case REPORT_ALARMS_ACTIVE: 2742 if (mLocalDeviceIdleController != null) { 2743 mLocalDeviceIdleController.setAlarmsActive(msg.arg1 != 0); 2744 } 2745 break; 2746 2747 default: 2748 // nope, just ignore it 2749 break; 2750 } 2751 } 2752 } 2753 2754 class ClockReceiver extends BroadcastReceiver { 2755 public ClockReceiver() { 2756 IntentFilter filter = new IntentFilter(); 2757 filter.addAction(Intent.ACTION_TIME_TICK); 2758 filter.addAction(Intent.ACTION_DATE_CHANGED); 2759 getContext().registerReceiver(this, filter); 2760 } 2761 2762 @Override 2763 public void onReceive(Context context, Intent intent) { 2764 if (intent.getAction().equals(Intent.ACTION_TIME_TICK)) { 2765 if (DEBUG_BATCH) { 2766 Slog.v(TAG, "Received TIME_TICK alarm; rescheduling"); 2767 } 2768 scheduleTimeTickEvent(); 2769 } else if (intent.getAction().equals(Intent.ACTION_DATE_CHANGED)) { 2770 // Since the kernel does not keep track of DST, we need to 2771 // reset the TZ information at the beginning of each day 2772 // based off of the current Zone gmt offset + userspace tracked 2773 // daylight savings information. 2774 TimeZone zone = TimeZone.getTimeZone(SystemProperties.get(TIMEZONE_PROPERTY)); 2775 int gmtOffset = zone.getOffset(System.currentTimeMillis()); 2776 setKernelTimezone(mNativeData, -(gmtOffset / 60000)); 2777 scheduleDateChangedEvent(); 2778 } 2779 } 2780 2781 public void scheduleTimeTickEvent() { 2782 final long currentTime = System.currentTimeMillis(); 2783 final long nextTime = 60000 * ((currentTime / 60000) + 1); 2784 2785 // Schedule this event for the amount of time that it would take to get to 2786 // the top of the next minute. 2787 final long tickEventDelay = nextTime - currentTime; 2788 2789 final WorkSource workSource = null; // Let system take blame for time tick events. 2790 setImpl(ELAPSED_REALTIME, SystemClock.elapsedRealtime() + tickEventDelay, 0, 2791 0, mTimeTickSender, null, null, AlarmManager.FLAG_STANDALONE, workSource, 2792 null, Process.myUid(), "android"); 2793 } 2794 2795 public void scheduleDateChangedEvent() { 2796 Calendar calendar = Calendar.getInstance(); 2797 calendar.setTimeInMillis(System.currentTimeMillis()); 2798 calendar.set(Calendar.HOUR_OF_DAY, 0); 2799 calendar.set(Calendar.MINUTE, 0); 2800 calendar.set(Calendar.SECOND, 0); 2801 calendar.set(Calendar.MILLISECOND, 0); 2802 calendar.add(Calendar.DAY_OF_MONTH, 1); 2803 2804 final WorkSource workSource = null; // Let system take blame for date change events. 2805 setImpl(RTC, calendar.getTimeInMillis(), 0, 0, mDateChangeSender, null, null, 2806 AlarmManager.FLAG_STANDALONE, workSource, null, 2807 Process.myUid(), "android"); 2808 } 2809 } 2810 2811 class InteractiveStateReceiver extends BroadcastReceiver { 2812 public InteractiveStateReceiver() { 2813 IntentFilter filter = new IntentFilter(); 2814 filter.addAction(Intent.ACTION_SCREEN_OFF); 2815 filter.addAction(Intent.ACTION_SCREEN_ON); 2816 filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); 2817 getContext().registerReceiver(this, filter); 2818 } 2819 2820 @Override 2821 public void onReceive(Context context, Intent intent) { 2822 synchronized (mLock) { 2823 interactiveStateChangedLocked(Intent.ACTION_SCREEN_ON.equals(intent.getAction())); 2824 } 2825 } 2826 } 2827 2828 class UninstallReceiver extends BroadcastReceiver { 2829 public UninstallReceiver() { 2830 IntentFilter filter = new IntentFilter(); 2831 filter.addAction(Intent.ACTION_PACKAGE_REMOVED); 2832 filter.addAction(Intent.ACTION_PACKAGE_RESTARTED); 2833 filter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 2834 filter.addDataScheme("package"); 2835 getContext().registerReceiver(this, filter); 2836 // Register for events related to sdcard installation. 2837 IntentFilter sdFilter = new IntentFilter(); 2838 sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); 2839 sdFilter.addAction(Intent.ACTION_USER_STOPPED); 2840 sdFilter.addAction(Intent.ACTION_UID_REMOVED); 2841 getContext().registerReceiver(this, sdFilter); 2842 } 2843 2844 @Override 2845 public void onReceive(Context context, Intent intent) { 2846 synchronized (mLock) { 2847 String action = intent.getAction(); 2848 String pkgList[] = null; 2849 if (Intent.ACTION_QUERY_PACKAGE_RESTART.equals(action)) { 2850 pkgList = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 2851 for (String packageName : pkgList) { 2852 if (lookForPackageLocked(packageName)) { 2853 setResultCode(Activity.RESULT_OK); 2854 return; 2855 } 2856 } 2857 return; 2858 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) { 2859 pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 2860 } else if (Intent.ACTION_USER_STOPPED.equals(action)) { 2861 int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 2862 if (userHandle >= 0) { 2863 removeUserLocked(userHandle); 2864 } 2865 } else if (Intent.ACTION_UID_REMOVED.equals(action)) { 2866 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 2867 if (uid >= 0) { 2868 mLastAllowWhileIdleDispatch.delete(uid); 2869 } 2870 } else { 2871 if (Intent.ACTION_PACKAGE_REMOVED.equals(action) 2872 && intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 2873 // This package is being updated; don't kill its alarms. 2874 return; 2875 } 2876 Uri data = intent.getData(); 2877 if (data != null) { 2878 String pkg = data.getSchemeSpecificPart(); 2879 if (pkg != null) { 2880 pkgList = new String[]{pkg}; 2881 } 2882 } 2883 } 2884 if (pkgList != null && (pkgList.length > 0)) { 2885 for (String pkg : pkgList) { 2886 removeLocked(pkg); 2887 mPriorities.remove(pkg); 2888 for (int i=mBroadcastStats.size()-1; i>=0; i--) { 2889 ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(i); 2890 if (uidStats.remove(pkg) != null) { 2891 if (uidStats.size() <= 0) { 2892 mBroadcastStats.removeAt(i); 2893 } 2894 } 2895 } 2896 } 2897 } 2898 } 2899 } 2900 } 2901 2902 final class UidObserver extends IUidObserver.Stub { 2903 @Override public void onUidStateChanged(int uid, int procState, long procStateSeq) { 2904 } 2905 2906 @Override public void onUidGone(int uid, boolean disabled) { 2907 if (disabled) { 2908 synchronized (mLock) { 2909 removeForStoppedLocked(uid); 2910 } 2911 } 2912 } 2913 2914 @Override public void onUidActive(int uid) { 2915 } 2916 2917 @Override public void onUidIdle(int uid, boolean disabled) { 2918 if (disabled) { 2919 synchronized (mLock) { 2920 removeForStoppedLocked(uid); 2921 } 2922 } 2923 } 2924 2925 @Override public void onUidCachedChanged(int uid, boolean cached) { 2926 } 2927 }; 2928 2929 private final BroadcastStats getStatsLocked(PendingIntent pi) { 2930 String pkg = pi.getCreatorPackage(); 2931 int uid = pi.getCreatorUid(); 2932 return getStatsLocked(uid, pkg); 2933 } 2934 2935 private final BroadcastStats getStatsLocked(int uid, String pkgName) { 2936 ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.get(uid); 2937 if (uidStats == null) { 2938 uidStats = new ArrayMap<String, BroadcastStats>(); 2939 mBroadcastStats.put(uid, uidStats); 2940 } 2941 BroadcastStats bs = uidStats.get(pkgName); 2942 if (bs == null) { 2943 bs = new BroadcastStats(uid, pkgName); 2944 uidStats.put(pkgName, bs); 2945 } 2946 return bs; 2947 } 2948 2949 /** 2950 * Canonical count of (operation.send() - onSendFinished()) and 2951 * listener send/complete/timeout invocations. 2952 * Guarded by the usual lock. 2953 */ 2954 @GuardedBy("mLock") 2955 private int mSendCount = 0; 2956 @GuardedBy("mLock") 2957 private int mSendFinishCount = 0; 2958 @GuardedBy("mLock") 2959 private int mListenerCount = 0; 2960 @GuardedBy("mLock") 2961 private int mListenerFinishCount = 0; 2962 2963 class DeliveryTracker extends IAlarmCompleteListener.Stub implements PendingIntent.OnFinished { 2964 2965 private InFlight removeLocked(PendingIntent pi, Intent intent) { 2966 for (int i = 0; i < mInFlight.size(); i++) { 2967 if (mInFlight.get(i).mPendingIntent == pi) { 2968 return mInFlight.remove(i); 2969 } 2970 } 2971 mLog.w("No in-flight alarm for " + pi + " " + intent); 2972 return null; 2973 } 2974 2975 private InFlight removeLocked(IBinder listener) { 2976 for (int i = 0; i < mInFlight.size(); i++) { 2977 if (mInFlight.get(i).mListener == listener) { 2978 return mInFlight.remove(i); 2979 } 2980 } 2981 mLog.w("No in-flight alarm for listener " + listener); 2982 return null; 2983 } 2984 2985 private void updateStatsLocked(InFlight inflight) { 2986 final long nowELAPSED = SystemClock.elapsedRealtime(); 2987 BroadcastStats bs = inflight.mBroadcastStats; 2988 bs.nesting--; 2989 if (bs.nesting <= 0) { 2990 bs.nesting = 0; 2991 bs.aggregateTime += nowELAPSED - bs.startTime; 2992 } 2993 FilterStats fs = inflight.mFilterStats; 2994 fs.nesting--; 2995 if (fs.nesting <= 0) { 2996 fs.nesting = 0; 2997 fs.aggregateTime += nowELAPSED - fs.startTime; 2998 } 2999 if (RECORD_ALARMS_IN_HISTORY) { 3000 if (inflight.mWorkSource != null && inflight.mWorkSource.size() > 0) { 3001 for (int wi=0; wi<inflight.mWorkSource.size(); wi++) { 3002 ActivityManager.noteAlarmFinish( 3003 inflight.mPendingIntent, inflight.mWorkSource.get(wi), inflight.mTag); 3004 } 3005 } else { 3006 ActivityManager.noteAlarmFinish( 3007 inflight.mPendingIntent, inflight.mUid, inflight.mTag); 3008 } 3009 } 3010 } 3011 3012 private void updateTrackingLocked(InFlight inflight) { 3013 if (inflight != null) { 3014 updateStatsLocked(inflight); 3015 } 3016 mBroadcastRefCount--; 3017 if (DEBUG_WAKELOCK) { 3018 Slog.d(TAG, "mBroadcastRefCount -> " + mBroadcastRefCount); 3019 } 3020 if (mBroadcastRefCount == 0) { 3021 mHandler.obtainMessage(AlarmHandler.REPORT_ALARMS_ACTIVE, 0).sendToTarget(); 3022 mWakeLock.release(); 3023 if (mInFlight.size() > 0) { 3024 mLog.w("Finished all dispatches with " + mInFlight.size() 3025 + " remaining inflights"); 3026 for (int i=0; i<mInFlight.size(); i++) { 3027 mLog.w(" Remaining #" + i + ": " + mInFlight.get(i)); 3028 } 3029 mInFlight.clear(); 3030 } 3031 } else { 3032 // the next of our alarms is now in flight. reattribute the wakelock. 3033 if (mInFlight.size() > 0) { 3034 InFlight inFlight = mInFlight.get(0); 3035 setWakelockWorkSource(inFlight.mPendingIntent, inFlight.mWorkSource, 3036 inFlight.mAlarmType, inFlight.mTag, -1, false); 3037 } else { 3038 // should never happen 3039 mLog.w("Alarm wakelock still held but sent queue empty"); 3040 mWakeLock.setWorkSource(null); 3041 } 3042 } 3043 } 3044 3045 /** 3046 * Callback that arrives when a direct-call alarm reports that delivery has finished 3047 */ 3048 @Override 3049 public void alarmComplete(IBinder who) { 3050 if (who == null) { 3051 mLog.w("Invalid alarmComplete: uid=" + Binder.getCallingUid() 3052 + " pid=" + Binder.getCallingPid()); 3053 return; 3054 } 3055 3056 final long ident = Binder.clearCallingIdentity(); 3057 try { 3058 synchronized (mLock) { 3059 mHandler.removeMessages(AlarmHandler.LISTENER_TIMEOUT, who); 3060 InFlight inflight = removeLocked(who); 3061 if (inflight != null) { 3062 if (DEBUG_LISTENER_CALLBACK) { 3063 Slog.i(TAG, "alarmComplete() from " + who); 3064 } 3065 updateTrackingLocked(inflight); 3066 mListenerFinishCount++; 3067 } else { 3068 // Delivery timed out, and the timeout handling already took care of 3069 // updating our tracking here, so we needn't do anything further. 3070 if (DEBUG_LISTENER_CALLBACK) { 3071 Slog.i(TAG, "Late alarmComplete() from " + who); 3072 } 3073 } 3074 } 3075 } finally { 3076 Binder.restoreCallingIdentity(ident); 3077 } 3078 } 3079 3080 /** 3081 * Callback that arrives when a PendingIntent alarm has finished delivery 3082 */ 3083 @Override 3084 public void onSendFinished(PendingIntent pi, Intent intent, int resultCode, 3085 String resultData, Bundle resultExtras) { 3086 synchronized (mLock) { 3087 mSendFinishCount++; 3088 updateTrackingLocked(removeLocked(pi, intent)); 3089 } 3090 } 3091 3092 /** 3093 * Timeout of a direct-call alarm delivery 3094 */ 3095 public void alarmTimedOut(IBinder who) { 3096 synchronized (mLock) { 3097 InFlight inflight = removeLocked(who); 3098 if (inflight != null) { 3099 // TODO: implement ANR policy for the target 3100 if (DEBUG_LISTENER_CALLBACK) { 3101 Slog.i(TAG, "Alarm listener " + who + " timed out in delivery"); 3102 } 3103 updateTrackingLocked(inflight); 3104 mListenerFinishCount++; 3105 } else { 3106 if (DEBUG_LISTENER_CALLBACK) { 3107 Slog.i(TAG, "Spurious timeout of listener " + who); 3108 } 3109 mLog.w("Spurious timeout of listener " + who); 3110 } 3111 } 3112 } 3113 3114 /** 3115 * Deliver an alarm and set up the post-delivery handling appropriately 3116 */ 3117 public void deliverLocked(Alarm alarm, long nowELAPSED, boolean allowWhileIdle) { 3118 if (alarm.operation != null) { 3119 // PendingIntent alarm 3120 mSendCount++; 3121 try { 3122 alarm.operation.send(getContext(), 0, 3123 mBackgroundIntent.putExtra( 3124 Intent.EXTRA_ALARM_COUNT, alarm.count), 3125 mDeliveryTracker, mHandler, null, 3126 allowWhileIdle ? mIdleOptions : null); 3127 } catch (PendingIntent.CanceledException e) { 3128 if (alarm.repeatInterval > 0) { 3129 // This IntentSender is no longer valid, but this 3130 // is a repeating alarm, so toss it 3131 removeImpl(alarm.operation); 3132 } 3133 // No actual delivery was possible, so the delivery tracker's 3134 // 'finished' callback won't be invoked. We also don't need 3135 // to do any wakelock or stats tracking, so we have nothing 3136 // left to do here but go on to the next thing. 3137 mSendFinishCount++; 3138 return; 3139 } 3140 } else { 3141 // Direct listener callback alarm 3142 mListenerCount++; 3143 try { 3144 if (DEBUG_LISTENER_CALLBACK) { 3145 Slog.v(TAG, "Alarm to uid=" + alarm.uid 3146 + " listener=" + alarm.listener.asBinder()); 3147 } 3148 alarm.listener.doAlarm(this); 3149 mHandler.sendMessageDelayed( 3150 mHandler.obtainMessage(AlarmHandler.LISTENER_TIMEOUT, 3151 alarm.listener.asBinder()), 3152 mConstants.LISTENER_TIMEOUT); 3153 } catch (Exception e) { 3154 if (DEBUG_LISTENER_CALLBACK) { 3155 Slog.i(TAG, "Alarm undeliverable to listener " 3156 + alarm.listener.asBinder(), e); 3157 } 3158 // As in the PendingIntent.CanceledException case, delivery of the 3159 // alarm was not possible, so we have no wakelock or timeout or 3160 // stats management to do. It threw before we posted the delayed 3161 // timeout message, so we're done here. 3162 mListenerFinishCount++; 3163 return; 3164 } 3165 } 3166 3167 // The alarm is now in flight; now arrange wakelock and stats tracking 3168 if (DEBUG_WAKELOCK) { 3169 Slog.d(TAG, "mBroadcastRefCount -> " + (mBroadcastRefCount + 1)); 3170 } 3171 if (mBroadcastRefCount == 0) { 3172 setWakelockWorkSource(alarm.operation, alarm.workSource, 3173 alarm.type, alarm.statsTag, (alarm.operation == null) ? alarm.uid : -1, 3174 true); 3175 mWakeLock.acquire(); 3176 mHandler.obtainMessage(AlarmHandler.REPORT_ALARMS_ACTIVE, 1).sendToTarget(); 3177 } 3178 final InFlight inflight = new InFlight(AlarmManagerService.this, 3179 alarm.operation, alarm.listener, alarm.workSource, alarm.uid, 3180 alarm.packageName, alarm.type, alarm.statsTag, nowELAPSED); 3181 mInFlight.add(inflight); 3182 mBroadcastRefCount++; 3183 3184 if (allowWhileIdle) { 3185 // Record the last time this uid handled an ALLOW_WHILE_IDLE alarm. 3186 mLastAllowWhileIdleDispatch.put(alarm.uid, nowELAPSED); 3187 if (RECORD_DEVICE_IDLE_ALARMS) { 3188 IdleDispatchEntry ent = new IdleDispatchEntry(); 3189 ent.uid = alarm.uid; 3190 ent.pkg = alarm.packageName; 3191 ent.tag = alarm.statsTag; 3192 ent.op = "DELIVER"; 3193 ent.elapsedRealtime = nowELAPSED; 3194 mAllowWhileIdleDispatches.add(ent); 3195 } 3196 } 3197 3198 final BroadcastStats bs = inflight.mBroadcastStats; 3199 bs.count++; 3200 if (bs.nesting == 0) { 3201 bs.nesting = 1; 3202 bs.startTime = nowELAPSED; 3203 } else { 3204 bs.nesting++; 3205 } 3206 final FilterStats fs = inflight.mFilterStats; 3207 fs.count++; 3208 if (fs.nesting == 0) { 3209 fs.nesting = 1; 3210 fs.startTime = nowELAPSED; 3211 } else { 3212 fs.nesting++; 3213 } 3214 if (alarm.type == ELAPSED_REALTIME_WAKEUP 3215 || alarm.type == RTC_WAKEUP) { 3216 bs.numWakeup++; 3217 fs.numWakeup++; 3218 if (alarm.workSource != null && alarm.workSource.size() > 0) { 3219 for (int wi=0; wi<alarm.workSource.size(); wi++) { 3220 final String wsName = alarm.workSource.getName(wi); 3221 ActivityManager.noteWakeupAlarm( 3222 alarm.operation, alarm.workSource.get(wi), 3223 (wsName != null) ? wsName : alarm.packageName, 3224 alarm.statsTag); 3225 } 3226 } else { 3227 ActivityManager.noteWakeupAlarm( 3228 alarm.operation, alarm.uid, alarm.packageName, alarm.statsTag); 3229 } 3230 } 3231 } 3232 } 3233 } 3234