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