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