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