• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server;
18 
19 import static android.app.AlarmManager.ELAPSED_REALTIME;
20 import static android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP;
21 import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE;
22 import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
23 import static android.app.AlarmManager.RTC;
24 import static android.app.AlarmManager.RTC_WAKEUP;
25 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         for (int i = mPendingNonWakeupAlarms.size() - 1; i >= 0; i--) {
3113             final Alarm a = mPendingNonWakeupAlarms.get(i);
3114             if (a.matches(operation, directReceiver)) {
3115                 // Don't set didRemove, since this doesn't impact the scheduled alarms.
3116                 mPendingNonWakeupAlarms.remove(i);
3117                 decrementAlarmCount(a.uid, 1);
3118             }
3119         }
3120         if (didRemove) {
3121             if (DEBUG_BATCH) {
3122                 Slog.v(TAG, "remove(operation) changed bounds; rebatching");
3123             }
3124             boolean restorePending = false;
3125             if (mPendingIdleUntil != null && mPendingIdleUntil.matches(operation, directReceiver)) {
3126                 mPendingIdleUntil = null;
3127                 restorePending = true;
3128             }
3129             if (mNextWakeFromIdle != null && mNextWakeFromIdle.matches(operation, directReceiver)) {
3130                 mNextWakeFromIdle = null;
3131             }
3132             rebatchAllAlarmsLocked(true);
3133             if (restorePending) {
3134                 restorePendingWhileIdleAlarmsLocked();
3135             }
3136             updateNextAlarmClockLocked();
3137         }
3138     }
3139 
removeLocked(final int uid)3140     void removeLocked(final int uid) {
3141         if (uid == Process.SYSTEM_UID) {
3142             // If a force-stop occurs for a system-uid package, ignore it.
3143             return;
3144         }
3145         boolean didRemove = false;
3146         final Predicate<Alarm> whichAlarms = (Alarm a) -> a.uid == uid;
3147         for (int i = mAlarmBatches.size() - 1; i >= 0; i--) {
3148             Batch b = mAlarmBatches.get(i);
3149             didRemove |= b.remove(whichAlarms, false);
3150             if (b.size() == 0) {
3151                 mAlarmBatches.remove(i);
3152             }
3153         }
3154         for (int i = mPendingWhileIdleAlarms.size() - 1; i >= 0; i--) {
3155             final Alarm a = mPendingWhileIdleAlarms.get(i);
3156             if (a.uid == uid) {
3157                 // Don't set didRemove, since this doesn't impact the scheduled alarms.
3158                 mPendingWhileIdleAlarms.remove(i);
3159                 decrementAlarmCount(uid, 1);
3160             }
3161         }
3162         for (int i = mPendingBackgroundAlarms.size() - 1; i >= 0; i --) {
3163             final ArrayList<Alarm> alarmsForUid = mPendingBackgroundAlarms.valueAt(i);
3164             for (int j = alarmsForUid.size() - 1; j >= 0; j--) {
3165                 if (alarmsForUid.get(j).uid == uid) {
3166                     alarmsForUid.remove(j);
3167                     decrementAlarmCount(uid, 1);
3168                 }
3169             }
3170             if (alarmsForUid.size() == 0) {
3171                 mPendingBackgroundAlarms.removeAt(i);
3172             }
3173         }
3174         // If we're currently keying off of this app's alarms for doze transitions,
3175         // make sure to reset to other triggers.
3176         if (mNextWakeFromIdle != null && mNextWakeFromIdle.uid == uid) {
3177             mNextWakeFromIdle = null;
3178         }
3179         if (mPendingIdleUntil != null && mPendingIdleUntil.uid == uid) {
3180             // Should never happen - only the system uid is allowed to set idle-until alarms
3181             Slog.wtf(TAG, "Removed app uid " + uid + " set idle-until alarm!");
3182             mPendingIdleUntil = null;
3183         }
3184         if (didRemove) {
3185             if (DEBUG_BATCH) {
3186                 Slog.v(TAG, "remove(uid) changed bounds; rebatching");
3187             }
3188             rebatchAllAlarmsLocked(true);
3189             rescheduleKernelAlarmsLocked();
3190             updateNextAlarmClockLocked();
3191         }
3192     }
3193 
removeLocked(final String packageName)3194     void removeLocked(final String packageName) {
3195         if (packageName == null) {
3196             if (localLOGV) {
3197                 Slog.w(TAG, "requested remove() of null packageName",
3198                         new RuntimeException("here"));
3199             }
3200             return;
3201         }
3202 
3203         boolean didRemove = false;
3204         final MutableBoolean removedNextWakeFromIdle = new MutableBoolean(false);
3205         final Predicate<Alarm> whichAlarms = (Alarm a) -> {
3206             final boolean didMatch = a.matches(packageName);
3207             if (didMatch && a == mNextWakeFromIdle) {
3208                 removedNextWakeFromIdle.value = true;
3209             }
3210             return didMatch;
3211         };
3212         final boolean oldHasTick = haveBatchesTimeTickAlarm(mAlarmBatches);
3213         for (int i = mAlarmBatches.size() - 1; i >= 0; i--) {
3214             Batch b = mAlarmBatches.get(i);
3215             didRemove |= b.remove(whichAlarms, false);
3216             if (b.size() == 0) {
3217                 mAlarmBatches.remove(i);
3218             }
3219         }
3220         final boolean newHasTick = haveBatchesTimeTickAlarm(mAlarmBatches);
3221         if (oldHasTick != newHasTick) {
3222             Slog.wtf(TAG, "removeLocked: hasTick changed from " + oldHasTick + " to " + newHasTick);
3223         }
3224 
3225         for (int i = mPendingWhileIdleAlarms.size() - 1; i >= 0; i--) {
3226             final Alarm a = mPendingWhileIdleAlarms.get(i);
3227             if (a.matches(packageName)) {
3228                 // Don't set didRemove, since this doesn't impact the scheduled alarms.
3229                 mPendingWhileIdleAlarms.remove(i);
3230                 decrementAlarmCount(a.uid, 1);
3231             }
3232         }
3233         for (int i = mPendingBackgroundAlarms.size() - 1; i >= 0; i --) {
3234             final ArrayList<Alarm> alarmsForUid = mPendingBackgroundAlarms.valueAt(i);
3235             for (int j = alarmsForUid.size() - 1; j >= 0; j--) {
3236                 final Alarm alarm = alarmsForUid.get(j);
3237                 if (alarm.matches(packageName)) {
3238                     alarmsForUid.remove(j);
3239                     decrementAlarmCount(alarm.uid, 1);
3240                 }
3241             }
3242             if (alarmsForUid.size() == 0) {
3243                 mPendingBackgroundAlarms.removeAt(i);
3244             }
3245         }
3246         // If we're currently keying off of this app's alarms for doze transitions,
3247         // make sure to reset to other triggers.
3248         if (removedNextWakeFromIdle.value) {
3249             mNextWakeFromIdle = null;
3250         }
3251         if (didRemove) {
3252             if (DEBUG_BATCH) {
3253                 Slog.v(TAG, "remove(package) changed bounds; rebatching");
3254             }
3255             rebatchAllAlarmsLocked(true);
3256             rescheduleKernelAlarmsLocked();
3257             updateNextAlarmClockLocked();
3258         }
3259     }
3260 
3261     // Only called for ephemeral apps
removeForStoppedLocked(final int uid)3262     void removeForStoppedLocked(final int uid) {
3263         if (uid == Process.SYSTEM_UID) {
3264             // If a force-stop occurs for a system-uid package, ignore it.
3265             return;
3266         }
3267         boolean didRemove = false;
3268         final Predicate<Alarm> whichAlarms = (Alarm a) -> {
3269             try {
3270                 if (a.uid == uid && ActivityManager.getService().isAppStartModeDisabled(
3271                         uid, a.packageName)) {
3272                     return true;
3273                 }
3274             } catch (RemoteException e) { /* fall through */}
3275             return false;
3276         };
3277         for (int i = mAlarmBatches.size() - 1; i >= 0; i--) {
3278             Batch b = mAlarmBatches.get(i);
3279             didRemove |= b.remove(whichAlarms, false);
3280             if (b.size() == 0) {
3281                 mAlarmBatches.remove(i);
3282             }
3283         }
3284         for (int i = mPendingWhileIdleAlarms.size() - 1; i >= 0; i--) {
3285             final Alarm a = mPendingWhileIdleAlarms.get(i);
3286             if (a.uid == uid) {
3287                 // Don't set didRemove, since this doesn't impact the scheduled alarms.
3288                 mPendingWhileIdleAlarms.remove(i);
3289                 decrementAlarmCount(uid, 1);
3290             }
3291         }
3292         for (int i = mPendingBackgroundAlarms.size() - 1; i >= 0; i--) {
3293             if (mPendingBackgroundAlarms.keyAt(i) == uid) {
3294                 final ArrayList<Alarm> toRemove = mPendingBackgroundAlarms.valueAt(i);
3295                 if (toRemove != null) {
3296                     decrementAlarmCount(uid, toRemove.size());
3297                 }
3298                 mPendingBackgroundAlarms.removeAt(i);
3299             }
3300         }
3301         if (didRemove) {
3302             if (DEBUG_BATCH) {
3303                 Slog.v(TAG, "remove(package) changed bounds; rebatching");
3304             }
3305             rebatchAllAlarmsLocked(true);
3306             rescheduleKernelAlarmsLocked();
3307             updateNextAlarmClockLocked();
3308         }
3309     }
3310 
removeUserLocked(int userHandle)3311     void removeUserLocked(int userHandle) {
3312         if (userHandle == USER_SYSTEM) {
3313             // If we're told we're removing the system user, ignore it.
3314             return;
3315         }
3316         boolean didRemove = false;
3317         final Predicate<Alarm> whichAlarms =
3318                 (Alarm a) -> UserHandle.getUserId(a.creatorUid) == userHandle;
3319         for (int i = mAlarmBatches.size() - 1; i >= 0; i--) {
3320             Batch b = mAlarmBatches.get(i);
3321             didRemove |= b.remove(whichAlarms, false);
3322             if (b.size() == 0) {
3323                 mAlarmBatches.remove(i);
3324             }
3325         }
3326         for (int i = mPendingWhileIdleAlarms.size() - 1; i >= 0; i--) {
3327             if (UserHandle.getUserId(mPendingWhileIdleAlarms.get(i).creatorUid)
3328                     == userHandle) {
3329                 // Don't set didRemove, since this doesn't impact the scheduled alarms.
3330                 final Alarm removed = mPendingWhileIdleAlarms.remove(i);
3331                 decrementAlarmCount(removed.uid, 1);
3332             }
3333         }
3334         for (int i = mPendingBackgroundAlarms.size() - 1; i >= 0; i--) {
3335             if (UserHandle.getUserId(mPendingBackgroundAlarms.keyAt(i)) == userHandle) {
3336                 final ArrayList<Alarm> toRemove = mPendingBackgroundAlarms.valueAt(i);
3337                 if (toRemove != null) {
3338                     for (int j = 0; j < toRemove.size(); j++) {
3339                         decrementAlarmCount(toRemove.get(j).uid, 1);
3340                     }
3341                 }
3342                 mPendingBackgroundAlarms.removeAt(i);
3343             }
3344         }
3345         for (int i = mLastAllowWhileIdleDispatch.size() - 1; i >= 0; i--) {
3346             if (UserHandle.getUserId(mLastAllowWhileIdleDispatch.keyAt(i)) == userHandle) {
3347                 mLastAllowWhileIdleDispatch.removeAt(i);
3348             }
3349         }
3350 
3351         if (didRemove) {
3352             if (DEBUG_BATCH) {
3353                 Slog.v(TAG, "remove(user) changed bounds; rebatching");
3354             }
3355             rebatchAllAlarmsLocked(true);
3356             rescheduleKernelAlarmsLocked();
3357             updateNextAlarmClockLocked();
3358         }
3359     }
3360 
interactiveStateChangedLocked(boolean interactive)3361     void interactiveStateChangedLocked(boolean interactive) {
3362         if (mInteractive != interactive) {
3363             mInteractive = interactive;
3364             final long nowELAPSED = mInjector.getElapsedRealtime();
3365             if (interactive) {
3366                 if (mPendingNonWakeupAlarms.size() > 0) {
3367                     final long thisDelayTime = nowELAPSED - mStartCurrentDelayTime;
3368                     mTotalDelayTime += thisDelayTime;
3369                     if (mMaxDelayTime < thisDelayTime) {
3370                         mMaxDelayTime = thisDelayTime;
3371                     }
3372                     final ArrayList<Alarm> triggerList = new ArrayList<>(mPendingNonWakeupAlarms);
3373                     deliverAlarmsLocked(triggerList, nowELAPSED);
3374                     mPendingNonWakeupAlarms.clear();
3375                 }
3376                 if (mNonInteractiveStartTime > 0) {
3377                     long dur = nowELAPSED - mNonInteractiveStartTime;
3378                     if (dur > mNonInteractiveTime) {
3379                         mNonInteractiveTime = dur;
3380                     }
3381                 }
3382                 // And send a TIME_TICK right now, since it is important to get the UI updated.
3383                 mHandler.post(() ->
3384                         getContext().sendBroadcastAsUser(mTimeTickIntent, UserHandle.ALL));
3385             } else {
3386                 mNonInteractiveStartTime = nowELAPSED;
3387             }
3388         }
3389     }
3390 
lookForPackageLocked(String packageName)3391     boolean lookForPackageLocked(String packageName) {
3392         for (int i = 0; i < mAlarmBatches.size(); i++) {
3393             Batch b = mAlarmBatches.get(i);
3394             if (b.hasPackage(packageName)) {
3395                 return true;
3396             }
3397         }
3398         for (int i = 0; i < mPendingWhileIdleAlarms.size(); i++) {
3399             final Alarm a = mPendingWhileIdleAlarms.get(i);
3400             if (a.matches(packageName)) {
3401                 return true;
3402             }
3403         }
3404         return false;
3405     }
3406 
setLocked(int type, long when)3407     private void setLocked(int type, long when) {
3408         if (mInjector.isAlarmDriverPresent()) {
3409             mInjector.setAlarm(type, when);
3410         } else {
3411             Message msg = Message.obtain();
3412             msg.what = AlarmHandler.ALARM_EVENT;
3413 
3414             mHandler.removeMessages(msg.what);
3415             mHandler.sendMessageAtTime(msg, when);
3416         }
3417     }
3418 
dumpAlarmList(PrintWriter pw, ArrayList<Alarm> list, String prefix, String label, long nowELAPSED, long nowRTC, SimpleDateFormat sdf)3419     private static final void dumpAlarmList(PrintWriter pw, ArrayList<Alarm> list,
3420             String prefix, String label, long nowELAPSED, long nowRTC, SimpleDateFormat sdf) {
3421         for (int i=list.size()-1; i>=0; i--) {
3422             Alarm a = list.get(i);
3423             pw.print(prefix); pw.print(label); pw.print(" #"); pw.print(i);
3424                     pw.print(": "); pw.println(a);
3425             a.dump(pw, prefix + "  ", nowELAPSED, nowRTC, sdf);
3426         }
3427     }
3428 
labelForType(int type)3429     private static final String labelForType(int type) {
3430         switch (type) {
3431         case RTC: return "RTC";
3432         case RTC_WAKEUP : return "RTC_WAKEUP";
3433         case ELAPSED_REALTIME : return "ELAPSED";
3434         case ELAPSED_REALTIME_WAKEUP: return "ELAPSED_WAKEUP";
3435         }
3436         return "--unknown--";
3437     }
3438 
dumpAlarmList(PrintWriter pw, ArrayList<Alarm> list, String prefix, long nowELAPSED, long nowRTC, SimpleDateFormat sdf)3439     private static final void dumpAlarmList(PrintWriter pw, ArrayList<Alarm> list,
3440             String prefix, long nowELAPSED, long nowRTC, SimpleDateFormat sdf) {
3441         for (int i=list.size()-1; i>=0; i--) {
3442             Alarm a = list.get(i);
3443             final String label = labelForType(a.type);
3444             pw.print(prefix); pw.print(label); pw.print(" #"); pw.print(i);
3445                     pw.print(": "); pw.println(a);
3446             a.dump(pw, prefix + "  ", nowELAPSED, nowRTC, sdf);
3447         }
3448     }
3449 
isBackgroundRestricted(Alarm alarm)3450     private boolean isBackgroundRestricted(Alarm alarm) {
3451         boolean exemptOnBatterySaver = (alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0;
3452         if (alarm.alarmClock != null) {
3453             // Don't defer alarm clocks
3454             return false;
3455         }
3456         if (alarm.operation != null) {
3457             if (alarm.operation.isActivity()) {
3458                 // Don't defer starting actual UI
3459                 return false;
3460             }
3461             if (alarm.operation.isForegroundService()) {
3462                 // FG service alarms are nearly as important; consult AST policy
3463                 exemptOnBatterySaver = true;
3464             }
3465         }
3466         final String sourcePackage = alarm.sourcePackage;
3467         final int sourceUid = alarm.creatorUid;
3468         return (mAppStateTracker != null) &&
3469                 mAppStateTracker.areAlarmsRestricted(sourceUid, sourcePackage,
3470                         exemptOnBatterySaver);
3471     }
3472 
init()3473     private static native long init();
close(long nativeData)3474     private static native void close(long nativeData);
set(long nativeData, int type, long seconds, long nanoseconds)3475     private static native int set(long nativeData, int type, long seconds, long nanoseconds);
waitForAlarm(long nativeData)3476     private static native int waitForAlarm(long nativeData);
setKernelTime(long nativeData, long millis)3477     private static native int setKernelTime(long nativeData, long millis);
setKernelTimezone(long nativeData, int minuteswest)3478     private static native int setKernelTimezone(long nativeData, int minuteswest);
getNextAlarm(long nativeData, int type)3479     private static native long getNextAlarm(long nativeData, int type);
3480 
getWhileIdleMinIntervalLocked(int uid)3481     private long getWhileIdleMinIntervalLocked(int uid) {
3482         final boolean dozing = mPendingIdleUntil != null;
3483         final boolean ebs = (mAppStateTracker != null)
3484                 && mAppStateTracker.isForceAllAppsStandbyEnabled();
3485         if (!dozing && !ebs) {
3486             return mConstants.ALLOW_WHILE_IDLE_SHORT_TIME;
3487         }
3488         if (dozing) {
3489             return mConstants.ALLOW_WHILE_IDLE_LONG_TIME;
3490         }
3491         if (mUseAllowWhileIdleShortTime.get(uid)) {
3492             // if the last allow-while-idle went off while uid was fg, or the uid
3493             // recently came into fg, don't block the alarm for long.
3494             return mConstants.ALLOW_WHILE_IDLE_SHORT_TIME;
3495         }
3496         return mConstants.ALLOW_WHILE_IDLE_LONG_TIME;
3497     }
3498 
triggerAlarmsLocked(ArrayList<Alarm> triggerList, final long nowELAPSED)3499     boolean triggerAlarmsLocked(ArrayList<Alarm> triggerList, final long nowELAPSED) {
3500         boolean hasWakeup = false;
3501         // batches are temporally sorted, so we need only pull from the
3502         // start of the list until we either empty it or hit a batch
3503         // that is not yet deliverable
3504         while (mAlarmBatches.size() > 0) {
3505             Batch batch = mAlarmBatches.get(0);
3506             if (batch.start > nowELAPSED) {
3507                 // Everything else is scheduled for the future
3508                 break;
3509             }
3510 
3511             // We will (re)schedule some alarms now; don't let that interfere
3512             // with delivery of this current batch
3513             mAlarmBatches.remove(0);
3514 
3515             final int N = batch.size();
3516             for (int i = 0; i < N; i++) {
3517                 Alarm alarm = batch.get(i);
3518 
3519                 if ((alarm.flags&AlarmManager.FLAG_ALLOW_WHILE_IDLE) != 0) {
3520                     // If this is an ALLOW_WHILE_IDLE alarm, we constrain how frequently the app can
3521                     // schedule such alarms.  The first such alarm from an app is always delivered.
3522                     final long lastTime = mLastAllowWhileIdleDispatch.get(alarm.creatorUid, -1);
3523                     final long minTime = lastTime + getWhileIdleMinIntervalLocked(alarm.creatorUid);
3524                     if (lastTime >= 0 && nowELAPSED < minTime) {
3525                         // Whoops, it hasn't been long enough since the last ALLOW_WHILE_IDLE
3526                         // alarm went off for this app.  Reschedule the alarm to be in the
3527                         // correct time period.
3528                         alarm.expectedWhenElapsed = alarm.whenElapsed = minTime;
3529                         if (alarm.maxWhenElapsed < minTime) {
3530                             alarm.maxWhenElapsed = minTime;
3531                         }
3532                         alarm.expectedMaxWhenElapsed = alarm.maxWhenElapsed;
3533                         if (RECORD_DEVICE_IDLE_ALARMS) {
3534                             IdleDispatchEntry ent = new IdleDispatchEntry();
3535                             ent.uid = alarm.uid;
3536                             ent.pkg = alarm.operation.getCreatorPackage();
3537                             ent.tag = alarm.operation.getTag("");
3538                             ent.op = "RESCHEDULE";
3539                             ent.elapsedRealtime = nowELAPSED;
3540                             ent.argRealtime = lastTime;
3541                             mAllowWhileIdleDispatches.add(ent);
3542                         }
3543                         setImplLocked(alarm, true, false);
3544                         continue;
3545                     }
3546                 }
3547                 if (isBackgroundRestricted(alarm)) {
3548                     // Alarms with FLAG_WAKE_FROM_IDLE or mPendingIdleUntil alarm are not deferred
3549                     if (DEBUG_BG_LIMIT) {
3550                         Slog.d(TAG, "Deferring alarm " + alarm + " due to user forced app standby");
3551                     }
3552                     ArrayList<Alarm> alarmsForUid = mPendingBackgroundAlarms.get(alarm.creatorUid);
3553                     if (alarmsForUid == null) {
3554                         alarmsForUid = new ArrayList<>();
3555                         mPendingBackgroundAlarms.put(alarm.creatorUid, alarmsForUid);
3556                     }
3557                     alarmsForUid.add(alarm);
3558                     continue;
3559                 }
3560 
3561                 alarm.count = 1;
3562                 triggerList.add(alarm);
3563                 if ((alarm.flags&AlarmManager.FLAG_WAKE_FROM_IDLE) != 0) {
3564                     EventLogTags.writeDeviceIdleWakeFromIdle(mPendingIdleUntil != null ? 1 : 0,
3565                             alarm.statsTag);
3566                 }
3567                 if (mPendingIdleUntil == alarm) {
3568                     mPendingIdleUntil = null;
3569                     rebatchAllAlarmsLocked(false);
3570                     restorePendingWhileIdleAlarmsLocked();
3571                 }
3572                 if (mNextWakeFromIdle == alarm) {
3573                     mNextWakeFromIdle = null;
3574                     rebatchAllAlarmsLocked(false);
3575                 }
3576 
3577                 // Recurring alarms may have passed several alarm intervals while the
3578                 // phone was asleep or off, so pass a trigger count when sending them.
3579                 if (alarm.repeatInterval > 0) {
3580                     // this adjustment will be zero if we're late by
3581                     // less than one full repeat interval
3582                     alarm.count += (nowELAPSED - alarm.expectedWhenElapsed) / alarm.repeatInterval;
3583                     // Also schedule its next recurrence
3584                     final long delta = alarm.count * alarm.repeatInterval;
3585                     final long nextElapsed = alarm.expectedWhenElapsed + delta;
3586                     setImplLocked(alarm.type, alarm.when + delta, nextElapsed, alarm.windowLength,
3587                             maxTriggerTime(nowELAPSED, nextElapsed, alarm.repeatInterval),
3588                             alarm.repeatInterval, alarm.operation, null, null, alarm.flags, true,
3589                             alarm.workSource, alarm.alarmClock, alarm.uid, alarm.packageName);
3590                 }
3591 
3592                 if (alarm.wakeup) {
3593                     hasWakeup = true;
3594                 }
3595 
3596                 // We removed an alarm clock. Let the caller recompute the next alarm clock.
3597                 if (alarm.alarmClock != null) {
3598                     mNextAlarmClockMayChange = true;
3599                 }
3600             }
3601         }
3602 
3603         // This is a new alarm delivery set; bump the sequence number to indicate that
3604         // all apps' alarm delivery classes should be recalculated.
3605         mCurrentSeq++;
3606         calculateDeliveryPriorities(triggerList);
3607         Collections.sort(triggerList, mAlarmDispatchComparator);
3608 
3609         if (localLOGV) {
3610             for (int i=0; i<triggerList.size(); i++) {
3611                 Slog.v(TAG, "Triggering alarm #" + i + ": " + triggerList.get(i));
3612             }
3613         }
3614 
3615         return hasWakeup;
3616     }
3617 
3618     /**
3619      * This Comparator sorts Alarms into increasing time order.
3620      */
3621     public static class IncreasingTimeOrder implements Comparator<Alarm> {
compare(Alarm a1, Alarm a2)3622         public int compare(Alarm a1, Alarm a2) {
3623             long when1 = a1.whenElapsed;
3624             long when2 = a2.whenElapsed;
3625             if (when1 > when2) {
3626                 return 1;
3627             }
3628             if (when1 < when2) {
3629                 return -1;
3630             }
3631             return 0;
3632         }
3633     }
3634 
3635     @VisibleForTesting
3636     static class Alarm {
3637         public final int type;
3638         public final long origWhen;
3639         public final boolean wakeup;
3640         public final PendingIntent operation;
3641         public final IAlarmListener listener;
3642         public final String listenerTag;
3643         public final String statsTag;
3644         public final WorkSource workSource;
3645         public final int flags;
3646         public final AlarmManager.AlarmClockInfo alarmClock;
3647         public final int uid;
3648         public final int creatorUid;
3649         public final String packageName;
3650         public final String sourcePackage;
3651         public int count;
3652         public long when;
3653         public long windowLength;
3654         public long whenElapsed;    // 'when' in the elapsed time base
3655         public long maxWhenElapsed; // also in the elapsed time base
3656         // Expected alarm expiry time before app standby deferring is applied.
3657         public long expectedWhenElapsed;
3658         public long expectedMaxWhenElapsed;
3659         public long repeatInterval;
3660         public PriorityClass priorityClass;
3661 
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)3662         public Alarm(int _type, long _when, long _whenElapsed, long _windowLength, long _maxWhen,
3663                 long _interval, PendingIntent _op, IAlarmListener _rec, String _listenerTag,
3664                 WorkSource _ws, int _flags, AlarmManager.AlarmClockInfo _info,
3665                 int _uid, String _pkgName) {
3666             type = _type;
3667             origWhen = _when;
3668             wakeup = _type == AlarmManager.ELAPSED_REALTIME_WAKEUP
3669                     || _type == AlarmManager.RTC_WAKEUP;
3670             when = _when;
3671             whenElapsed = _whenElapsed;
3672             expectedWhenElapsed = _whenElapsed;
3673             windowLength = _windowLength;
3674             maxWhenElapsed = expectedMaxWhenElapsed = clampPositive(_maxWhen);
3675             repeatInterval = _interval;
3676             operation = _op;
3677             listener = _rec;
3678             listenerTag = _listenerTag;
3679             statsTag = makeTag(_op, _listenerTag, _type);
3680             workSource = _ws;
3681             flags = _flags;
3682             alarmClock = _info;
3683             uid = _uid;
3684             packageName = _pkgName;
3685             sourcePackage = (operation != null) ? operation.getCreatorPackage() : packageName;
3686             creatorUid = (operation != null) ? operation.getCreatorUid() : uid;
3687         }
3688 
makeTag(PendingIntent pi, String tag, int type)3689         public static String makeTag(PendingIntent pi, String tag, int type) {
3690             final String alarmString = type == ELAPSED_REALTIME_WAKEUP || type == RTC_WAKEUP
3691                     ? "*walarm*:" : "*alarm*:";
3692             return (pi != null) ? pi.getTag(alarmString) : (alarmString + tag);
3693         }
3694 
makeWakeupEvent(long nowRTC)3695         public WakeupEvent makeWakeupEvent(long nowRTC) {
3696             return new WakeupEvent(nowRTC, creatorUid,
3697                     (operation != null)
3698                         ? operation.getIntent().getAction()
3699                         : ("<listener>:" + listenerTag));
3700         }
3701 
3702         // Returns true if either matches
matches(PendingIntent pi, IAlarmListener rec)3703         public boolean matches(PendingIntent pi, IAlarmListener rec) {
3704             return (operation != null)
3705                     ? operation.equals(pi)
3706                     : rec != null && listener.asBinder().equals(rec.asBinder());
3707         }
3708 
matches(String packageName)3709         public boolean matches(String packageName) {
3710             return packageName.equals(sourcePackage);
3711         }
3712 
3713         @Override
toString()3714         public String toString() {
3715             StringBuilder sb = new StringBuilder(128);
3716             sb.append("Alarm{");
3717             sb.append(Integer.toHexString(System.identityHashCode(this)));
3718             sb.append(" type ");
3719             sb.append(type);
3720             sb.append(" when ");
3721             sb.append(when);
3722             sb.append(" ");
3723             sb.append(sourcePackage);
3724             sb.append('}');
3725             return sb.toString();
3726         }
3727 
dump(PrintWriter pw, String prefix, long nowELAPSED, long nowRTC, SimpleDateFormat sdf)3728         public void dump(PrintWriter pw, String prefix, long nowELAPSED, long nowRTC,
3729                 SimpleDateFormat sdf) {
3730             final boolean isRtc = (type == RTC || type == RTC_WAKEUP);
3731             pw.print(prefix); pw.print("tag="); pw.println(statsTag);
3732             pw.print(prefix); pw.print("type="); pw.print(type);
3733                     pw.print(" expectedWhenElapsed="); TimeUtils.formatDuration(
3734                     expectedWhenElapsed, nowELAPSED, pw);
3735                     pw.print(" expectedMaxWhenElapsed="); TimeUtils.formatDuration(
3736                     expectedMaxWhenElapsed, nowELAPSED, pw);
3737                     pw.print(" whenElapsed="); TimeUtils.formatDuration(whenElapsed,
3738                             nowELAPSED, pw);
3739                     pw.print(" maxWhenElapsed="); TimeUtils.formatDuration(maxWhenElapsed,
3740                             nowELAPSED, pw);
3741                     pw.print(" when=");
3742                     if (isRtc) {
3743                         pw.print(sdf.format(new Date(when)));
3744                     } else {
3745                         TimeUtils.formatDuration(when, nowELAPSED, pw);
3746                     }
3747                     pw.println();
3748             pw.print(prefix); pw.print("window="); TimeUtils.formatDuration(windowLength, pw);
3749                     pw.print(" repeatInterval="); pw.print(repeatInterval);
3750                     pw.print(" count="); pw.print(count);
3751                     pw.print(" flags=0x"); pw.println(Integer.toHexString(flags));
3752             if (alarmClock != null) {
3753                 pw.print(prefix); pw.println("Alarm clock:");
3754                 pw.print(prefix); pw.print("  triggerTime=");
3755                 pw.println(sdf.format(new Date(alarmClock.getTriggerTime())));
3756                 pw.print(prefix); pw.print("  showIntent="); pw.println(alarmClock.getShowIntent());
3757             }
3758             pw.print(prefix); pw.print("operation="); pw.println(operation);
3759             if (listener != null) {
3760                 pw.print(prefix); pw.print("listener="); pw.println(listener.asBinder());
3761             }
3762         }
3763 
dumpDebug(ProtoOutputStream proto, long fieldId, long nowElapsed, long nowRTC)3764         public void dumpDebug(ProtoOutputStream proto, long fieldId, long nowElapsed,
3765                 long nowRTC) {
3766             final long token = proto.start(fieldId);
3767 
3768             proto.write(AlarmProto.TAG, statsTag);
3769             proto.write(AlarmProto.TYPE, type);
3770             proto.write(AlarmProto.TIME_UNTIL_WHEN_ELAPSED_MS, whenElapsed - nowElapsed);
3771             proto.write(AlarmProto.WINDOW_LENGTH_MS, windowLength);
3772             proto.write(AlarmProto.REPEAT_INTERVAL_MS, repeatInterval);
3773             proto.write(AlarmProto.COUNT, count);
3774             proto.write(AlarmProto.FLAGS, flags);
3775             if (alarmClock != null) {
3776                 alarmClock.dumpDebug(proto, AlarmProto.ALARM_CLOCK);
3777             }
3778             if (operation != null) {
3779                 operation.dumpDebug(proto, AlarmProto.OPERATION);
3780             }
3781             if (listener != null) {
3782                 proto.write(AlarmProto.LISTENER, listener.asBinder().toString());
3783             }
3784 
3785             proto.end(token);
3786         }
3787     }
3788 
recordWakeupAlarms(ArrayList<Batch> batches, long nowELAPSED, long nowRTC)3789     void recordWakeupAlarms(ArrayList<Batch> batches, long nowELAPSED, long nowRTC) {
3790         final int numBatches = batches.size();
3791         for (int nextBatch = 0; nextBatch < numBatches; nextBatch++) {
3792             Batch b = batches.get(nextBatch);
3793             if (b.start > nowELAPSED) {
3794                 break;
3795             }
3796 
3797             final int numAlarms = b.alarms.size();
3798             for (int nextAlarm = 0; nextAlarm < numAlarms; nextAlarm++) {
3799                 Alarm a = b.alarms.get(nextAlarm);
3800                 mRecentWakeups.add(a.makeWakeupEvent(nowRTC));
3801             }
3802         }
3803     }
3804 
currentNonWakeupFuzzLocked(long nowELAPSED)3805     long currentNonWakeupFuzzLocked(long nowELAPSED) {
3806         long timeSinceOn = nowELAPSED - mNonInteractiveStartTime;
3807         if (timeSinceOn < 5*60*1000) {
3808             // If the screen has been off for 5 minutes, only delay by at most two minutes.
3809             return 2*60*1000;
3810         } else if (timeSinceOn < 30*60*1000) {
3811             // If the screen has been off for 30 minutes, only delay by at most 15 minutes.
3812             return 15*60*1000;
3813         } else {
3814             // Otherwise, we will delay by at most an hour.
3815             return 60*60*1000;
3816         }
3817     }
3818 
fuzzForDuration(long duration)3819     static int fuzzForDuration(long duration) {
3820         if (duration < 15*60*1000) {
3821             // If the duration until the time is less than 15 minutes, the maximum fuzz
3822             // is the duration.
3823             return (int)duration;
3824         } else if (duration < 90*60*1000) {
3825             // If duration is less than 1 1/2 hours, the maximum fuzz is 15 minutes,
3826             return 15*60*1000;
3827         } else {
3828             // Otherwise, we will fuzz by at most half an hour.
3829             return 30*60*1000;
3830         }
3831     }
3832 
checkAllowNonWakeupDelayLocked(long nowELAPSED)3833     boolean checkAllowNonWakeupDelayLocked(long nowELAPSED) {
3834         if (mInteractive) {
3835             return false;
3836         }
3837         if (mLastAlarmDeliveryTime <= 0) {
3838             return false;
3839         }
3840         if (mPendingNonWakeupAlarms.size() > 0 && mNextNonWakeupDeliveryTime < nowELAPSED) {
3841             // This is just a little paranoia, if somehow we have pending non-wakeup alarms
3842             // and the next delivery time is in the past, then just deliver them all.  This
3843             // avoids bugs where we get stuck in a loop trying to poll for alarms.
3844             return false;
3845         }
3846         long timeSinceLast = nowELAPSED - mLastAlarmDeliveryTime;
3847         return timeSinceLast <= currentNonWakeupFuzzLocked(nowELAPSED);
3848     }
3849 
deliverAlarmsLocked(ArrayList<Alarm> triggerList, long nowELAPSED)3850     void deliverAlarmsLocked(ArrayList<Alarm> triggerList, long nowELAPSED) {
3851         mLastAlarmDeliveryTime = nowELAPSED;
3852         for (int i=0; i<triggerList.size(); i++) {
3853             Alarm alarm = triggerList.get(i);
3854             final boolean allowWhileIdle = (alarm.flags&AlarmManager.FLAG_ALLOW_WHILE_IDLE) != 0;
3855             if (alarm.wakeup) {
3856               Trace.traceBegin(Trace.TRACE_TAG_POWER, "Dispatch wakeup alarm to " + alarm.packageName);
3857             } else {
3858               Trace.traceBegin(Trace.TRACE_TAG_POWER, "Dispatch non-wakeup alarm to " + alarm.packageName);
3859             }
3860             try {
3861                 if (localLOGV) {
3862                     Slog.v(TAG, "sending alarm " + alarm);
3863                 }
3864                 if (RECORD_ALARMS_IN_HISTORY) {
3865                     ActivityManager.noteAlarmStart(alarm.operation, alarm.workSource, alarm.uid,
3866                             alarm.statsTag);
3867                 }
3868                 mDeliveryTracker.deliverLocked(alarm, nowELAPSED, allowWhileIdle);
3869             } catch (RuntimeException e) {
3870                 Slog.w(TAG, "Failure sending alarm.", e);
3871             }
3872             Trace.traceEnd(Trace.TRACE_TAG_POWER);
3873             decrementAlarmCount(alarm.uid, 1);
3874         }
3875     }
3876 
isExemptFromAppStandby(Alarm a)3877     private boolean isExemptFromAppStandby(Alarm a) {
3878         return a.alarmClock != null || UserHandle.isCore(a.creatorUid)
3879                 || (a.flags & FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED) != 0;
3880     }
3881 
3882     @VisibleForTesting
3883     static class Injector {
3884         private long mNativeData;
3885         private Context mContext;
3886 
Injector(Context context)3887         Injector(Context context) {
3888             mContext = context;
3889         }
3890 
init()3891         void init() {
3892             mNativeData = AlarmManagerService.init();
3893         }
3894 
waitForAlarm()3895         int waitForAlarm() {
3896             return AlarmManagerService.waitForAlarm(mNativeData);
3897         }
3898 
isAlarmDriverPresent()3899         boolean isAlarmDriverPresent() {
3900             return mNativeData != 0;
3901         }
3902 
setAlarm(int type, long millis)3903         void setAlarm(int type, long millis) {
3904             // The kernel never triggers alarms with negative wakeup times
3905             // so we ensure they are positive.
3906             final long alarmSeconds, alarmNanoseconds;
3907             if (millis < 0) {
3908                 alarmSeconds = 0;
3909                 alarmNanoseconds = 0;
3910             } else {
3911                 alarmSeconds = millis / 1000;
3912                 alarmNanoseconds = (millis % 1000) * 1000 * 1000;
3913             }
3914 
3915             final int result = AlarmManagerService.set(mNativeData, type, alarmSeconds,
3916                     alarmNanoseconds);
3917             if (result != 0) {
3918                 final long nowElapsed = SystemClock.elapsedRealtime();
3919                 Slog.wtf(TAG, "Unable to set kernel alarm, now=" + nowElapsed
3920                         + " type=" + type + " @ (" + alarmSeconds + "," + alarmNanoseconds
3921                         + "), ret = " + result + " = " + Os.strerror(result));
3922             }
3923         }
3924 
getNextAlarm(int type)3925         long getNextAlarm(int type) {
3926             return AlarmManagerService.getNextAlarm(mNativeData, type);
3927         }
3928 
setKernelTimezone(int minutesWest)3929         void setKernelTimezone(int minutesWest) {
3930             AlarmManagerService.setKernelTimezone(mNativeData, minutesWest);
3931         }
3932 
setKernelTime(long millis)3933         void setKernelTime(long millis) {
3934             if (mNativeData != 0) {
3935                 AlarmManagerService.setKernelTime(mNativeData, millis);
3936             }
3937         }
3938 
close()3939         void close() {
3940             AlarmManagerService.close(mNativeData);
3941         }
3942 
getElapsedRealtime()3943         long getElapsedRealtime() {
3944             return SystemClock.elapsedRealtime();
3945         }
3946 
getCurrentTimeMillis()3947         long getCurrentTimeMillis() {
3948             return System.currentTimeMillis();
3949         }
3950 
getAlarmWakeLock()3951         PowerManager.WakeLock getAlarmWakeLock() {
3952             final PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
3953             return pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*alarm*");
3954         }
3955 
getSystemUiUid()3956         int getSystemUiUid() {
3957             PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
3958             return pm.getPackageUid(pm.getSystemUiServiceComponent().getPackageName(),
3959                     MATCH_SYSTEM_ONLY, USER_SYSTEM);
3960         }
3961 
getClockReceiver(AlarmManagerService service)3962         ClockReceiver getClockReceiver(AlarmManagerService service) {
3963             return service.new ClockReceiver();
3964         }
3965     }
3966 
3967     private class AlarmThread extends Thread
3968     {
3969         private int mFalseWakeups;
3970         private int mWtfThreshold;
AlarmThread()3971         public AlarmThread()
3972         {
3973             super("AlarmManager");
3974             mFalseWakeups = 0;
3975             mWtfThreshold = 100;
3976         }
3977 
run()3978         public void run()
3979         {
3980             ArrayList<Alarm> triggerList = new ArrayList<Alarm>();
3981 
3982             while (true)
3983             {
3984                 int result = mInjector.waitForAlarm();
3985                 final long nowRTC = mInjector.getCurrentTimeMillis();
3986                 final long nowELAPSED = mInjector.getElapsedRealtime();
3987                 synchronized (mLock) {
3988                     mLastWakeup = nowELAPSED;
3989                 }
3990                 if (result == 0) {
3991                     Slog.wtf(TAG, "waitForAlarm returned 0, nowRTC = " + nowRTC
3992                             + ", nowElapsed = " + nowELAPSED);
3993                 }
3994                 triggerList.clear();
3995 
3996                 if ((result & TIME_CHANGED_MASK) != 0) {
3997                     // The kernel can give us spurious time change notifications due to
3998                     // small adjustments it makes internally; we want to filter those out.
3999                     final long lastTimeChangeClockTime;
4000                     final long expectedClockTime;
4001                     synchronized (mLock) {
4002                         lastTimeChangeClockTime = mLastTimeChangeClockTime;
4003                         expectedClockTime = lastTimeChangeClockTime
4004                                 + (nowELAPSED - mLastTimeChangeRealtime);
4005                     }
4006                     if (lastTimeChangeClockTime == 0 || nowRTC < (expectedClockTime-1000)
4007                             || nowRTC > (expectedClockTime+1000)) {
4008                         // The change is by at least +/- 1000 ms (or this is the first change),
4009                         // let's do it!
4010                         if (DEBUG_BATCH) {
4011                             Slog.v(TAG, "Time changed notification from kernel; rebatching");
4012                         }
4013                         // StatsLog requires currentTimeMillis(), which == nowRTC to within usecs.
4014                         FrameworkStatsLog.write(FrameworkStatsLog.WALL_CLOCK_TIME_SHIFTED, nowRTC);
4015                         removeImpl(null, mTimeTickTrigger);
4016                         removeImpl(mDateChangeSender, null);
4017                         rebatchAllAlarms();
4018                         mClockReceiver.scheduleTimeTickEvent();
4019                         mClockReceiver.scheduleDateChangedEvent();
4020                         synchronized (mLock) {
4021                             mNumTimeChanged++;
4022                             mLastTimeChangeClockTime = nowRTC;
4023                             mLastTimeChangeRealtime = nowELAPSED;
4024                         }
4025                         Intent intent = new Intent(Intent.ACTION_TIME_CHANGED);
4026                         intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
4027                                 | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
4028                                 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
4029                                 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4030                         getContext().sendBroadcastAsUser(intent, UserHandle.ALL);
4031 
4032                         // The world has changed on us, so we need to re-evaluate alarms
4033                         // regardless of whether the kernel has told us one went off.
4034                         result |= IS_WAKEUP_MASK;
4035                     }
4036                 }
4037 
4038                 if (result != TIME_CHANGED_MASK) {
4039                     // If this was anything besides just a time change, then figure what if
4040                     // anything to do about alarms.
4041                     synchronized (mLock) {
4042                         if (localLOGV) Slog.v(
4043                             TAG, "Checking for alarms... rtc=" + nowRTC
4044                             + ", elapsed=" + nowELAPSED);
4045 
4046                         if (WAKEUP_STATS) {
4047                             if ((result & IS_WAKEUP_MASK) != 0) {
4048                                 long newEarliest = nowRTC - RECENT_WAKEUP_PERIOD;
4049                                 int n = 0;
4050                                 for (WakeupEvent event : mRecentWakeups) {
4051                                     if (event.when > newEarliest) break;
4052                                     n++; // number of now-stale entries at the list head
4053                                 }
4054                                 for (int i = 0; i < n; i++) {
4055                                     mRecentWakeups.remove();
4056                                 }
4057 
4058                                 recordWakeupAlarms(mAlarmBatches, nowELAPSED, nowRTC);
4059                             }
4060                         }
4061 
4062                         mLastTrigger = nowELAPSED;
4063                         boolean hasWakeup = triggerAlarmsLocked(triggerList, nowELAPSED);
4064                         if (!hasWakeup && checkAllowNonWakeupDelayLocked(nowELAPSED)) {
4065                             // if there are no wakeup alarms and the screen is off, we can
4066                             // delay what we have so far until the future.
4067                             if (mPendingNonWakeupAlarms.size() == 0) {
4068                                 mStartCurrentDelayTime = nowELAPSED;
4069                                 mNextNonWakeupDeliveryTime = nowELAPSED
4070                                         + ((currentNonWakeupFuzzLocked(nowELAPSED)*3)/2);
4071                             }
4072                             mPendingNonWakeupAlarms.addAll(triggerList);
4073                             mNumDelayedAlarms += triggerList.size();
4074                             rescheduleKernelAlarmsLocked();
4075                             updateNextAlarmClockLocked();
4076                         } else {
4077                             // now deliver the alarm intents; if there are pending non-wakeup
4078                             // alarms, we need to merge them in to the list.  note we don't
4079                             // just deliver them first because we generally want non-wakeup
4080                             // alarms delivered after wakeup alarms.
4081                             if (mPendingNonWakeupAlarms.size() > 0) {
4082                                 calculateDeliveryPriorities(mPendingNonWakeupAlarms);
4083                                 triggerList.addAll(mPendingNonWakeupAlarms);
4084                                 Collections.sort(triggerList, mAlarmDispatchComparator);
4085                                 final long thisDelayTime = nowELAPSED - mStartCurrentDelayTime;
4086                                 mTotalDelayTime += thisDelayTime;
4087                                 if (mMaxDelayTime < thisDelayTime) {
4088                                     mMaxDelayTime = thisDelayTime;
4089                                 }
4090                                 mPendingNonWakeupAlarms.clear();
4091                             }
4092                             if (mLastTimeChangeRealtime != nowELAPSED && triggerList.isEmpty()) {
4093                                 if (++mFalseWakeups >= mWtfThreshold) {
4094                                     Slog.wtf(TAG, "Too many (" + mFalseWakeups
4095                                             + ") false wakeups, nowElapsed=" + nowELAPSED);
4096                                     if (mWtfThreshold < 100_000) {
4097                                         mWtfThreshold *= 10;
4098                                     } else {
4099                                         mFalseWakeups = 0;
4100                                     }
4101                                 }
4102                             }
4103                             final ArraySet<Pair<String, Integer>> triggerPackages =
4104                                     new ArraySet<>();
4105                             for (int i = 0; i < triggerList.size(); i++) {
4106                                 final Alarm a = triggerList.get(i);
4107                                 if (!isExemptFromAppStandby(a)) {
4108                                     triggerPackages.add(Pair.create(
4109                                             a.sourcePackage, UserHandle.getUserId(a.creatorUid)));
4110                                 }
4111                             }
4112                             deliverAlarmsLocked(triggerList, nowELAPSED);
4113                             reorderAlarmsBasedOnStandbyBuckets(triggerPackages);
4114                             rescheduleKernelAlarmsLocked();
4115                             updateNextAlarmClockLocked();
4116                         }
4117                     }
4118 
4119                 } else {
4120                     // Just in case -- even though no wakeup flag was set, make sure
4121                     // we have updated the kernel to the next alarm time.
4122                     synchronized (mLock) {
4123                         rescheduleKernelAlarmsLocked();
4124                     }
4125                 }
4126             }
4127         }
4128     }
4129 
4130     /**
4131      * Attribute blame for a WakeLock.
4132      * @param ws WorkSource to attribute blame.
4133      * @param knownUid attribution uid; < 0 values are ignored.
4134      */
setWakelockWorkSource(WorkSource ws, int knownUid, String tag, boolean first)4135     void setWakelockWorkSource(WorkSource ws, int knownUid, String tag, boolean first) {
4136         try {
4137             mWakeLock.setHistoryTag(first ? tag : null);
4138 
4139             if (ws != null) {
4140                 mWakeLock.setWorkSource(ws);
4141                 return;
4142             }
4143 
4144             if (knownUid >= 0) {
4145                 mWakeLock.setWorkSource(new WorkSource(knownUid));
4146                 return;
4147             }
4148         } catch (Exception e) {
4149         }
4150 
4151         // Something went wrong; fall back to attributing the lock to the OS
4152         mWakeLock.setWorkSource(null);
4153     }
4154 
getAlarmAttributionUid(Alarm alarm)4155     private static int getAlarmAttributionUid(Alarm alarm) {
4156         if (alarm.workSource != null && !alarm.workSource.isEmpty()) {
4157             return alarm.workSource.getAttributionUid();
4158         }
4159 
4160         return alarm.creatorUid;
4161     }
4162 
4163     @VisibleForTesting
4164     class AlarmHandler extends Handler {
4165         public static final int ALARM_EVENT = 1;
4166         public static final int SEND_NEXT_ALARM_CLOCK_CHANGED = 2;
4167         public static final int LISTENER_TIMEOUT = 3;
4168         public static final int REPORT_ALARMS_ACTIVE = 4;
4169         public static final int APP_STANDBY_BUCKET_CHANGED = 5;
4170         public static final int CHARGING_STATUS_CHANGED = 6;
4171         public static final int REMOVE_FOR_STOPPED = 7;
4172         public static final int REMOVE_FOR_CANCELED = 8;
4173 
AlarmHandler()4174         AlarmHandler() {
4175             super(Looper.myLooper());
4176         }
4177 
postRemoveForStopped(int uid)4178         public void postRemoveForStopped(int uid) {
4179             obtainMessage(REMOVE_FOR_STOPPED, uid, 0).sendToTarget();
4180         }
4181 
4182         @Override
handleMessage(Message msg)4183         public void handleMessage(Message msg) {
4184             switch (msg.what) {
4185                 case ALARM_EVENT: {
4186                     // This code is used when the kernel timer driver is not available, which
4187                     // shouldn't happen. Here, we try our best to simulate it, which may be useful
4188                     // when porting Android to a new device. Note that we can't wake up a device
4189                     // this way, so WAKE_UP alarms will be delivered only when the device is awake.
4190                     ArrayList<Alarm> triggerList = new ArrayList<Alarm>();
4191                     synchronized (mLock) {
4192                         final long nowELAPSED = mInjector.getElapsedRealtime();
4193                         triggerAlarmsLocked(triggerList, nowELAPSED);
4194                         updateNextAlarmClockLocked();
4195                     }
4196 
4197                     // now trigger the alarms without the lock held
4198                     for (int i=0; i<triggerList.size(); i++) {
4199                         Alarm alarm = triggerList.get(i);
4200                         try {
4201                             alarm.operation.send();
4202                         } catch (PendingIntent.CanceledException e) {
4203                             if (alarm.repeatInterval > 0) {
4204                                 // This IntentSender is no longer valid, but this
4205                                 // is a repeating alarm, so toss the hoser.
4206                                 removeImpl(alarm.operation, null);
4207                             }
4208                         }
4209                         decrementAlarmCount(alarm.uid, 1);
4210                     }
4211                     break;
4212                 }
4213 
4214                 case SEND_NEXT_ALARM_CLOCK_CHANGED:
4215                     sendNextAlarmClockChanged();
4216                     break;
4217 
4218                 case LISTENER_TIMEOUT:
4219                     mDeliveryTracker.alarmTimedOut((IBinder) msg.obj);
4220                     break;
4221 
4222                 case REPORT_ALARMS_ACTIVE:
4223                     if (mLocalDeviceIdleController != null) {
4224                         mLocalDeviceIdleController.setAlarmsActive(msg.arg1 != 0);
4225                     }
4226                     break;
4227 
4228                 case CHARGING_STATUS_CHANGED:
4229                     synchronized (mLock) {
4230                         mAppStandbyParole = (Boolean) msg.obj;
4231                         if (reorderAlarmsBasedOnStandbyBuckets(null)) {
4232                             rescheduleKernelAlarmsLocked();
4233                             updateNextAlarmClockLocked();
4234                         }
4235                     }
4236                     break;
4237 
4238                 case APP_STANDBY_BUCKET_CHANGED:
4239                     synchronized (mLock) {
4240                         final ArraySet<Pair<String, Integer>> filterPackages = new ArraySet<>();
4241                         filterPackages.add(Pair.create((String) msg.obj, msg.arg1));
4242                         if (reorderAlarmsBasedOnStandbyBuckets(filterPackages)) {
4243                             rescheduleKernelAlarmsLocked();
4244                             updateNextAlarmClockLocked();
4245                         }
4246                     }
4247                     break;
4248 
4249                 case REMOVE_FOR_STOPPED:
4250                     synchronized (mLock) {
4251                         removeForStoppedLocked(msg.arg1);
4252                     }
4253                     break;
4254 
4255                 case REMOVE_FOR_CANCELED:
4256                     final PendingIntent operation = (PendingIntent) msg.obj;
4257                     synchronized (mLock) {
4258                         removeLocked(operation, null);
4259                     }
4260                     break;
4261 
4262                 default:
4263                     // nope, just ignore it
4264                     break;
4265             }
4266         }
4267     }
4268 
4269     @VisibleForTesting
4270     class ChargingReceiver extends BroadcastReceiver {
ChargingReceiver()4271         ChargingReceiver() {
4272             IntentFilter filter = new IntentFilter();
4273             filter.addAction(BatteryManager.ACTION_CHARGING);
4274             filter.addAction(BatteryManager.ACTION_DISCHARGING);
4275             getContext().registerReceiver(this, filter);
4276         }
4277 
4278         @Override
onReceive(Context context, Intent intent)4279         public void onReceive(Context context, Intent intent) {
4280             final String action = intent.getAction();
4281             final boolean charging;
4282             if (BatteryManager.ACTION_CHARGING.equals(action)) {
4283                 if (DEBUG_STANDBY) {
4284                     Slog.d(TAG, "Device is charging.");
4285                 }
4286                 charging = true;
4287             } else {
4288                 if (DEBUG_STANDBY) {
4289                     Slog.d(TAG, "Disconnected from power.");
4290                 }
4291                 charging = false;
4292             }
4293             mHandler.removeMessages(AlarmHandler.CHARGING_STATUS_CHANGED);
4294             mHandler.obtainMessage(AlarmHandler.CHARGING_STATUS_CHANGED, charging)
4295                     .sendToTarget();
4296         }
4297     }
4298 
4299     @VisibleForTesting
4300     class ClockReceiver extends BroadcastReceiver {
ClockReceiver()4301         public ClockReceiver() {
4302             IntentFilter filter = new IntentFilter();
4303             filter.addAction(Intent.ACTION_DATE_CHANGED);
4304             getContext().registerReceiver(this, filter);
4305         }
4306 
4307         @Override
onReceive(Context context, Intent intent)4308         public void onReceive(Context context, Intent intent) {
4309             if (intent.getAction().equals(Intent.ACTION_DATE_CHANGED)) {
4310                 // Since the kernel does not keep track of DST, we need to
4311                 // reset the TZ information at the beginning of each day
4312                 // based off of the current Zone gmt offset + userspace tracked
4313                 // daylight savings information.
4314                 TimeZone zone = TimeZone.getTimeZone(SystemProperties.get(TIMEZONE_PROPERTY));
4315                 int gmtOffset = zone.getOffset(mInjector.getCurrentTimeMillis());
4316                 mInjector.setKernelTimezone(-(gmtOffset / 60000));
4317                 scheduleDateChangedEvent();
4318             }
4319         }
4320 
scheduleTimeTickEvent()4321         public void scheduleTimeTickEvent() {
4322             final long currentTime = mInjector.getCurrentTimeMillis();
4323             final long nextTime = 60000 * ((currentTime / 60000) + 1);
4324 
4325             // Schedule this event for the amount of time that it would take to get to
4326             // the top of the next minute.
4327             final long tickEventDelay = nextTime - currentTime;
4328 
4329             final WorkSource workSource = null; // Let system take blame for time tick events.
4330             setImpl(ELAPSED_REALTIME, mInjector.getElapsedRealtime() + tickEventDelay, 0,
4331                     0, null, mTimeTickTrigger, "TIME_TICK", AlarmManager.FLAG_STANDALONE,
4332                     workSource, null, Process.myUid(), "android");
4333 
4334             // Finally, remember when we set the tick alarm
4335             synchronized (mLock) {
4336                 mLastTickSet = currentTime;
4337             }
4338         }
4339 
scheduleDateChangedEvent()4340         public void scheduleDateChangedEvent() {
4341             Calendar calendar = Calendar.getInstance();
4342             calendar.setTimeInMillis(mInjector.getCurrentTimeMillis());
4343             calendar.set(Calendar.HOUR_OF_DAY, 0);
4344             calendar.set(Calendar.MINUTE, 0);
4345             calendar.set(Calendar.SECOND, 0);
4346             calendar.set(Calendar.MILLISECOND, 0);
4347             calendar.add(Calendar.DAY_OF_MONTH, 1);
4348 
4349             final WorkSource workSource = null; // Let system take blame for date change events.
4350             setImpl(RTC, calendar.getTimeInMillis(), 0, 0, mDateChangeSender, null, null,
4351                     AlarmManager.FLAG_STANDALONE, workSource, null,
4352                     Process.myUid(), "android");
4353         }
4354     }
4355 
4356     class InteractiveStateReceiver extends BroadcastReceiver {
InteractiveStateReceiver()4357         public InteractiveStateReceiver() {
4358             IntentFilter filter = new IntentFilter();
4359             filter.addAction(Intent.ACTION_SCREEN_OFF);
4360             filter.addAction(Intent.ACTION_SCREEN_ON);
4361             filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
4362             getContext().registerReceiver(this, filter);
4363         }
4364 
4365         @Override
onReceive(Context context, Intent intent)4366         public void onReceive(Context context, Intent intent) {
4367             synchronized (mLock) {
4368                 interactiveStateChangedLocked(Intent.ACTION_SCREEN_ON.equals(intent.getAction()));
4369             }
4370         }
4371     }
4372 
4373     class UninstallReceiver extends BroadcastReceiver {
UninstallReceiver()4374         public UninstallReceiver() {
4375             IntentFilter filter = new IntentFilter();
4376             filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
4377             filter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
4378             filter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4379             filter.addDataScheme("package");
4380             getContext().registerReceiver(this, filter);
4381              // Register for events related to sdcard installation.
4382             IntentFilter sdFilter = new IntentFilter();
4383             sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
4384             sdFilter.addAction(Intent.ACTION_USER_STOPPED);
4385             sdFilter.addAction(Intent.ACTION_UID_REMOVED);
4386             getContext().registerReceiver(this, sdFilter);
4387         }
4388 
4389         @Override
onReceive(Context context, Intent intent)4390         public void onReceive(Context context, Intent intent) {
4391             final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
4392             synchronized (mLock) {
4393                 String pkgList[] = null;
4394                 switch (intent.getAction()) {
4395                     case Intent.ACTION_QUERY_PACKAGE_RESTART:
4396                         pkgList = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4397                         for (String packageName : pkgList) {
4398                             if (lookForPackageLocked(packageName)) {
4399                                 setResultCode(Activity.RESULT_OK);
4400                                 return;
4401                             }
4402                         }
4403                         return;
4404                     case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
4405                         pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
4406                         break;
4407                     case Intent.ACTION_USER_STOPPED:
4408                         final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
4409                         if (userHandle >= 0) {
4410                             removeUserLocked(userHandle);
4411                             mAppWakeupHistory.removeForUser(userHandle);
4412                         }
4413                         return;
4414                     case Intent.ACTION_UID_REMOVED:
4415                         if (uid >= 0) {
4416                             mLastAllowWhileIdleDispatch.delete(uid);
4417                             mUseAllowWhileIdleShortTime.delete(uid);
4418                         }
4419                         return;
4420                     case Intent.ACTION_PACKAGE_REMOVED:
4421                         if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
4422                             // This package is being updated; don't kill its alarms.
4423                             return;
4424                         }
4425                         // Intentional fall-through.
4426                     case Intent.ACTION_PACKAGE_RESTARTED:
4427                         final Uri data = intent.getData();
4428                         if (data != null) {
4429                             final String pkg = data.getSchemeSpecificPart();
4430                             if (pkg != null) {
4431                                 pkgList = new String[]{pkg};
4432                             }
4433                         }
4434                         break;
4435                 }
4436                 if (pkgList != null && (pkgList.length > 0)) {
4437                     for (String pkg : pkgList) {
4438                         if (uid >= 0) {
4439                             // package-removed and package-restarted case
4440                             mAppWakeupHistory.removeForPackage(pkg, UserHandle.getUserId(uid));
4441                             removeLocked(uid);
4442                         } else {
4443                             // external-applications-unavailable case
4444                             removeLocked(pkg);
4445                         }
4446                         mPriorities.remove(pkg);
4447                         for (int i=mBroadcastStats.size()-1; i>=0; i--) {
4448                             ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(i);
4449                             if (uidStats.remove(pkg) != null) {
4450                                 if (uidStats.size() <= 0) {
4451                                     mBroadcastStats.removeAt(i);
4452                                 }
4453                             }
4454                         }
4455                     }
4456                 }
4457             }
4458         }
4459     }
4460 
4461     final class UidObserver extends IUidObserver.Stub {
onUidStateChanged(int uid, int procState, long procStateSeq, int capability)4462         @Override public void onUidStateChanged(int uid, int procState, long procStateSeq,
4463             int capability) {
4464         }
4465 
onUidGone(int uid, boolean disabled)4466         @Override public void onUidGone(int uid, boolean disabled) {
4467             if (disabled) {
4468                 mHandler.postRemoveForStopped(uid);
4469             }
4470         }
4471 
onUidActive(int uid)4472         @Override public void onUidActive(int uid) {
4473         }
4474 
onUidIdle(int uid, boolean disabled)4475         @Override public void onUidIdle(int uid, boolean disabled) {
4476             if (disabled) {
4477                 mHandler.postRemoveForStopped(uid);
4478             }
4479         }
4480 
onUidCachedChanged(int uid, boolean cached)4481         @Override public void onUidCachedChanged(int uid, boolean cached) {
4482         }
4483     }
4484 
4485     /**
4486      * Tracking of app assignments to standby buckets
4487      */
4488     private final class AppStandbyTracker extends
4489             AppIdleStateChangeListener {
4490         @Override
onAppIdleStateChanged(final String packageName, final @UserIdInt int userId, boolean idle, int bucket, int reason)4491         public void onAppIdleStateChanged(final String packageName, final @UserIdInt int userId,
4492                 boolean idle, int bucket, int reason) {
4493             if (DEBUG_STANDBY) {
4494                 Slog.d(TAG, "Package " + packageName + " for user " + userId + " now in bucket " +
4495                         bucket);
4496             }
4497             mHandler.removeMessages(AlarmHandler.APP_STANDBY_BUCKET_CHANGED);
4498             mHandler.obtainMessage(AlarmHandler.APP_STANDBY_BUCKET_CHANGED, userId, -1, packageName)
4499                     .sendToTarget();
4500         }
4501     }
4502 
4503     private final Listener mForceAppStandbyListener = new Listener() {
4504         @Override
4505         public void unblockAllUnrestrictedAlarms() {
4506             synchronized (mLock) {
4507                 sendAllUnrestrictedPendingBackgroundAlarmsLocked();
4508             }
4509         }
4510 
4511         @Override
4512         public void unblockAlarmsForUid(int uid) {
4513             synchronized (mLock) {
4514                 sendPendingBackgroundAlarmsLocked(uid, null);
4515             }
4516         }
4517 
4518         @Override
4519         public void unblockAlarmsForUidPackage(int uid, String packageName) {
4520             synchronized (mLock) {
4521                 sendPendingBackgroundAlarmsLocked(uid, packageName);
4522             }
4523         }
4524 
4525         @Override
4526         public void onUidForeground(int uid, boolean foreground) {
4527             synchronized (mLock) {
4528                 if (foreground) {
4529                     mUseAllowWhileIdleShortTime.put(uid, true);
4530 
4531                     // Note we don't have to drain the pending while-idle alarms here, because
4532                     // this event should coincide with unblockAlarmsForUid().
4533                 }
4534             }
4535         }
4536     };
4537 
getStatsLocked(PendingIntent pi)4538     private final BroadcastStats getStatsLocked(PendingIntent pi) {
4539         String pkg = pi.getCreatorPackage();
4540         int uid = pi.getCreatorUid();
4541         return getStatsLocked(uid, pkg);
4542     }
4543 
getStatsLocked(int uid, String pkgName)4544     private final BroadcastStats getStatsLocked(int uid, String pkgName) {
4545         ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.get(uid);
4546         if (uidStats == null) {
4547             uidStats = new ArrayMap<String, BroadcastStats>();
4548             mBroadcastStats.put(uid, uidStats);
4549         }
4550         BroadcastStats bs = uidStats.get(pkgName);
4551         if (bs == null) {
4552             bs = new BroadcastStats(uid, pkgName);
4553             uidStats.put(pkgName, bs);
4554         }
4555         return bs;
4556     }
4557 
4558     /**
4559      * Canonical count of (operation.send() - onSendFinished()) and
4560      * listener send/complete/timeout invocations.
4561      * Guarded by the usual lock.
4562      */
4563     @GuardedBy("mLock")
4564     private int mSendCount = 0;
4565     @GuardedBy("mLock")
4566     private int mSendFinishCount = 0;
4567     @GuardedBy("mLock")
4568     private int mListenerCount = 0;
4569     @GuardedBy("mLock")
4570     private int mListenerFinishCount = 0;
4571 
4572     class DeliveryTracker extends IAlarmCompleteListener.Stub implements PendingIntent.OnFinished {
4573 
removeLocked(PendingIntent pi, Intent intent)4574         private InFlight removeLocked(PendingIntent pi, Intent intent) {
4575             for (int i = 0; i < mInFlight.size(); i++) {
4576                 final InFlight inflight = mInFlight.get(i);
4577                 if (inflight.mPendingIntent == pi) {
4578                     if (pi.isBroadcast()) {
4579                         notifyBroadcastAlarmCompleteLocked(inflight.mUid);
4580                     }
4581                     return mInFlight.remove(i);
4582                 }
4583             }
4584             mLog.w("No in-flight alarm for " + pi + " " + intent);
4585             return null;
4586         }
4587 
removeLocked(IBinder listener)4588         private InFlight removeLocked(IBinder listener) {
4589             for (int i = 0; i < mInFlight.size(); i++) {
4590                 if (mInFlight.get(i).mListener == listener) {
4591                     return mInFlight.remove(i);
4592                 }
4593             }
4594             mLog.w("No in-flight alarm for listener " + listener);
4595             return null;
4596         }
4597 
updateStatsLocked(InFlight inflight)4598         private void updateStatsLocked(InFlight inflight) {
4599             final long nowELAPSED = mInjector.getElapsedRealtime();
4600             BroadcastStats bs = inflight.mBroadcastStats;
4601             bs.nesting--;
4602             if (bs.nesting <= 0) {
4603                 bs.nesting = 0;
4604                 bs.aggregateTime += nowELAPSED - bs.startTime;
4605             }
4606             FilterStats fs = inflight.mFilterStats;
4607             fs.nesting--;
4608             if (fs.nesting <= 0) {
4609                 fs.nesting = 0;
4610                 fs.aggregateTime += nowELAPSED - fs.startTime;
4611             }
4612             if (RECORD_ALARMS_IN_HISTORY) {
4613                 ActivityManager.noteAlarmFinish(inflight.mPendingIntent, inflight.mWorkSource,
4614                         inflight.mUid, inflight.mTag);
4615             }
4616         }
4617 
updateTrackingLocked(InFlight inflight)4618         private void updateTrackingLocked(InFlight inflight) {
4619             if (inflight != null) {
4620                 updateStatsLocked(inflight);
4621             }
4622             mBroadcastRefCount--;
4623             if (DEBUG_WAKELOCK) {
4624                 Slog.d(TAG, "mBroadcastRefCount -> " + mBroadcastRefCount);
4625             }
4626             if (mBroadcastRefCount == 0) {
4627                 mHandler.obtainMessage(AlarmHandler.REPORT_ALARMS_ACTIVE, 0).sendToTarget();
4628                 mWakeLock.release();
4629                 if (mInFlight.size() > 0) {
4630                     mLog.w("Finished all dispatches with " + mInFlight.size()
4631                             + " remaining inflights");
4632                     for (int i=0; i<mInFlight.size(); i++) {
4633                         mLog.w("  Remaining #" + i + ": " + mInFlight.get(i));
4634                     }
4635                     mInFlight.clear();
4636                 }
4637             } else {
4638                 // the next of our alarms is now in flight.  reattribute the wakelock.
4639                 if (mInFlight.size() > 0) {
4640                     InFlight inFlight = mInFlight.get(0);
4641                     setWakelockWorkSource(inFlight.mWorkSource, inFlight.mCreatorUid, inFlight.mTag,
4642                             false);
4643                 } else {
4644                     // should never happen
4645                     mLog.w("Alarm wakelock still held but sent queue empty");
4646                     mWakeLock.setWorkSource(null);
4647                 }
4648             }
4649         }
4650 
4651         /**
4652          * Callback that arrives when a direct-call alarm reports that delivery has finished
4653          */
4654         @Override
alarmComplete(IBinder who)4655         public void alarmComplete(IBinder who) {
4656             if (who == null) {
4657                 mLog.w("Invalid alarmComplete: uid=" + Binder.getCallingUid()
4658                         + " pid=" + Binder.getCallingPid());
4659                 return;
4660             }
4661 
4662             final long ident = Binder.clearCallingIdentity();
4663             try {
4664                 synchronized (mLock) {
4665                     mHandler.removeMessages(AlarmHandler.LISTENER_TIMEOUT, who);
4666                     InFlight inflight = removeLocked(who);
4667                     if (inflight != null) {
4668                         if (DEBUG_LISTENER_CALLBACK) {
4669                             Slog.i(TAG, "alarmComplete() from " + who);
4670                         }
4671                         updateTrackingLocked(inflight);
4672                         mListenerFinishCount++;
4673                     } else {
4674                         // Delivery timed out, and the timeout handling already took care of
4675                         // updating our tracking here, so we needn't do anything further.
4676                         if (DEBUG_LISTENER_CALLBACK) {
4677                             Slog.i(TAG, "Late alarmComplete() from " + who);
4678                         }
4679                     }
4680                 }
4681             } finally {
4682                 Binder.restoreCallingIdentity(ident);
4683             }
4684         }
4685 
4686         /**
4687          * Callback that arrives when a PendingIntent alarm has finished delivery
4688          */
4689         @Override
onSendFinished(PendingIntent pi, Intent intent, int resultCode, String resultData, Bundle resultExtras)4690         public void onSendFinished(PendingIntent pi, Intent intent, int resultCode,
4691                 String resultData, Bundle resultExtras) {
4692             synchronized (mLock) {
4693                 mSendFinishCount++;
4694                 updateTrackingLocked(removeLocked(pi, intent));
4695             }
4696         }
4697 
4698         /**
4699          * Timeout of a direct-call alarm delivery
4700          */
alarmTimedOut(IBinder who)4701         public void alarmTimedOut(IBinder who) {
4702             synchronized (mLock) {
4703                 InFlight inflight = removeLocked(who);
4704                 if (inflight != null) {
4705                     // TODO: implement ANR policy for the target
4706                     if (DEBUG_LISTENER_CALLBACK) {
4707                         Slog.i(TAG, "Alarm listener " + who + " timed out in delivery");
4708                     }
4709                     updateTrackingLocked(inflight);
4710                     mListenerFinishCount++;
4711                 } else {
4712                     if (DEBUG_LISTENER_CALLBACK) {
4713                         Slog.i(TAG, "Spurious timeout of listener " + who);
4714                     }
4715                     mLog.w("Spurious timeout of listener " + who);
4716                 }
4717             }
4718         }
4719 
4720         /**
4721          * Deliver an alarm and set up the post-delivery handling appropriately
4722          */
4723         @GuardedBy("mLock")
deliverLocked(Alarm alarm, long nowELAPSED, boolean allowWhileIdle)4724         public void deliverLocked(Alarm alarm, long nowELAPSED, boolean allowWhileIdle) {
4725             final long workSourceToken = ThreadLocalWorkSource.setUid(
4726                     getAlarmAttributionUid(alarm));
4727             try {
4728                 if (alarm.operation != null) {
4729                     // PendingIntent alarm
4730                     mSendCount++;
4731 
4732                     try {
4733                         alarm.operation.send(getContext(), 0,
4734                                 mBackgroundIntent.putExtra(
4735                                         Intent.EXTRA_ALARM_COUNT, alarm.count),
4736                                 mDeliveryTracker, mHandler, null,
4737                                 allowWhileIdle ? mIdleOptions : null);
4738                     } catch (PendingIntent.CanceledException e) {
4739                         if (alarm.repeatInterval > 0) {
4740                             // This IntentSender is no longer valid, but this
4741                             // is a repeating alarm, so toss it
4742                             removeImpl(alarm.operation, null);
4743                         }
4744                         // No actual delivery was possible, so the delivery tracker's
4745                         // 'finished' callback won't be invoked.  We also don't need
4746                         // to do any wakelock or stats tracking, so we have nothing
4747                         // left to do here but go on to the next thing.
4748                         mSendFinishCount++;
4749                         return;
4750                     }
4751                 } else {
4752                     // Direct listener callback alarm
4753                     mListenerCount++;
4754 
4755                     if (RECORD_ALARMS_IN_HISTORY) {
4756                         if (alarm.listener == mTimeTickTrigger) {
4757                             mTickHistory[mNextTickHistory++] = nowELAPSED;
4758                             if (mNextTickHistory >= TICK_HISTORY_DEPTH) {
4759                                 mNextTickHistory = 0;
4760                             }
4761                         }
4762                     }
4763 
4764                     try {
4765                         if (DEBUG_LISTENER_CALLBACK) {
4766                             Slog.v(TAG, "Alarm to uid=" + alarm.uid
4767                                     + " listener=" + alarm.listener.asBinder());
4768                         }
4769                         alarm.listener.doAlarm(this);
4770                         mHandler.sendMessageDelayed(
4771                                 mHandler.obtainMessage(AlarmHandler.LISTENER_TIMEOUT,
4772                                         alarm.listener.asBinder()),
4773                                 mConstants.LISTENER_TIMEOUT);
4774                     } catch (Exception e) {
4775                         if (DEBUG_LISTENER_CALLBACK) {
4776                             Slog.i(TAG, "Alarm undeliverable to listener "
4777                                     + alarm.listener.asBinder(), e);
4778                         }
4779                         // As in the PendingIntent.CanceledException case, delivery of the
4780                         // alarm was not possible, so we have no wakelock or timeout or
4781                         // stats management to do.  It threw before we posted the delayed
4782                         // timeout message, so we're done here.
4783                         mListenerFinishCount++;
4784                         return;
4785                     }
4786                 }
4787             } finally {
4788                 ThreadLocalWorkSource.restore(workSourceToken);
4789             }
4790 
4791             // The alarm is now in flight; now arrange wakelock and stats tracking
4792             if (DEBUG_WAKELOCK) {
4793                 Slog.d(TAG, "mBroadcastRefCount -> " + (mBroadcastRefCount + 1));
4794             }
4795             if (mBroadcastRefCount == 0) {
4796                 setWakelockWorkSource(alarm.workSource, alarm.creatorUid, alarm.statsTag, true);
4797                 mWakeLock.acquire();
4798                 mHandler.obtainMessage(AlarmHandler.REPORT_ALARMS_ACTIVE, 1).sendToTarget();
4799             }
4800             final InFlight inflight = new InFlight(AlarmManagerService.this, alarm, nowELAPSED);
4801             mInFlight.add(inflight);
4802             mBroadcastRefCount++;
4803             if (inflight.isBroadcast()) {
4804                 notifyBroadcastAlarmPendingLocked(alarm.uid);
4805             }
4806             if (allowWhileIdle) {
4807                 // Record the last time this uid handled an ALLOW_WHILE_IDLE alarm.
4808                 mLastAllowWhileIdleDispatch.put(alarm.creatorUid, nowELAPSED);
4809                 if ((mAppStateTracker == null)
4810                         || mAppStateTracker.isUidInForeground(alarm.creatorUid)) {
4811                     mUseAllowWhileIdleShortTime.put(alarm.creatorUid, true);
4812                 } else {
4813                     mUseAllowWhileIdleShortTime.put(alarm.creatorUid, false);
4814                 }
4815                 if (RECORD_DEVICE_IDLE_ALARMS) {
4816                     IdleDispatchEntry ent = new IdleDispatchEntry();
4817                     ent.uid = alarm.uid;
4818                     ent.pkg = alarm.packageName;
4819                     ent.tag = alarm.statsTag;
4820                     ent.op = "DELIVER";
4821                     ent.elapsedRealtime = nowELAPSED;
4822                     mAllowWhileIdleDispatches.add(ent);
4823                 }
4824             }
4825             if (!isExemptFromAppStandby(alarm)) {
4826                 final Pair<String, Integer> packageUser = Pair.create(alarm.sourcePackage,
4827                         UserHandle.getUserId(alarm.creatorUid));
4828                 mAppWakeupHistory.recordAlarmForPackage(alarm.sourcePackage,
4829                         UserHandle.getUserId(alarm.creatorUid), nowELAPSED);
4830             }
4831             final BroadcastStats bs = inflight.mBroadcastStats;
4832             bs.count++;
4833             if (bs.nesting == 0) {
4834                 bs.nesting = 1;
4835                 bs.startTime = nowELAPSED;
4836             } else {
4837                 bs.nesting++;
4838             }
4839             final FilterStats fs = inflight.mFilterStats;
4840             fs.count++;
4841             if (fs.nesting == 0) {
4842                 fs.nesting = 1;
4843                 fs.startTime = nowELAPSED;
4844             } else {
4845                 fs.nesting++;
4846             }
4847             if (alarm.type == ELAPSED_REALTIME_WAKEUP
4848                     || alarm.type == RTC_WAKEUP) {
4849                 bs.numWakeup++;
4850                 fs.numWakeup++;
4851                 ActivityManager.noteWakeupAlarm(
4852                         alarm.operation, alarm.workSource, alarm.uid, alarm.packageName,
4853                         alarm.statsTag);
4854             }
4855         }
4856     }
4857 
incrementAlarmCount(int uid)4858     private void incrementAlarmCount(int uid) {
4859         final int uidIndex = mAlarmsPerUid.indexOfKey(uid);
4860         if (uidIndex >= 0) {
4861             mAlarmsPerUid.setValueAt(uidIndex, mAlarmsPerUid.valueAt(uidIndex) + 1);
4862         } else {
4863             mAlarmsPerUid.put(uid, 1);
4864         }
4865     }
4866 
decrementAlarmCount(int uid, int decrement)4867     private void decrementAlarmCount(int uid, int decrement) {
4868         int oldCount = 0;
4869         final int uidIndex = mAlarmsPerUid.indexOfKey(uid);
4870         if (uidIndex >= 0) {
4871             oldCount = mAlarmsPerUid.valueAt(uidIndex);
4872             if (oldCount > decrement) {
4873                 mAlarmsPerUid.setValueAt(uidIndex, oldCount - decrement);
4874             } else {
4875                 mAlarmsPerUid.removeAt(uidIndex);
4876             }
4877         }
4878         if (oldCount < decrement) {
4879             Slog.wtf(TAG, "Attempt to decrement existing alarm count " + oldCount + " by "
4880                     + decrement + " for uid " + uid);
4881         }
4882     }
4883 
4884     private class ShellCmd extends ShellCommand {
4885 
getBinderService()4886         IAlarmManager getBinderService() {
4887             return IAlarmManager.Stub.asInterface(mService);
4888         }
4889 
4890         @Override
onCommand(String cmd)4891         public int onCommand(String cmd) {
4892             if (cmd == null) {
4893                 return handleDefaultCommands(cmd);
4894             }
4895 
4896             final PrintWriter pw = getOutPrintWriter();
4897             try {
4898                 switch (cmd) {
4899                     case "set-time":
4900                         final long millis = Long.parseLong(getNextArgRequired());
4901                         return (getBinderService().setTime(millis)) ? 0 : -1;
4902                     case "set-timezone":
4903                         final String tz = getNextArgRequired();
4904                         getBinderService().setTimeZone(tz);
4905                         return 0;
4906                     default:
4907                         return handleDefaultCommands(cmd);
4908                 }
4909             } catch (Exception e) {
4910                 pw.println(e);
4911             }
4912             return -1;
4913         }
4914 
4915         @Override
onHelp()4916         public void onHelp() {
4917             PrintWriter pw = getOutPrintWriter();
4918             pw.println("Alarm manager service (alarm) commands:");
4919             pw.println("  help");
4920             pw.println("    Print this help text.");
4921             pw.println("  set-time TIME");
4922             pw.println("    Set the system clock time to TIME where TIME is milliseconds");
4923             pw.println("    since the Epoch.");
4924             pw.println("  set-timezone TZ");
4925             pw.println("    Set the system timezone to TZ where TZ is an Olson id.");
4926         }
4927     }
4928 }
4929