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