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.alarm;
18 
19 import static android.app.ActivityManager.UidFrozenStateChangedCallback.UID_FROZEN_STATE_FROZEN;
20 import static android.app.ActivityManagerInternal.ALLOW_NON_FULL;
21 import static android.app.AlarmManager.ELAPSED_REALTIME;
22 import static android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP;
23 import static android.app.AlarmManager.EXACT_LISTENER_ALARMS_DROPPED_ON_CACHED;
24 import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE;
25 import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE_COMPAT;
26 import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
27 import static android.app.AlarmManager.FLAG_IDLE_UNTIL;
28 import static android.app.AlarmManager.FLAG_PRIORITIZE;
29 import static android.app.AlarmManager.FLAG_WAKE_FROM_IDLE;
30 import static android.app.AlarmManager.INTERVAL_DAY;
31 import static android.app.AlarmManager.INTERVAL_HOUR;
32 import static android.app.AlarmManager.RTC;
33 import static android.app.AlarmManager.RTC_WAKEUP;
34 import static android.content.PermissionChecker.PERMISSION_GRANTED;
35 import static android.content.PermissionChecker.PID_UNKNOWN;
36 import static android.content.PermissionChecker.checkPermissionForPreflight;
37 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
38 import static android.os.PowerExemptionManager.REASON_ALARM_MANAGER_ALARM_CLOCK;
39 import static android.os.PowerExemptionManager.REASON_DENIED;
40 import static android.os.PowerExemptionManager.REASON_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED;
41 import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
42 import static android.os.PowerWhitelistManager.REASON_ALARM_MANAGER_WHILE_IDLE;
43 import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
44 import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED;
45 import static android.os.UserHandle.USER_SYSTEM;
46 
47 import static com.android.server.SystemClockTime.TIME_CONFIDENCE_HIGH;
48 import static com.android.server.SystemTimeZone.TIME_ZONE_CONFIDENCE_HIGH;
49 import static com.android.server.alarm.Alarm.APP_STANDBY_POLICY_INDEX;
50 import static com.android.server.alarm.Alarm.BATTERY_SAVER_POLICY_INDEX;
51 import static com.android.server.alarm.Alarm.DEVICE_IDLE_POLICY_INDEX;
52 import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_ALLOW_LIST;
53 import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_COMPAT;
54 import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_LISTENER;
55 import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_NOT_APPLICABLE;
56 import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_PERMISSION;
57 import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_POLICY_PERMISSION;
58 import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_PRIORITIZED;
59 import static com.android.server.alarm.Alarm.REQUESTER_POLICY_INDEX;
60 import static com.android.server.alarm.AlarmManagerService.AlarmHandler.REMOVE_EXACT_LISTENER_ALARMS_ON_CACHED;
61 import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_REASON_ALARM_CANCELLED;
62 import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_REASON_DATA_CLEARED;
63 import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_REASON_EXACT_PERMISSION_REVOKED;
64 import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_REASON_LISTENER_BINDER_DIED;
65 import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_REASON_LISTENER_CACHED;
66 import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_REASON_PI_CANCELLED;
67 import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_REASON_UNDEFINED;
68 
69 import android.Manifest;
70 import android.annotation.CurrentTimeMillisLong;
71 import android.annotation.ElapsedRealtimeLong;
72 import android.annotation.EnforcePermission;
73 import android.annotation.IntDef;
74 import android.annotation.NonNull;
75 import android.annotation.SuppressLint;
76 import android.annotation.UserIdInt;
77 import android.app.Activity;
78 import android.app.ActivityManager;
79 import android.app.ActivityManagerInternal;
80 import android.app.ActivityOptions;
81 import android.app.AlarmManager;
82 import android.app.AppOpsManager;
83 import android.app.BroadcastOptions;
84 import android.app.IAlarmCompleteListener;
85 import android.app.IAlarmListener;
86 import android.app.IAlarmManager;
87 import android.app.PendingIntent;
88 import android.app.compat.CompatChanges;
89 import android.app.role.RoleManager;
90 import android.app.usage.UsageStatsManager;
91 import android.app.usage.UsageStatsManagerInternal;
92 import android.content.BroadcastReceiver;
93 import android.content.Context;
94 import android.content.Intent;
95 import android.content.IntentFilter;
96 import android.content.pm.PackageManager;
97 import android.content.pm.PackageManagerInternal;
98 import android.content.pm.UserPackage;
99 import android.net.Uri;
100 import android.os.BatteryManager;
101 import android.os.BatteryStatsInternal;
102 import android.os.Binder;
103 import android.os.Build;
104 import android.os.Bundle;
105 import android.os.Handler;
106 import android.os.HandlerExecutor;
107 import android.os.IBinder;
108 import android.os.Looper;
109 import android.os.Message;
110 import android.os.PowerExemptionManager;
111 import android.os.PowerManager;
112 import android.os.Process;
113 import android.os.RemoteException;
114 import android.os.ResultReceiver;
115 import android.os.ServiceManager;
116 import android.os.ShellCallback;
117 import android.os.ShellCommand;
118 import android.os.SystemClock;
119 import android.os.SystemProperties;
120 import android.os.ThreadLocalWorkSource;
121 import android.os.Trace;
122 import android.os.UserHandle;
123 import android.os.WorkSource;
124 import android.provider.DeviceConfig;
125 import android.provider.Settings;
126 import android.system.Os;
127 import android.text.TextUtils;
128 import android.text.format.DateFormat;
129 import android.util.ArrayMap;
130 import android.util.ArraySet;
131 import android.util.EventLog;
132 import android.util.IndentingPrintWriter;
133 import android.util.IntArray;
134 import android.util.Log;
135 import android.util.LongArrayQueue;
136 import android.util.Slog;
137 import android.util.SparseArray;
138 import android.util.SparseBooleanArray;
139 import android.util.SparseIntArray;
140 import android.util.SparseLongArray;
141 import android.util.TimeUtils;
142 import android.util.proto.ProtoOutputStream;
143 
144 import com.android.internal.annotations.GuardedBy;
145 import com.android.internal.annotations.VisibleForTesting;
146 import com.android.internal.app.IAppOpsCallback;
147 import com.android.internal.app.IAppOpsService;
148 import com.android.internal.util.ArrayUtils;
149 import com.android.internal.util.DumpUtils;
150 import com.android.internal.util.FrameworkStatsLog;
151 import com.android.internal.util.LocalLog;
152 import com.android.internal.util.RingBuffer;
153 import com.android.internal.util.StatLogger;
154 import com.android.server.AlarmManagerInternal;
155 import com.android.server.AppSchedulingModuleThread;
156 import com.android.server.AppStateTracker;
157 import com.android.server.AppStateTrackerImpl;
158 import com.android.server.AppStateTrackerImpl.Listener;
159 import com.android.server.DeviceIdleInternal;
160 import com.android.server.EventLogTags;
161 import com.android.server.LocalServices;
162 import com.android.server.SystemClockTime;
163 import com.android.server.SystemClockTime.TimeConfidence;
164 import com.android.server.SystemService;
165 import com.android.server.SystemServiceManager;
166 import com.android.server.SystemTimeZone;
167 import com.android.server.SystemTimeZone.TimeZoneConfidence;
168 import com.android.server.pm.permission.PermissionManagerService;
169 import com.android.server.pm.permission.PermissionManagerServiceInternal;
170 import com.android.server.pm.pkg.AndroidPackage;
171 import com.android.server.usage.AppStandbyInternal;
172 import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;
173 
174 import dalvik.annotation.optimization.NeverCompile;
175 
176 import java.io.FileDescriptor;
177 import java.io.PrintWriter;
178 import java.lang.annotation.Retention;
179 import java.lang.annotation.RetentionPolicy;
180 import java.text.SimpleDateFormat;
181 import java.time.Instant;
182 import java.time.zone.ZoneOffsetTransition;
183 import java.time.zone.ZoneRules;
184 import java.util.ArrayList;
185 import java.util.Arrays;
186 import java.util.Calendar;
187 import java.util.Collections;
188 import java.util.Comparator;
189 import java.util.Date;
190 import java.util.Locale;
191 import java.util.Set;
192 import java.util.TimeZone;
193 import java.util.TreeSet;
194 import java.util.concurrent.ThreadLocalRandom;
195 import java.util.concurrent.TimeUnit;
196 import java.util.function.Predicate;
197 
198 /**
199  * Alarm manager implementation.
200  *
201  * Unit test:
202  * atest FrameworksMockingServicesTests:com.android.server.alarm.AlarmManagerServiceTest
203  */
204 public class AlarmManagerService extends SystemService {
205     private static final int RTC_WAKEUP_MASK = 1 << RTC_WAKEUP;
206     private static final int ELAPSED_REALTIME_WAKEUP_MASK = 1 << ELAPSED_REALTIME_WAKEUP;
207     private static final int REMOVAL_HISTORY_SIZE_PER_UID = 10;
208     static final int TIME_CHANGED_MASK = 1 << 16;
209     static final int IS_WAKEUP_MASK = RTC_WAKEUP_MASK | ELAPSED_REALTIME_WAKEUP_MASK;
210 
211     static final String TAG = "AlarmManager";
212     static final String TIME_TICK_TAG = "TIME_TICK";
213     static final boolean localLOGV = false;
214     static final boolean DEBUG_BATCH = localLOGV || false;
215     static final boolean DEBUG_ALARM_CLOCK = localLOGV || false;
216     static final boolean DEBUG_LISTENER_CALLBACK = localLOGV || false;
217     static final boolean DEBUG_WAKELOCK = localLOGV || false;
218     static final boolean DEBUG_BG_LIMIT = localLOGV || false;
219     static final boolean DEBUG_STANDBY = localLOGV || false;
220     static final boolean RECORD_ALARMS_IN_HISTORY = true;
221     static final boolean RECORD_DEVICE_IDLE_ALARMS = false;
222 
223     static final int TICK_HISTORY_DEPTH = 10;
224     static final long INDEFINITE_DELAY = 365 * INTERVAL_DAY;
225 
226     // Indices into the KEYS_APP_STANDBY_QUOTAS array.
227     static final int ACTIVE_INDEX = 0;
228     static final int WORKING_INDEX = 1;
229     static final int FREQUENT_INDEX = 2;
230     static final int RARE_INDEX = 3;
231     static final int NEVER_INDEX = 4;
232 
233     private static final long TEMPORARY_QUOTA_DURATION = INTERVAL_DAY;
234 
235     // System properties read on some device configurations to initialize time properly and
236     // perform DST transitions at the bootloader level.
237     private static final String TIMEOFFSET_PROPERTY = "persist.sys.time.offset";
238     private static final String DST_TRANSITION_PROPERTY = "persist.sys.time.dst_transition";
239     private static final String DST_OFFSET_PROPERTY = "persist.sys.time.dst_offset";
240 
241 
242     private final Intent mBackgroundIntent
243             = new Intent().addFlags(Intent.FLAG_FROM_BACKGROUND);
244 
245     private static final Intent NEXT_ALARM_CLOCK_CHANGED_INTENT =
246             new Intent(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED)
247                     .addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
248                             | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
249 
250     final LocalLog mLog = new LocalLog(TAG);
251 
252     AppOpsManager mAppOps;
253     DeviceIdleInternal mLocalDeviceIdleController;
254     private UsageStatsManagerInternal mUsageStatsManagerInternal;
255     private ActivityManagerInternal mActivityManagerInternal;
256     private PackageManagerInternal mPackageManagerInternal;
257     private BatteryStatsInternal mBatteryStatsInternal;
258     private RoleManager mRoleManager;
259     private volatile PermissionManagerServiceInternal mLocalPermissionManager;
260 
261     final Object mLock = new Object();
262 
263     /** Immutable set of app ids requesting {@link Manifest.permission#SCHEDULE_EXACT_ALARM} */
264     @VisibleForTesting
265     volatile Set<Integer> mExactAlarmCandidates = Collections.emptySet();
266 
267     /**
268      * A map from uid to the last op-mode we have seen for
269      * {@link AppOpsManager#OP_SCHEDULE_EXACT_ALARM}. Used for evaluating permission state change
270      * when the app-op changes.
271      */
272     @VisibleForTesting
273     @GuardedBy("mLock")
274     SparseIntArray mLastOpScheduleExactAlarm = new SparseIntArray();
275 
276     // List of alarms per uid deferred due to user applied background restrictions on the source app
277     SparseArray<ArrayList<Alarm>> mPendingBackgroundAlarms = new SparseArray<>();
278 
279     private boolean mStartUserBeforeScheduledAlarms;
280     private long mNextWakeup;
281     private long mNextNonWakeup;
282     private long mNextWakeUpSetAt;
283     private long mNextNonWakeUpSetAt;
284     private long mLastWakeup;
285     private long mLastTrigger;
286 
287     private long mLastTickSet;
288     private long mLastTickReceived;
289     // ring buffer of recent TIME_TICK issuance, in the elapsed timebase
290     private final long[] mTickHistory = new long[TICK_HISTORY_DEPTH];
291     private int mNextTickHistory;
292 
293     private final Injector mInjector;
294     int mBroadcastRefCount = 0;
295     boolean mUseFrozenStateToDropListenerAlarms;
296     MetricsHelper mMetricsHelper;
297     PowerManager.WakeLock mWakeLock;
298     SparseIntArray mAlarmsPerUid = new SparseIntArray();
299     ArrayList<Alarm> mPendingNonWakeupAlarms = new ArrayList<>();
300     ArrayList<InFlight> mInFlight = new ArrayList<>();
301     private final ArrayList<AlarmManagerInternal.InFlightListener> mInFlightListeners =
302             new ArrayList<>();
303     AlarmHandler mHandler;
304     AppWakeupHistory mAppWakeupHistory;
305     AppWakeupHistory mAllowWhileIdleHistory;
306     AppWakeupHistory mAllowWhileIdleCompatHistory;
307     TemporaryQuotaReserve mTemporaryQuotaReserve;
308     private final SparseLongArray mLastPriorityAlarmDispatch = new SparseLongArray();
309     private final SparseArray<RingBuffer<RemovedAlarm>> mRemovalHistory = new SparseArray<>();
310     ClockReceiver mClockReceiver;
311     final DeliveryTracker mDeliveryTracker = new DeliveryTracker();
312     IBinder.DeathRecipient mListenerDeathRecipient;
313     Intent mTimeTickIntent;
314     Bundle mTimeTickOptions;
315     IAlarmListener mTimeTickTrigger;
316     PendingIntent mDateChangeSender;
317     boolean mInteractive = true;
318     long mNonInteractiveStartTime;
319     long mNonInteractiveTime;
320     long mLastAlarmDeliveryTime;
321     long mStartCurrentDelayTime;
322     long mNextNonWakeupDeliveryTime;
323     long mLastTimeChangeClockTime;
324     long mLastTimeChangeRealtime;
325     int mNumTimeChanged;
326 
327     /**
328      * At boot we use SYSTEM_UI_SELF_PERMISSION to look up the definer's uid.
329      */
330     int mSystemUiUid;
331 
isTimeTickAlarm(Alarm a)332     static boolean isTimeTickAlarm(Alarm a) {
333         return a.uid == Process.SYSTEM_UID && TIME_TICK_TAG.equals(a.listenerTag);
334     }
335 
336     final static class IdleDispatchEntry {
337         int uid;
338         String pkg;
339         String tag;
340         String op;
341         long elapsedRealtime;
342         long argRealtime;
343     }
344     final ArrayList<IdleDispatchEntry> mAllowWhileIdleDispatches = new ArrayList();
345 
346     interface Stats {
347         int REORDER_ALARMS_FOR_STANDBY = 0;
348         int HAS_SCHEDULE_EXACT_ALARM = 1;
349     }
350 
351     private final StatLogger mStatLogger = new StatLogger("Alarm manager stats", new String[]{
352             "REORDER_ALARMS_FOR_STANDBY",
353             "HAS_SCHEDULE_EXACT_ALARM",
354     });
355 
356     BroadcastOptions mOptsWithFgs = makeBasicAlarmBroadcastOptions();
357     BroadcastOptions mOptsWithFgsForAlarmClock = makeBasicAlarmBroadcastOptions();
358     BroadcastOptions mOptsWithoutFgs = makeBasicAlarmBroadcastOptions();
359     BroadcastOptions mOptsTimeBroadcast = makeBasicAlarmBroadcastOptions();
360     ActivityOptions mActivityOptsRestrictBal = ActivityOptions.makeBasic();
361     BroadcastOptions mBroadcastOptsRestrictBal = makeBasicAlarmBroadcastOptions();
362 
makeBasicAlarmBroadcastOptions()363     private static BroadcastOptions makeBasicAlarmBroadcastOptions() {
364         final BroadcastOptions b = BroadcastOptions.makeBasic();
365         b.setAlarmBroadcast(true);
366         return b;
367     }
368 
369     // TODO(b/172085676): Move inside alarm store.
370     private final SparseArray<AlarmManager.AlarmClockInfo> mNextAlarmClockForUser =
371             new SparseArray<>();
372     private final SparseArray<AlarmManager.AlarmClockInfo> mTmpSparseAlarmClockArray =
373             new SparseArray<>();
374     private final SparseBooleanArray mPendingSendNextAlarmClockChangedForUser =
375             new SparseBooleanArray();
376     private boolean mNextAlarmClockMayChange;
377 
378     @GuardedBy("mLock")
379     private final Runnable mAlarmClockUpdater = () -> mNextAlarmClockMayChange = true;
380 
381     // May only use on mHandler's thread, locking not required.
382     private final SparseArray<AlarmManager.AlarmClockInfo> mHandlerSparseAlarmClockArray =
383             new SparseArray<>();
384 
385     private AppStateTrackerImpl mAppStateTracker;
386     @VisibleForTesting
387     boolean mAppStandbyParole;
388 
389     /**
390      * Holds information about temporary quota that can be allotted to apps to use as a "reserve"
391      * when they run out of their standard app-standby quota.
392      * This reserve only lasts for a fixed duration of time from when it was last replenished.
393      */
394     static class TemporaryQuotaReserve {
395 
396         private static class QuotaInfo {
397             public int remainingQuota;
398             public long expirationTime;
399             public long lastUsage;
400         }
401         /** Map of {package, user} -> {quotaInfo} */
402         private final ArrayMap<UserPackage, QuotaInfo> mQuotaBuffer = new ArrayMap<>();
403 
404         private long mMaxDuration;
405 
TemporaryQuotaReserve(long maxDuration)406         TemporaryQuotaReserve(long maxDuration) {
407             mMaxDuration = maxDuration;
408         }
409 
replenishQuota(String packageName, int userId, int quota, long nowElapsed)410         void replenishQuota(String packageName, int userId, int quota, long nowElapsed) {
411             if (quota <= 0) {
412                 return;
413             }
414             final UserPackage userPackage = UserPackage.of(userId, packageName);
415             QuotaInfo currentQuotaInfo = mQuotaBuffer.get(userPackage);
416             if (currentQuotaInfo == null) {
417                 currentQuotaInfo = new QuotaInfo();
418                 mQuotaBuffer.put(userPackage, currentQuotaInfo);
419             }
420             currentQuotaInfo.remainingQuota = quota;
421             currentQuotaInfo.expirationTime = nowElapsed + mMaxDuration;
422         }
423 
424         /** Returns if the supplied package has reserve quota to fire at the given time. */
hasQuota(String packageName, int userId, long triggerElapsed)425         boolean hasQuota(String packageName, int userId, long triggerElapsed) {
426             final UserPackage userPackage = UserPackage.of(userId, packageName);
427             final QuotaInfo quotaInfo = mQuotaBuffer.get(userPackage);
428 
429             return quotaInfo != null && quotaInfo.remainingQuota > 0
430                     && triggerElapsed <= quotaInfo.expirationTime;
431         }
432 
433         /**
434          * Records quota usage of the given package at the given time and subtracts quota if
435          * required.
436          */
recordUsage(String packageName, int userId, long nowElapsed)437         void recordUsage(String packageName, int userId, long nowElapsed) {
438             final UserPackage userPackage = UserPackage.of(userId, packageName);
439             final QuotaInfo quotaInfo = mQuotaBuffer.get(userPackage);
440 
441             if (quotaInfo == null) {
442                 Slog.wtf(TAG, "Temporary quota being consumed at " + nowElapsed
443                         + " but not found for package: " + packageName + ", user: " + userId);
444                 return;
445             }
446             // Only consume quota if this usage is later than the last one recorded. This is
447             // needed as this can be called multiple times when a batch of alarms is delivered.
448             if (nowElapsed > quotaInfo.lastUsage) {
449                 if (quotaInfo.remainingQuota <= 0) {
450                     Slog.wtf(TAG, "Temporary quota being consumed at " + nowElapsed
451                             + " but remaining only " + quotaInfo.remainingQuota
452                             + " for package: " + packageName + ", user: " + userId);
453                 } else if (quotaInfo.expirationTime < nowElapsed) {
454                     Slog.wtf(TAG, "Temporary quota being consumed at " + nowElapsed
455                             + " but expired at " + quotaInfo.expirationTime
456                             + " for package: " + packageName + ", user: " + userId);
457                 } else {
458                     quotaInfo.remainingQuota--;
459                     // We keep the quotaInfo entry even if remaining quota reduces to 0 as
460                     // following calls can be made with nowElapsed <= lastUsage. The object will
461                     // eventually be removed in cleanUpExpiredQuotas or reused in replenishQuota.
462                 }
463                 quotaInfo.lastUsage = nowElapsed;
464             }
465         }
466 
467         /** Clean up any quotas that have expired before the given time. */
cleanUpExpiredQuotas(long nowElapsed)468         void cleanUpExpiredQuotas(long nowElapsed) {
469             for (int i = mQuotaBuffer.size() - 1; i >= 0; i--) {
470                 final QuotaInfo quotaInfo = mQuotaBuffer.valueAt(i);
471                 if (quotaInfo.expirationTime < nowElapsed) {
472                     mQuotaBuffer.removeAt(i);
473                 }
474             }
475         }
476 
removeForUser(int userId)477         void removeForUser(int userId) {
478             for (int i = mQuotaBuffer.size() - 1; i >= 0; i--) {
479                 final UserPackage userPackageKey = mQuotaBuffer.keyAt(i);
480                 if (userPackageKey.userId == userId) {
481                     mQuotaBuffer.removeAt(i);
482                 }
483             }
484         }
485 
removeForPackage(String packageName, int userId)486         void removeForPackage(String packageName, int userId) {
487             final UserPackage userPackage = UserPackage.of(userId, packageName);
488             mQuotaBuffer.remove(userPackage);
489         }
490 
dump(IndentingPrintWriter pw, long nowElapsed)491         void dump(IndentingPrintWriter pw, long nowElapsed) {
492             pw.increaseIndent();
493             for (int i = 0; i < mQuotaBuffer.size(); i++) {
494                 final UserPackage userPackage = mQuotaBuffer.keyAt(i);
495                 final QuotaInfo quotaInfo = mQuotaBuffer.valueAt(i);
496                 pw.print(userPackage.packageName);
497                 pw.print(", u");
498                 pw.print(userPackage.userId);
499                 pw.print(": ");
500                 if (quotaInfo == null) {
501                     pw.print("--");
502                 } else {
503                     pw.print("quota: ");
504                     pw.print(quotaInfo.remainingQuota);
505                     pw.print(", expiration: ");
506                     TimeUtils.formatDuration(quotaInfo.expirationTime, nowElapsed, pw);
507                     pw.print(" last used: ");
508                     TimeUtils.formatDuration(quotaInfo.lastUsage, nowElapsed, pw);
509                 }
510                 pw.println();
511             }
512             pw.decreaseIndent();
513         }
514     }
515 
516     /**
517      * A container to keep rolling window history of previous times when an alarm was sent to
518      * a package.
519      */
520     @VisibleForTesting
521     static class AppWakeupHistory {
522         private final ArrayMap<UserPackage, LongArrayQueue> mPackageHistory = new ArrayMap<>();
523         private long mWindowSize;
524 
AppWakeupHistory(long windowSize)525         AppWakeupHistory(long windowSize) {
526             mWindowSize = windowSize;
527         }
528 
recordAlarmForPackage(String packageName, int userId, long nowElapsed)529         void recordAlarmForPackage(String packageName, int userId, long nowElapsed) {
530             final UserPackage userPackage = UserPackage.of(userId, packageName);
531             LongArrayQueue history = mPackageHistory.get(userPackage);
532             if (history == null) {
533                 history = new LongArrayQueue();
534                 mPackageHistory.put(userPackage, history);
535             }
536             if (history.size() == 0 || history.peekLast() < nowElapsed) {
537                 history.addLast(nowElapsed);
538             }
539             snapToWindow(history);
540         }
541 
removeForUser(int userId)542         void removeForUser(int userId) {
543             for (int i = mPackageHistory.size() - 1; i >= 0; i--) {
544                 final UserPackage userPackageKey = mPackageHistory.keyAt(i);
545                 if (userPackageKey.userId == userId) {
546                     mPackageHistory.removeAt(i);
547                 }
548             }
549         }
550 
removeForPackage(String packageName, int userId)551         void removeForPackage(String packageName, int userId) {
552             final UserPackage userPackage = UserPackage.of(userId, packageName);
553             mPackageHistory.remove(userPackage);
554         }
555 
snapToWindow(LongArrayQueue history)556         private void snapToWindow(LongArrayQueue history) {
557             while (history.peekFirst() + mWindowSize < history.peekLast()) {
558                 history.removeFirst();
559             }
560         }
561 
getTotalWakeupsInWindow(String packageName, int userId)562         int getTotalWakeupsInWindow(String packageName, int userId) {
563             final LongArrayQueue history = mPackageHistory.get(UserPackage.of(userId, packageName));
564             return (history == null) ? 0 : history.size();
565         }
566 
567         /**
568          * @param n The desired nth-last wakeup
569          *          (1=1st-last=the ultimate wakeup and 2=2nd-last=the penultimate wakeup)
570          */
getNthLastWakeupForPackage(String packageName, int userId, int n)571         long getNthLastWakeupForPackage(String packageName, int userId, int n) {
572             final LongArrayQueue history = mPackageHistory.get(UserPackage.of(userId, packageName));
573             if (history == null) {
574                 return 0;
575             }
576             final int i = history.size() - n;
577             return (i < 0) ? 0 : history.get(i);
578         }
579 
dump(IndentingPrintWriter pw, long nowElapsed)580         void dump(IndentingPrintWriter pw, long nowElapsed) {
581             pw.increaseIndent();
582             for (int i = 0; i < mPackageHistory.size(); i++) {
583                 final UserPackage userPackage = mPackageHistory.keyAt(i);
584                 final LongArrayQueue timestamps = mPackageHistory.valueAt(i);
585                 pw.print(userPackage.packageName);
586                 pw.print(", u");
587                 pw.print(userPackage.userId);
588                 pw.print(": ");
589                 // limit dumping to a max of 100 values
590                 final int lastIdx = Math.max(0, timestamps.size() - 100);
591                 for (int j = timestamps.size() - 1; j >= lastIdx; j--) {
592                     TimeUtils.formatDuration(timestamps.get(j), nowElapsed, pw);
593                     pw.print(", ");
594                 }
595                 pw.println();
596             }
597             pw.decreaseIndent();
598         }
599     }
600 
601     static class RemovedAlarm {
602         static final int REMOVE_REASON_UNDEFINED = 0;
603         static final int REMOVE_REASON_ALARM_CANCELLED = 1;
604         static final int REMOVE_REASON_EXACT_PERMISSION_REVOKED = 2;
605         static final int REMOVE_REASON_DATA_CLEARED = 3;
606         static final int REMOVE_REASON_PI_CANCELLED = 4;
607         static final int REMOVE_REASON_LISTENER_BINDER_DIED = 5;
608         static final int REMOVE_REASON_LISTENER_CACHED = 6;
609 
610         final Alarm.Snapshot mAlarmSnapshot;
611         final long mWhenRemovedElapsed;
612         final long mWhenRemovedRtc;
613         final int mRemoveReason;
614 
RemovedAlarm(Alarm a, int removeReason, long nowRtc, long nowElapsed)615         RemovedAlarm(Alarm a, int removeReason, long nowRtc, long nowElapsed) {
616             mAlarmSnapshot = new Alarm.Snapshot(a);
617             mRemoveReason = removeReason;
618             mWhenRemovedRtc = nowRtc;
619             mWhenRemovedElapsed = nowElapsed;
620         }
621 
isLoggable(int reason)622         static final boolean isLoggable(int reason) {
623             // We don't want to log meaningless reasons. This also gives a way for callers to
624             // opt out of logging, e.g. when replacing an alarm.
625             return reason != REMOVE_REASON_UNDEFINED;
626         }
627 
removeReasonToString(int reason)628         static final String removeReasonToString(int reason) {
629             switch (reason) {
630                 case REMOVE_REASON_ALARM_CANCELLED:
631                     return "alarm_cancelled";
632                 case REMOVE_REASON_EXACT_PERMISSION_REVOKED:
633                     return "exact_alarm_permission_revoked";
634                 case REMOVE_REASON_DATA_CLEARED:
635                     return "data_cleared";
636                 case REMOVE_REASON_PI_CANCELLED:
637                     return "pi_cancelled";
638                 case REMOVE_REASON_LISTENER_BINDER_DIED:
639                     return "listener_binder_died";
640                 case REMOVE_REASON_LISTENER_CACHED:
641                     return "listener_cached";
642                 default:
643                     return "unknown:" + reason;
644             }
645         }
646 
dump(IndentingPrintWriter pw, long nowElapsed, SimpleDateFormat sdf)647         void dump(IndentingPrintWriter pw, long nowElapsed, SimpleDateFormat sdf) {
648             pw.increaseIndent();
649 
650             pw.print("Reason", removeReasonToString(mRemoveReason));
651             pw.print("elapsed=");
652             TimeUtils.formatDuration(mWhenRemovedElapsed, nowElapsed, pw);
653             pw.print(" rtc=");
654             pw.print(sdf.format(new Date(mWhenRemovedRtc)));
655             pw.println();
656 
657             pw.println("Snapshot:");
658             pw.increaseIndent();
659             mAlarmSnapshot.dump(pw, nowElapsed);
660             pw.decreaseIndent();
661 
662             pw.decreaseIndent();
663         }
664     }
665 
666     /**
667      * All times are in milliseconds. These constants are kept synchronized with the system
668      * global Settings. Any access to this class or its fields should be done while
669      * holding the AlarmManagerService.mLock lock.
670      */
671     @VisibleForTesting
672     final class Constants implements DeviceConfig.OnPropertiesChangedListener {
673         // Key names stored in the settings value.
674         @VisibleForTesting
675         static final String KEY_MIN_FUTURITY = "min_futurity";
676         @VisibleForTesting
677         static final String KEY_MIN_INTERVAL = "min_interval";
678         @VisibleForTesting
679         static final String KEY_MAX_INTERVAL = "max_interval";
680         @VisibleForTesting
681         static final String KEY_MIN_WINDOW = "min_window";
682         @VisibleForTesting
683         static final String KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION
684                 = "allow_while_idle_whitelist_duration";
685         @VisibleForTesting
686         static final String KEY_LISTENER_TIMEOUT = "listener_timeout";
687         @VisibleForTesting
688         static final String KEY_MAX_ALARMS_PER_UID = "max_alarms_per_uid";
689         private static final String KEY_APP_STANDBY_WINDOW = "app_standby_window";
690         private static final String KEY_PREFIX_STANDBY_QUOTA = "standby_quota_";
691         @VisibleForTesting
692         final String[] KEYS_APP_STANDBY_QUOTAS = {
693                 KEY_PREFIX_STANDBY_QUOTA + "active",
694                 KEY_PREFIX_STANDBY_QUOTA + "working",
695                 KEY_PREFIX_STANDBY_QUOTA + "frequent",
696                 KEY_PREFIX_STANDBY_QUOTA + "rare",
697                 KEY_PREFIX_STANDBY_QUOTA + "never",
698         };
699         // Not putting this in the KEYS_APP_STANDBY_QUOTAS array because this uses a different
700         // window size.
701         private static final String KEY_APP_STANDBY_RESTRICTED_QUOTA =
702                 KEY_PREFIX_STANDBY_QUOTA + "restricted";
703         private static final String KEY_APP_STANDBY_RESTRICTED_WINDOW =
704                 "app_standby_restricted_window";
705 
706         private static final String KEY_TIME_TICK_ALLOWED_WHILE_IDLE =
707                 "time_tick_allowed_while_idle";
708 
709         private static final String KEY_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF =
710                 "delay_nonwakeup_alarms_while_screen_off";
711 
712         @VisibleForTesting
713         static final String KEY_ALLOW_WHILE_IDLE_QUOTA = "allow_while_idle_quota";
714 
715         @VisibleForTesting
716         static final String KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA = "allow_while_idle_compat_quota";
717 
718         @VisibleForTesting
719         static final String KEY_ALLOW_WHILE_IDLE_WINDOW = "allow_while_idle_window";
720         @VisibleForTesting
721         static final String KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW = "allow_while_idle_compat_window";
722 
723         @VisibleForTesting
724         static final String KEY_PRIORITY_ALARM_DELAY = "priority_alarm_delay";
725         @VisibleForTesting
726         static final String KEY_MIN_DEVICE_IDLE_FUZZ = "min_device_idle_fuzz";
727         @VisibleForTesting
728         static final String KEY_MAX_DEVICE_IDLE_FUZZ = "max_device_idle_fuzz";
729         @VisibleForTesting
730         static final String KEY_TEMPORARY_QUOTA_BUMP = "temporary_quota_bump";
731         @VisibleForTesting
732         static final String KEY_CACHED_LISTENER_REMOVAL_DELAY = "cached_listener_removal_delay";
733 
734         private static final long DEFAULT_MIN_FUTURITY = 5 * 1000;
735         private static final long DEFAULT_MIN_INTERVAL = 60 * 1000;
736         private static final long DEFAULT_MAX_INTERVAL = 365 * INTERVAL_DAY;
737         private static final long DEFAULT_MIN_WINDOW = 10 * 60 * 1000;
738         private static final long DEFAULT_ALLOW_WHILE_IDLE_ALLOWLIST_DURATION = 10 * 1000;
739         private static final long DEFAULT_LISTENER_TIMEOUT = 5 * 1000;
740         private static final int DEFAULT_MAX_ALARMS_PER_UID = 500;
741         private static final long DEFAULT_APP_STANDBY_WINDOW = 60 * 60 * 1000;  // 1 hr
742         /**
743          * Max number of times an app can receive alarms in {@link #APP_STANDBY_WINDOW}
744          */
745         private final int[] DEFAULT_APP_STANDBY_QUOTAS = {
746                 720,    // Active
747                 10,     // Working
748                 2,      // Frequent
749                 1,      // Rare
750                 0       // Never
751         };
752         private static final int DEFAULT_APP_STANDBY_RESTRICTED_QUOTA = 1;
753         private static final long DEFAULT_APP_STANDBY_RESTRICTED_WINDOW = INTERVAL_DAY;
754 
755         private static final boolean DEFAULT_TIME_TICK_ALLOWED_WHILE_IDLE = true;
756 
757         /**
758          * Default quota for pre-S apps. The same as allowing an alarm slot once
759          * every ALLOW_WHILE_IDLE_LONG_DELAY, which was 9 minutes.
760          */
761         private static final int DEFAULT_ALLOW_WHILE_IDLE_COMPAT_QUOTA = 7;
762         private static final int DEFAULT_ALLOW_WHILE_IDLE_QUOTA = 72;
763 
764         private static final long DEFAULT_ALLOW_WHILE_IDLE_WINDOW = 60 * 60 * 1000; // 1 hour.
765         private static final long DEFAULT_ALLOW_WHILE_IDLE_COMPAT_WINDOW = 60 * 60 * 1000;
766 
767         private static final long DEFAULT_PRIORITY_ALARM_DELAY = 9 * 60_000;
768 
769         private static final long DEFAULT_MIN_DEVICE_IDLE_FUZZ = 2 * 60_000;
770         private static final long DEFAULT_MAX_DEVICE_IDLE_FUZZ = 15 * 60_000;
771 
772         private static final int DEFAULT_TEMPORARY_QUOTA_BUMP = 0;
773 
774         private static final boolean DEFAULT_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF = true;
775 
776         private static final long DEFAULT_CACHED_LISTENER_REMOVAL_DELAY = 10_000;
777 
778         // Minimum futurity of a new alarm
779         public long MIN_FUTURITY = DEFAULT_MIN_FUTURITY;
780 
781         // Minimum alarm recurrence interval
782         public long MIN_INTERVAL = DEFAULT_MIN_INTERVAL;
783 
784         // Maximum alarm recurrence interval
785         public long MAX_INTERVAL = DEFAULT_MAX_INTERVAL;
786 
787         // Minimum window size for inexact alarms
788         public long MIN_WINDOW = DEFAULT_MIN_WINDOW;
789 
790         // BroadcastOptions.setTemporaryAppWhitelistDuration() to use for FLAG_ALLOW_WHILE_IDLE.
791         public long ALLOW_WHILE_IDLE_WHITELIST_DURATION
792                 = DEFAULT_ALLOW_WHILE_IDLE_ALLOWLIST_DURATION;
793 
794         // Direct alarm listener callback timeout
795         public long LISTENER_TIMEOUT = DEFAULT_LISTENER_TIMEOUT;
796         public int MAX_ALARMS_PER_UID = DEFAULT_MAX_ALARMS_PER_UID;
797 
798         public long APP_STANDBY_WINDOW = DEFAULT_APP_STANDBY_WINDOW;
799         public int[] APP_STANDBY_QUOTAS = new int[DEFAULT_APP_STANDBY_QUOTAS.length];
800         public int APP_STANDBY_RESTRICTED_QUOTA = DEFAULT_APP_STANDBY_RESTRICTED_QUOTA;
801         public long APP_STANDBY_RESTRICTED_WINDOW = DEFAULT_APP_STANDBY_RESTRICTED_WINDOW;
802 
803         public boolean TIME_TICK_ALLOWED_WHILE_IDLE = DEFAULT_TIME_TICK_ALLOWED_WHILE_IDLE;
804 
805         public int ALLOW_WHILE_IDLE_QUOTA = DEFAULT_ALLOW_WHILE_IDLE_QUOTA;
806 
807         /**
808          * Used to provide backwards compatibility to pre-S apps with a quota equivalent to the
809          * earlier delay throttling mechanism.
810          */
811         public int ALLOW_WHILE_IDLE_COMPAT_QUOTA = DEFAULT_ALLOW_WHILE_IDLE_COMPAT_QUOTA;
812 
813         /**
814          * The window used for enforcing {@link #ALLOW_WHILE_IDLE_COMPAT_QUOTA}.
815          * Can be configured, but only recommended for testing.
816          */
817         public long ALLOW_WHILE_IDLE_COMPAT_WINDOW = DEFAULT_ALLOW_WHILE_IDLE_COMPAT_WINDOW;
818 
819         /**
820          * The window used for enforcing {@link #ALLOW_WHILE_IDLE_COMPAT_QUOTA}.
821          * Can be configured, but only recommended for testing.
822          */
823         public long ALLOW_WHILE_IDLE_WINDOW = DEFAULT_ALLOW_WHILE_IDLE_WINDOW;
824 
825         /**
826          * Minimum delay between two slots that an app can get for their prioritized alarms, while
827          * the device is in doze.
828          */
829         public long PRIORITY_ALARM_DELAY = DEFAULT_PRIORITY_ALARM_DELAY;
830 
831         /**
832          * Minimum time interval that an IDLE_UNTIL will be pulled earlier to a subsequent
833          * WAKE_FROM_IDLE alarm.
834          */
835         public long MIN_DEVICE_IDLE_FUZZ = DEFAULT_MIN_DEVICE_IDLE_FUZZ;
836 
837         /**
838          * Maximum time interval that an IDLE_UNTIL will be pulled earlier to a subsequent
839          * WAKE_FROM_IDLE alarm.
840          */
841         public long MAX_DEVICE_IDLE_FUZZ = DEFAULT_MAX_DEVICE_IDLE_FUZZ;
842 
843         /**
844          * The amount of temporary reserve quota to give apps on receiving the
845          * {@link AppIdleStateChangeListener#triggerTemporaryQuotaBump(String, int)} callback
846          * from {@link com.android.server.usage.AppStandbyController}.
847          * <p> This quota adds on top of the standard standby bucket quota available to the app, and
848          * works the same way, i.e. each count of quota denotes one point in time when the app can
849          * receive any number of alarms together.
850          * This quota is tracked per package and expires after {@link #TEMPORARY_QUOTA_DURATION}.
851          */
852         public int TEMPORARY_QUOTA_BUMP = DEFAULT_TEMPORARY_QUOTA_BUMP;
853 
854         public boolean DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF =
855                 DEFAULT_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF;
856 
857         /**
858          * Exact listener alarms for apps that get cached are removed after this duration. This is
859          * a grace period to allow for transient procstate changes, e.g., when the app switches
860          * between different lifecycles.
861          */
862         public long CACHED_LISTENER_REMOVAL_DELAY = DEFAULT_CACHED_LISTENER_REMOVAL_DELAY;
863 
864         private long mLastAllowWhileIdleWhitelistDuration = -1;
865         private int mVersion = 0;
866 
Constants(Handler handler)867         Constants(Handler handler) {
868             updateAllowWhileIdleWhitelistDurationLocked();
869             for (int i = 0; i < APP_STANDBY_QUOTAS.length; i++) {
870                 APP_STANDBY_QUOTAS[i] = DEFAULT_APP_STANDBY_QUOTAS[i];
871             }
872         }
873 
getVersion()874         public int getVersion() {
875             synchronized (mLock) {
876                 return mVersion;
877             }
878         }
879 
start()880         public void start() {
881             mInjector.registerDeviceConfigListener(this);
882             onPropertiesChanged(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_ALARM_MANAGER));
883         }
884 
885         @SuppressLint("MissingPermission")
updateAllowWhileIdleWhitelistDurationLocked()886         public void updateAllowWhileIdleWhitelistDurationLocked() {
887             if (mLastAllowWhileIdleWhitelistDuration != ALLOW_WHILE_IDLE_WHITELIST_DURATION) {
888                 mLastAllowWhileIdleWhitelistDuration = ALLOW_WHILE_IDLE_WHITELIST_DURATION;
889 
890                 mOptsWithFgs.setTemporaryAppAllowlist(ALLOW_WHILE_IDLE_WHITELIST_DURATION,
891                         TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
892                         REASON_ALARM_MANAGER_WHILE_IDLE, "");
893                 mOptsWithFgsForAlarmClock.setTemporaryAppAllowlist(
894                         ALLOW_WHILE_IDLE_WHITELIST_DURATION,
895                         TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
896                         REASON_ALARM_MANAGER_ALARM_CLOCK, "");
897                 mOptsWithoutFgs.setTemporaryAppAllowlist(ALLOW_WHILE_IDLE_WHITELIST_DURATION,
898                         TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED, REASON_DENIED, "");
899             }
900         }
901 
902         @Override
onPropertiesChanged(@onNull DeviceConfig.Properties properties)903         public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) {
904             boolean standbyQuotaUpdated = false;
905             boolean deviceIdleFuzzBoundariesUpdated = false;
906             synchronized (mLock) {
907                 mVersion++;
908                 for (String name : properties.getKeyset()) {
909                     if (name == null) {
910                         continue;
911                     }
912 
913                     switch (name) {
914                         case KEY_MIN_FUTURITY:
915                             MIN_FUTURITY = properties.getLong(
916                                     KEY_MIN_FUTURITY, DEFAULT_MIN_FUTURITY);
917                             break;
918                         case KEY_MIN_INTERVAL:
919                             MIN_INTERVAL = properties.getLong(
920                                     KEY_MIN_INTERVAL, DEFAULT_MIN_INTERVAL);
921                             break;
922                         case KEY_MAX_INTERVAL:
923                             MAX_INTERVAL = properties.getLong(
924                                     KEY_MAX_INTERVAL, DEFAULT_MAX_INTERVAL);
925                             break;
926                         case KEY_ALLOW_WHILE_IDLE_QUOTA:
927                             ALLOW_WHILE_IDLE_QUOTA = properties.getInt(KEY_ALLOW_WHILE_IDLE_QUOTA,
928                                     DEFAULT_ALLOW_WHILE_IDLE_QUOTA);
929                             if (ALLOW_WHILE_IDLE_QUOTA <= 0) {
930                                 Slog.w(TAG, "Must have positive allow_while_idle quota");
931                                 ALLOW_WHILE_IDLE_QUOTA = 1;
932                             }
933                             break;
934                         case KEY_MIN_WINDOW:
935                             MIN_WINDOW = properties.getLong(KEY_MIN_WINDOW, DEFAULT_MIN_WINDOW);
936                             break;
937                         case KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA:
938                             ALLOW_WHILE_IDLE_COMPAT_QUOTA = properties.getInt(
939                                     KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA,
940                                     DEFAULT_ALLOW_WHILE_IDLE_COMPAT_QUOTA);
941                             if (ALLOW_WHILE_IDLE_COMPAT_QUOTA <= 0) {
942                                 Slog.w(TAG, "Must have positive allow_while_idle_compat quota");
943                                 ALLOW_WHILE_IDLE_COMPAT_QUOTA = 1;
944                             }
945                             break;
946                         case KEY_ALLOW_WHILE_IDLE_WINDOW:
947                             ALLOW_WHILE_IDLE_WINDOW = properties.getLong(
948                                     KEY_ALLOW_WHILE_IDLE_WINDOW, DEFAULT_ALLOW_WHILE_IDLE_WINDOW);
949 
950                             if (ALLOW_WHILE_IDLE_WINDOW > INTERVAL_HOUR) {
951                                 Slog.w(TAG, "Cannot have allow_while_idle_window > "
952                                         + INTERVAL_HOUR);
953                                 ALLOW_WHILE_IDLE_WINDOW = INTERVAL_HOUR;
954                             } else if (ALLOW_WHILE_IDLE_WINDOW != DEFAULT_ALLOW_WHILE_IDLE_WINDOW) {
955                                 Slog.w(TAG, "Using a non-default allow_while_idle_window = "
956                                         + ALLOW_WHILE_IDLE_WINDOW);
957                             }
958                             break;
959                         case KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW:
960                             ALLOW_WHILE_IDLE_COMPAT_WINDOW = properties.getLong(
961                                     KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW,
962                                     DEFAULT_ALLOW_WHILE_IDLE_COMPAT_WINDOW);
963 
964                             if (ALLOW_WHILE_IDLE_COMPAT_WINDOW > INTERVAL_HOUR) {
965                                 Slog.w(TAG, "Cannot have allow_while_idle_compat_window > "
966                                         + INTERVAL_HOUR);
967                                 ALLOW_WHILE_IDLE_COMPAT_WINDOW = INTERVAL_HOUR;
968                             } else if (ALLOW_WHILE_IDLE_COMPAT_WINDOW
969                                     != DEFAULT_ALLOW_WHILE_IDLE_COMPAT_WINDOW) {
970                                 Slog.w(TAG, "Using a non-default allow_while_idle_compat_window = "
971                                         + ALLOW_WHILE_IDLE_COMPAT_WINDOW);
972                             }
973                             break;
974                         case KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION:
975                             ALLOW_WHILE_IDLE_WHITELIST_DURATION = properties.getLong(
976                                     KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION,
977                                     DEFAULT_ALLOW_WHILE_IDLE_ALLOWLIST_DURATION);
978                             updateAllowWhileIdleWhitelistDurationLocked();
979                             break;
980                         case KEY_LISTENER_TIMEOUT:
981                             LISTENER_TIMEOUT = properties.getLong(
982                                     KEY_LISTENER_TIMEOUT, DEFAULT_LISTENER_TIMEOUT);
983                             break;
984                         case KEY_MAX_ALARMS_PER_UID:
985                             MAX_ALARMS_PER_UID = properties.getInt(
986                                     KEY_MAX_ALARMS_PER_UID, DEFAULT_MAX_ALARMS_PER_UID);
987                             if (MAX_ALARMS_PER_UID < DEFAULT_MAX_ALARMS_PER_UID) {
988                                 Slog.w(TAG, "Cannot set " + KEY_MAX_ALARMS_PER_UID + " lower than "
989                                         + DEFAULT_MAX_ALARMS_PER_UID);
990                                 MAX_ALARMS_PER_UID = DEFAULT_MAX_ALARMS_PER_UID;
991                             }
992                             break;
993                         case KEY_APP_STANDBY_WINDOW:
994                         case KEY_APP_STANDBY_RESTRICTED_WINDOW:
995                             updateStandbyWindowsLocked();
996                             break;
997                         case KEY_TIME_TICK_ALLOWED_WHILE_IDLE:
998                             TIME_TICK_ALLOWED_WHILE_IDLE = properties.getBoolean(
999                                     KEY_TIME_TICK_ALLOWED_WHILE_IDLE,
1000                                     DEFAULT_TIME_TICK_ALLOWED_WHILE_IDLE);
1001                             break;
1002                         case KEY_PRIORITY_ALARM_DELAY:
1003                             PRIORITY_ALARM_DELAY = properties.getLong(KEY_PRIORITY_ALARM_DELAY,
1004                                     DEFAULT_PRIORITY_ALARM_DELAY);
1005                             break;
1006                         case KEY_MIN_DEVICE_IDLE_FUZZ:
1007                         case KEY_MAX_DEVICE_IDLE_FUZZ:
1008                             if (!deviceIdleFuzzBoundariesUpdated) {
1009                                 updateDeviceIdleFuzzBoundaries();
1010                                 deviceIdleFuzzBoundariesUpdated = true;
1011                             }
1012                             break;
1013                         case KEY_TEMPORARY_QUOTA_BUMP:
1014                             TEMPORARY_QUOTA_BUMP = properties.getInt(KEY_TEMPORARY_QUOTA_BUMP,
1015                                     DEFAULT_TEMPORARY_QUOTA_BUMP);
1016                             break;
1017                         case KEY_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF:
1018                             DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF = properties.getBoolean(
1019                                     KEY_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF,
1020                                     DEFAULT_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF);
1021                             break;
1022                         case KEY_CACHED_LISTENER_REMOVAL_DELAY:
1023                             CACHED_LISTENER_REMOVAL_DELAY = properties.getLong(
1024                                     KEY_CACHED_LISTENER_REMOVAL_DELAY,
1025                                     DEFAULT_CACHED_LISTENER_REMOVAL_DELAY);
1026                             break;
1027                         default:
1028                             if (name.startsWith(KEY_PREFIX_STANDBY_QUOTA) && !standbyQuotaUpdated) {
1029                                 // The quotas need to be updated in order, so we can't just rely
1030                                 // on the property iteration order.
1031                                 updateStandbyQuotasLocked();
1032                                 standbyQuotaUpdated = true;
1033                             }
1034                             break;
1035                     }
1036                 }
1037             }
1038         }
1039 
updateDeviceIdleFuzzBoundaries()1040         private void updateDeviceIdleFuzzBoundaries() {
1041             final DeviceConfig.Properties properties = DeviceConfig.getProperties(
1042                     DeviceConfig.NAMESPACE_ALARM_MANAGER,
1043                     KEY_MIN_DEVICE_IDLE_FUZZ, KEY_MAX_DEVICE_IDLE_FUZZ);
1044 
1045             MIN_DEVICE_IDLE_FUZZ = properties.getLong(KEY_MIN_DEVICE_IDLE_FUZZ,
1046                     DEFAULT_MIN_DEVICE_IDLE_FUZZ);
1047             MAX_DEVICE_IDLE_FUZZ = properties.getLong(KEY_MAX_DEVICE_IDLE_FUZZ,
1048                     DEFAULT_MAX_DEVICE_IDLE_FUZZ);
1049 
1050             if (MAX_DEVICE_IDLE_FUZZ < MIN_DEVICE_IDLE_FUZZ) {
1051                 Slog.w(TAG, "max_device_idle_fuzz cannot be smaller than"
1052                         + " min_device_idle_fuzz! Increasing to "
1053                         + MIN_DEVICE_IDLE_FUZZ);
1054                 MAX_DEVICE_IDLE_FUZZ = MIN_DEVICE_IDLE_FUZZ;
1055             }
1056         }
1057 
updateStandbyQuotasLocked()1058         private void updateStandbyQuotasLocked() {
1059             // The bucket quotas need to be read as an atomic unit but the properties passed to
1060             // onPropertiesChanged may only have one key populated at a time.
1061             final DeviceConfig.Properties properties = DeviceConfig.getProperties(
1062                     DeviceConfig.NAMESPACE_ALARM_MANAGER, KEYS_APP_STANDBY_QUOTAS);
1063 
1064             APP_STANDBY_QUOTAS[ACTIVE_INDEX] = properties.getInt(
1065                     KEYS_APP_STANDBY_QUOTAS[ACTIVE_INDEX],
1066                     DEFAULT_APP_STANDBY_QUOTAS[ACTIVE_INDEX]);
1067             for (int i = WORKING_INDEX; i < KEYS_APP_STANDBY_QUOTAS.length; i++) {
1068                 APP_STANDBY_QUOTAS[i] = properties.getInt(
1069                         KEYS_APP_STANDBY_QUOTAS[i],
1070                         Math.min(APP_STANDBY_QUOTAS[i - 1], DEFAULT_APP_STANDBY_QUOTAS[i]));
1071             }
1072 
1073             APP_STANDBY_RESTRICTED_QUOTA = Math.max(1,
1074                     DeviceConfig.getInt(DeviceConfig.NAMESPACE_ALARM_MANAGER,
1075                             KEY_APP_STANDBY_RESTRICTED_QUOTA,
1076                             DEFAULT_APP_STANDBY_RESTRICTED_QUOTA));
1077         }
1078 
updateStandbyWindowsLocked()1079         private void updateStandbyWindowsLocked() {
1080             // The bucket windows need to be read as an atomic unit but the properties passed to
1081             // onPropertiesChanged may only have one key populated at a time.
1082             final DeviceConfig.Properties properties = DeviceConfig.getProperties(
1083                     DeviceConfig.NAMESPACE_ALARM_MANAGER,
1084                     KEY_APP_STANDBY_WINDOW, KEY_APP_STANDBY_RESTRICTED_WINDOW);
1085             APP_STANDBY_WINDOW = properties.getLong(
1086                     KEY_APP_STANDBY_WINDOW, DEFAULT_APP_STANDBY_WINDOW);
1087             if (APP_STANDBY_WINDOW > DEFAULT_APP_STANDBY_WINDOW) {
1088                 Slog.w(TAG, "Cannot exceed the app_standby_window size of "
1089                         + DEFAULT_APP_STANDBY_WINDOW);
1090                 APP_STANDBY_WINDOW = DEFAULT_APP_STANDBY_WINDOW;
1091             } else if (APP_STANDBY_WINDOW < DEFAULT_APP_STANDBY_WINDOW) {
1092                 // Not recommended outside of testing.
1093                 Slog.w(TAG, "Using a non-default app_standby_window of " + APP_STANDBY_WINDOW);
1094             }
1095 
1096             APP_STANDBY_RESTRICTED_WINDOW = Math.max(APP_STANDBY_WINDOW,
1097                     properties.getLong(
1098                             KEY_APP_STANDBY_RESTRICTED_WINDOW,
1099                             DEFAULT_APP_STANDBY_RESTRICTED_WINDOW));
1100         }
1101 
dump(IndentingPrintWriter pw)1102         void dump(IndentingPrintWriter pw) {
1103             pw.println("Settings:");
1104 
1105             pw.increaseIndent();
1106 
1107             pw.print("version", mVersion);
1108             pw.println();
1109 
1110             pw.print(KEY_MIN_FUTURITY);
1111             pw.print("=");
1112             TimeUtils.formatDuration(MIN_FUTURITY, pw);
1113             pw.println();
1114 
1115             pw.print(KEY_MIN_INTERVAL);
1116             pw.print("=");
1117             TimeUtils.formatDuration(MIN_INTERVAL, pw);
1118             pw.println();
1119 
1120             pw.print(KEY_MAX_INTERVAL);
1121             pw.print("=");
1122             TimeUtils.formatDuration(MAX_INTERVAL, pw);
1123             pw.println();
1124 
1125             pw.print(KEY_MIN_WINDOW);
1126             pw.print("=");
1127             TimeUtils.formatDuration(MIN_WINDOW, pw);
1128             pw.println();
1129 
1130             pw.print(KEY_LISTENER_TIMEOUT);
1131             pw.print("=");
1132             TimeUtils.formatDuration(LISTENER_TIMEOUT, pw);
1133             pw.println();
1134 
1135             pw.print(KEY_ALLOW_WHILE_IDLE_QUOTA, ALLOW_WHILE_IDLE_QUOTA);
1136             pw.println();
1137 
1138             pw.print(KEY_ALLOW_WHILE_IDLE_WINDOW);
1139             pw.print("=");
1140             TimeUtils.formatDuration(ALLOW_WHILE_IDLE_WINDOW, pw);
1141             pw.println();
1142 
1143             pw.print(KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA, ALLOW_WHILE_IDLE_COMPAT_QUOTA);
1144             pw.println();
1145 
1146             pw.print(KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW);
1147             pw.print("=");
1148             TimeUtils.formatDuration(ALLOW_WHILE_IDLE_COMPAT_WINDOW, pw);
1149             pw.println();
1150 
1151             pw.print(KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION);
1152             pw.print("=");
1153             TimeUtils.formatDuration(ALLOW_WHILE_IDLE_WHITELIST_DURATION, pw);
1154             pw.println();
1155 
1156             pw.print(KEY_MAX_ALARMS_PER_UID, MAX_ALARMS_PER_UID);
1157             pw.println();
1158 
1159             pw.print(KEY_APP_STANDBY_WINDOW);
1160             pw.print("=");
1161             TimeUtils.formatDuration(APP_STANDBY_WINDOW, pw);
1162             pw.println();
1163 
1164             for (int i = 0; i < KEYS_APP_STANDBY_QUOTAS.length; i++) {
1165                 pw.print(KEYS_APP_STANDBY_QUOTAS[i], APP_STANDBY_QUOTAS[i]);
1166                 pw.println();
1167             }
1168 
1169             pw.print(KEY_APP_STANDBY_RESTRICTED_QUOTA, APP_STANDBY_RESTRICTED_QUOTA);
1170             pw.println();
1171 
1172             pw.print(KEY_APP_STANDBY_RESTRICTED_WINDOW);
1173             pw.print("=");
1174             TimeUtils.formatDuration(APP_STANDBY_RESTRICTED_WINDOW, pw);
1175             pw.println();
1176 
1177             pw.print(KEY_TIME_TICK_ALLOWED_WHILE_IDLE, TIME_TICK_ALLOWED_WHILE_IDLE);
1178             pw.println();
1179 
1180             pw.print(KEY_PRIORITY_ALARM_DELAY);
1181             pw.print("=");
1182             TimeUtils.formatDuration(PRIORITY_ALARM_DELAY, pw);
1183             pw.println();
1184 
1185             pw.print(KEY_MIN_DEVICE_IDLE_FUZZ);
1186             pw.print("=");
1187             TimeUtils.formatDuration(MIN_DEVICE_IDLE_FUZZ, pw);
1188             pw.println();
1189 
1190             pw.print(KEY_MAX_DEVICE_IDLE_FUZZ);
1191             pw.print("=");
1192             TimeUtils.formatDuration(MAX_DEVICE_IDLE_FUZZ, pw);
1193             pw.println();
1194 
1195             pw.print(KEY_TEMPORARY_QUOTA_BUMP, TEMPORARY_QUOTA_BUMP);
1196             pw.println();
1197 
1198             pw.print(KEY_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF,
1199                     DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF);
1200             pw.println();
1201 
1202             pw.print(KEY_CACHED_LISTENER_REMOVAL_DELAY);
1203             pw.print("=");
1204             TimeUtils.formatDuration(CACHED_LISTENER_REMOVAL_DELAY, pw);
1205             pw.println();
1206 
1207             pw.decreaseIndent();
1208         }
1209 
dumpProto(ProtoOutputStream proto, long fieldId)1210         void dumpProto(ProtoOutputStream proto, long fieldId) {
1211             final long token = proto.start(fieldId);
1212 
1213             proto.write(ConstantsProto.MIN_FUTURITY_DURATION_MS, MIN_FUTURITY);
1214             proto.write(ConstantsProto.MIN_INTERVAL_DURATION_MS, MIN_INTERVAL);
1215             proto.write(ConstantsProto.MAX_INTERVAL_DURATION_MS, MAX_INTERVAL);
1216             proto.write(ConstantsProto.LISTENER_TIMEOUT_DURATION_MS, LISTENER_TIMEOUT);
1217             proto.write(ConstantsProto.ALLOW_WHILE_IDLE_WHITELIST_DURATION_MS,
1218                     ALLOW_WHILE_IDLE_WHITELIST_DURATION);
1219 
1220             proto.end(token);
1221         }
1222     }
1223 
1224     Constants mConstants;
1225 
1226     /** Dispatch priority to use for system alarms. */
1227     static final int PRIORITY_SYSTEM = 0;
1228     /** Dispatch priority to use for a package that has any wakeup alarm in the pending batch. */
1229     static final int PRIORITY_WAKEUP = 1;
1230     /** The default dispatch priority to use when no special conditions apply. */
1231     static final int PRIORITY_NORMAL = 2;
1232 
1233     /**
1234      * Priority to assign to alarms in an outgoing batch. Higher priority alarms are considered more
1235      * urgent than lower priority ones (smaller value is higher priority). Priorities are assigned
1236      * per package, so all alarms in one package will share the same priority in an outgoing batch -
1237      * which should be the highest (minimum) priority computed over all its alarms.
1238      * This is done to ensure that alarms in the same package preserve their relative ordering.
1239      */
1240     @IntDef(prefix = "PRIORITY_", value = {
1241             PRIORITY_SYSTEM,
1242             PRIORITY_WAKEUP,
1243             PRIORITY_NORMAL,
1244     })
1245     @Retention(RetentionPolicy.SOURCE)
1246     public @interface DispatchPriority {}
1247 
1248     final Comparator<Alarm> mAlarmDispatchComparator = (lhs, rhs) -> {
1249 
1250         // Alarm to exit device_idle should go out first.
1251         final boolean idleUntil1 = (lhs.flags & FLAG_IDLE_UNTIL) != 0;
1252         final boolean idleUntil2 = (rhs.flags & FLAG_IDLE_UNTIL) != 0;
1253         if (idleUntil1 != idleUntil2) {
1254             return idleUntil1 ? -1 : 1;
1255         }
1256 
1257         // Then, priority class trumps everything.  SYSTEM < WAKEUP < NORMAL
1258         if (lhs.priorityClass < rhs.priorityClass) {
1259             return -1;
1260         } else if (lhs.priorityClass > rhs.priorityClass) {
1261             return 1;
1262         }
1263 
1264         // Within all system alarms, pulling time_tick to the front, as it is time-sensitive.
1265         final boolean timeTick1 = (lhs.listener == mTimeTickTrigger);
1266         final boolean timeTick2 = (rhs.listener == mTimeTickTrigger);
1267         if (timeTick1 != timeTick2) {
1268             return timeTick1 ? -1 : 1;
1269         }
1270 
1271         // Within each class, sort by requested delivery time
1272         if (lhs.getRequestedElapsed() < rhs.getRequestedElapsed()) {
1273             return -1;
1274         } else if (lhs.getRequestedElapsed() > rhs.getRequestedElapsed()) {
1275             return 1;
1276         }
1277 
1278         return 0;
1279     };
1280 
1281     /**
1282      * Assigns a {@link DispatchPriority} to each alarm that will be used to order alarms in an
1283      * outgoing batch.
1284      *
1285      * @param alarms The batch of alarms about to be sent.
1286      */
calculateDeliveryPriorities(ArrayList<Alarm> alarms)1287     void calculateDeliveryPriorities(ArrayList<Alarm> alarms) {
1288         final int N = alarms.size();
1289 
1290         // Batches are expected to be small (generally N < 10). So an additional iteration to
1291         // collect a small set of UserPackage objects should be unnoticeable.
1292         final ArraySet<UserPackage> wakeupPackages = new ArraySet<>(4);
1293         for (int i = 0; i < N; i++) {
1294             final Alarm a = alarms.get(i);
1295             if (a.wakeup) {
1296                 wakeupPackages.add(
1297                         UserPackage.of(UserHandle.getUserId(a.creatorUid), a.sourcePackage));
1298             }
1299         }
1300 
1301         for (int i = 0; i < N; i++) {
1302             final Alarm a = alarms.get(i);
1303 
1304             if (a.creatorUid == Process.SYSTEM_UID && "android".equals(a.sourcePackage)) {
1305                 a.priorityClass = PRIORITY_SYSTEM;
1306             } else if (wakeupPackages.contains(
1307                     UserPackage.of(UserHandle.getUserId(a.creatorUid), a.sourcePackage))) {
1308                 a.priorityClass = PRIORITY_WAKEUP;
1309             } else {
1310                 a.priorityClass = PRIORITY_NORMAL;
1311             }
1312         }
1313     }
1314 
1315     // minimum recurrence period or alarm futurity for us to be able to fuzz it
1316     static final long MIN_FUZZABLE_INTERVAL = 10000;
1317     @GuardedBy("mLock")
1318     AlarmStore mAlarmStore;
1319 
1320     UserWakeupStore mUserWakeupStore;
1321     // set to non-null if in idle mode; while in this mode, any alarms we don't want
1322     // to run during this time are rescehduled to go off after this alarm.
1323     Alarm mPendingIdleUntil = null;
1324     Alarm mNextWakeFromIdle = null;
1325 
1326     @VisibleForTesting
AlarmManagerService(Context context, Injector injector)1327     AlarmManagerService(Context context, Injector injector) {
1328         super(context);
1329         mInjector = injector;
1330     }
1331 
AlarmManagerService(Context context)1332     public AlarmManagerService(Context context) {
1333         this(context, new Injector(context));
1334     }
1335 
isRtc(int type)1336     static boolean isRtc(int type) {
1337         return (type == RTC || type == RTC_WAKEUP);
1338     }
1339 
convertToElapsed(long when, int type)1340     private long convertToElapsed(long when, int type) {
1341         if (isRtc(type)) {
1342             when -= mInjector.getCurrentTimeMillis() - mInjector.getElapsedRealtimeMillis();
1343         }
1344         return when;
1345     }
1346 
1347     /**
1348      * This is the minimum window that can be requested for the given alarm. Windows smaller than
1349      * this value will be elongated to match it.
1350      * Current heuristic is similar to {@link #maxTriggerTime(long, long, long)}, the minimum
1351      * allowed window is either {@link Constants#MIN_WINDOW} or 75% of the alarm's futurity,
1352      * whichever is smaller.
1353      */
getMinimumAllowedWindow(long nowElapsed, long triggerElapsed)1354     long getMinimumAllowedWindow(long nowElapsed, long triggerElapsed) {
1355         final long futurity = triggerElapsed - nowElapsed;
1356         return Math.min((long) (futurity * 0.75), mConstants.MIN_WINDOW);
1357     }
1358 
1359     // Apply a heuristic to { recurrence interval, futurity of the trigger time } to
1360     // calculate the end of our nominal delivery window for the alarm.
maxTriggerTime(long now, long triggerAtTime, long interval)1361     static long maxTriggerTime(long now, long triggerAtTime, long interval) {
1362         // Current heuristic: batchable window is 75% of either the recurrence interval
1363         // [for a periodic alarm] or of the time from now to the desired delivery time,
1364         // with a minimum delay/interval of 10 seconds, under which we will simply not
1365         // defer the alarm.
1366         long futurity = (interval == 0)
1367                 ? (triggerAtTime - now)
1368                 : interval;
1369         if (futurity < MIN_FUZZABLE_INTERVAL) {
1370             futurity = 0;
1371         }
1372         long maxElapsed = addClampPositive(triggerAtTime, (long) (0.75 * futurity));
1373         // For non-repeating alarms, window is capped at a maximum of one hour from the requested
1374         // delivery time. This allows for inexact-while-idle alarms to be slightly more reliable.
1375         // In practice, the delivery window should generally be much smaller than that
1376         // when the device is not idling.
1377         if (interval == 0) {
1378             maxElapsed = Math.min(maxElapsed, addClampPositive(triggerAtTime, INTERVAL_HOUR));
1379         }
1380         return maxElapsed;
1381     }
1382 
1383     // The RTC clock has moved arbitrarily, so we need to recalculate all the RTC alarm deliveries.
reevaluateRtcAlarms()1384     void reevaluateRtcAlarms() {
1385         synchronized (mLock) {
1386             boolean changed = mAlarmStore.updateAlarmDeliveries(a -> {
1387                 if (!isRtc(a.type)) {
1388                     return false;
1389                 }
1390                 return restoreRequestedTime(a);
1391             });
1392 
1393             if (changed && mPendingIdleUntil != null) {
1394                 if (mNextWakeFromIdle != null && isRtc(mNextWakeFromIdle.type)) {
1395                     // The next wake from idle got updated due to the rtc time change, so we need
1396                     // to update the time we have to come out of idle too.
1397                     final boolean idleUntilUpdated = mAlarmStore.updateAlarmDeliveries(
1398                             a -> (a == mPendingIdleUntil) && adjustIdleUntilTime(a));
1399                     if (idleUntilUpdated) {
1400                         mAlarmStore.updateAlarmDeliveries(
1401                                 alarm -> adjustDeliveryTimeBasedOnDeviceIdle(alarm));
1402                     }
1403                 }
1404             }
1405 
1406             if (changed) {
1407                 rescheduleKernelAlarmsLocked();
1408                 // Only time shifted, so the next alarm clock will not change
1409             }
1410         }
1411     }
1412 
1413     /**
1414      * Recalculates alarm send times based on the current app-standby buckets
1415      *
1416      * @param targetPackages [Package, User] pairs for which alarms need to be re-evaluated,
1417      *                       null indicates all
1418      * @return True if there was any reordering done to the current list.
1419      */
reorderAlarmsBasedOnStandbyBuckets(ArraySet<UserPackage> targetPackages)1420     boolean reorderAlarmsBasedOnStandbyBuckets(ArraySet<UserPackage> targetPackages) {
1421         final long start = mStatLogger.getTime();
1422 
1423         final boolean changed = mAlarmStore.updateAlarmDeliveries(a -> {
1424             final UserPackage userPackage =
1425                     UserPackage.of(UserHandle.getUserId(a.creatorUid), a.sourcePackage);
1426             if (targetPackages != null && !targetPackages.contains(userPackage)) {
1427                 return false;
1428             }
1429             return adjustDeliveryTimeBasedOnBucketLocked(a);
1430         });
1431 
1432         mStatLogger.logDurationStat(Stats.REORDER_ALARMS_FOR_STANDBY, start);
1433         return changed;
1434     }
1435 
restoreRequestedTime(Alarm a)1436     private boolean restoreRequestedTime(Alarm a) {
1437         return a.setPolicyElapsed(REQUESTER_POLICY_INDEX, convertToElapsed(a.origWhen, a.type));
1438     }
1439 
clampPositive(long val)1440     static long clampPositive(long val) {
1441         return (val >= 0) ? val : Long.MAX_VALUE;
1442     }
1443 
addClampPositive(long val1, long val2)1444     static long addClampPositive(long val1, long val2) {
1445         long val = val1 + val2;
1446         if (val >= 0) {
1447             return val;
1448         } else if (val1 >= 0 && val2 >= 0) {
1449             /* Both are +ve, so overflow happened. */
1450             return Long.MAX_VALUE;
1451         } else {
1452             return 0;
1453         }
1454     }
1455 
1456     /**
1457      * Sends alarms that were blocked due to user applied background restrictions - either because
1458      * the user lifted those or the uid came to foreground.
1459      *
1460      * @param uid         uid to filter on
1461      * @param packageName package to filter on, or null for all packages in uid
1462      */
1463     @GuardedBy("mLock")
sendPendingBackgroundAlarmsLocked(int uid, String packageName)1464     void sendPendingBackgroundAlarmsLocked(int uid, String packageName) {
1465         final ArrayList<Alarm> alarmsForUid = mPendingBackgroundAlarms.get(uid);
1466         if (alarmsForUid == null || alarmsForUid.size() == 0) {
1467             return;
1468         }
1469         final ArrayList<Alarm> alarmsToDeliver;
1470         if (packageName != null) {
1471             if (DEBUG_BG_LIMIT) {
1472                 Slog.d(TAG, "Sending blocked alarms for uid " + uid + ", package " + packageName);
1473             }
1474             alarmsToDeliver = new ArrayList<>();
1475             for (int i = alarmsForUid.size() - 1; i >= 0; i--) {
1476                 final Alarm a = alarmsForUid.get(i);
1477                 if (a.matches(packageName)) {
1478                     alarmsToDeliver.add(alarmsForUid.remove(i));
1479                 }
1480             }
1481             if (alarmsForUid.size() == 0) {
1482                 mPendingBackgroundAlarms.remove(uid);
1483             }
1484         } else {
1485             if (DEBUG_BG_LIMIT) {
1486                 Slog.d(TAG, "Sending blocked alarms for uid " + uid);
1487             }
1488             alarmsToDeliver = alarmsForUid;
1489             mPendingBackgroundAlarms.remove(uid);
1490         }
1491         deliverPendingBackgroundAlarmsLocked(alarmsToDeliver, mInjector.getElapsedRealtimeMillis());
1492     }
1493 
1494     /**
1495      * Check all alarms in {@link #mPendingBackgroundAlarms} and send the ones that are not
1496      * restricted.
1497      *
1498      * This is only called when the power save allowlist changes, so it's okay to be slow.
1499      */
1500     @GuardedBy("mLock")
sendAllUnrestrictedPendingBackgroundAlarmsLocked()1501     void sendAllUnrestrictedPendingBackgroundAlarmsLocked() {
1502         final ArrayList<Alarm> alarmsToDeliver = new ArrayList<>();
1503 
1504         findAllUnrestrictedPendingBackgroundAlarmsLockedInner(
1505                 mPendingBackgroundAlarms, alarmsToDeliver, this::isBackgroundRestricted);
1506 
1507         if (alarmsToDeliver.size() > 0) {
1508             deliverPendingBackgroundAlarmsLocked(
1509                     alarmsToDeliver, mInjector.getElapsedRealtimeMillis());
1510         }
1511     }
1512 
1513     @VisibleForTesting
findAllUnrestrictedPendingBackgroundAlarmsLockedInner( SparseArray<ArrayList<Alarm>> pendingAlarms, ArrayList<Alarm> unrestrictedAlarms, Predicate<Alarm> isBackgroundRestricted)1514     static void findAllUnrestrictedPendingBackgroundAlarmsLockedInner(
1515             SparseArray<ArrayList<Alarm>> pendingAlarms, ArrayList<Alarm> unrestrictedAlarms,
1516             Predicate<Alarm> isBackgroundRestricted) {
1517 
1518         for (int uidIndex = pendingAlarms.size() - 1; uidIndex >= 0; uidIndex--) {
1519             final ArrayList<Alarm> alarmsForUid = pendingAlarms.valueAt(uidIndex);
1520 
1521             for (int alarmIndex = alarmsForUid.size() - 1; alarmIndex >= 0; alarmIndex--) {
1522                 final Alarm alarm = alarmsForUid.get(alarmIndex);
1523 
1524                 if (isBackgroundRestricted.test(alarm)) {
1525                     continue;
1526                 }
1527 
1528                 unrestrictedAlarms.add(alarm);
1529                 alarmsForUid.remove(alarmIndex);
1530             }
1531 
1532             if (alarmsForUid.size() == 0) {
1533                 pendingAlarms.removeAt(uidIndex);
1534             }
1535         }
1536     }
1537 
1538     @GuardedBy("mLock")
deliverPendingBackgroundAlarmsLocked(ArrayList<Alarm> alarms, long nowELAPSED)1539     private void deliverPendingBackgroundAlarmsLocked(ArrayList<Alarm> alarms, long nowELAPSED) {
1540         final int N = alarms.size();
1541         boolean hasWakeup = false;
1542         for (int i = 0; i < N; i++) {
1543             final Alarm alarm = alarms.get(i);
1544             if (alarm.wakeup) {
1545                 hasWakeup = true;
1546             }
1547             alarm.count = 1;
1548             // Recurring alarms may have passed several alarm intervals while the
1549             // alarm was kept pending. Send the appropriate trigger count.
1550             if (alarm.repeatInterval > 0) {
1551                 alarm.count += (nowELAPSED - alarm.getRequestedElapsed()) / alarm.repeatInterval;
1552                 // Also schedule its next recurrence
1553                 final long delta = alarm.count * alarm.repeatInterval;
1554                 final long nextElapsed = alarm.getRequestedElapsed() + delta;
1555                 final long nextMaxElapsed = maxTriggerTime(nowELAPSED, nextElapsed,
1556                         alarm.repeatInterval);
1557                 setImplLocked(alarm.type, alarm.origWhen + delta, nextElapsed,
1558                         nextMaxElapsed - nextElapsed, alarm.repeatInterval, alarm.operation, null,
1559                         null, alarm.flags, alarm.workSource, alarm.alarmClock, alarm.uid,
1560                         alarm.packageName, null, EXACT_ALLOW_REASON_NOT_APPLICABLE);
1561                 // Kernel alarms will be rescheduled as needed in setImplLocked
1562             }
1563         }
1564         if (!hasWakeup && checkAllowNonWakeupDelayLocked(nowELAPSED)) {
1565             // No need to wakeup for non wakeup alarms
1566             if (mPendingNonWakeupAlarms.size() == 0) {
1567                 mStartCurrentDelayTime = nowELAPSED;
1568                 mNextNonWakeupDeliveryTime = nowELAPSED
1569                         + ((currentNonWakeupFuzzLocked(nowELAPSED) * 3) / 2);
1570             }
1571             mPendingNonWakeupAlarms.addAll(alarms);
1572             mNumDelayedAlarms += alarms.size();
1573         } else {
1574             if (DEBUG_BG_LIMIT) {
1575                 Slog.d(TAG, "Waking up to deliver pending blocked alarms");
1576             }
1577             // Since we are waking up, also deliver any pending non wakeup alarms we have.
1578             if (mPendingNonWakeupAlarms.size() > 0) {
1579                 alarms.addAll(mPendingNonWakeupAlarms);
1580                 final long thisDelayTime = nowELAPSED - mStartCurrentDelayTime;
1581                 mTotalDelayTime += thisDelayTime;
1582                 if (mMaxDelayTime < thisDelayTime) {
1583                     mMaxDelayTime = thisDelayTime;
1584                 }
1585                 mPendingNonWakeupAlarms.clear();
1586             }
1587             calculateDeliveryPriorities(alarms);
1588             Collections.sort(alarms, mAlarmDispatchComparator);
1589             deliverAlarmsLocked(alarms, nowELAPSED);
1590         }
1591     }
1592 
1593     static final class InFlight {
1594         final PendingIntent mPendingIntent;
1595         final long mWhenElapsed;
1596         final IBinder mListener;
1597         final WorkSource mWorkSource;
1598         final int mUid;
1599         final int mCreatorUid;
1600         final String mTag;
1601         final BroadcastStats mBroadcastStats;
1602         final FilterStats mFilterStats;
1603         final int mAlarmType;
1604         final int mPriorityClass;
1605 
InFlight(AlarmManagerService service, Alarm alarm, long nowELAPSED)1606         InFlight(AlarmManagerService service, Alarm alarm, long nowELAPSED) {
1607             mPendingIntent = alarm.operation;
1608             mWhenElapsed = nowELAPSED;
1609             mListener = alarm.listener != null ? alarm.listener.asBinder() : null;
1610             mWorkSource = alarm.workSource;
1611             mUid = alarm.uid;
1612             mCreatorUid = alarm.creatorUid;
1613             mTag = alarm.statsTag;
1614             mBroadcastStats = (alarm.operation != null)
1615                     ? service.getStatsLocked(alarm.operation)
1616                     : service.getStatsLocked(alarm.uid, alarm.packageName);
1617             FilterStats fs = mBroadcastStats.filterStats.get(mTag);
1618             if (fs == null) {
1619                 fs = new FilterStats(mBroadcastStats, mTag);
1620                 mBroadcastStats.filterStats.put(mTag, fs);
1621             }
1622             fs.lastTime = nowELAPSED;
1623             mFilterStats = fs;
1624             mAlarmType = alarm.type;
1625             mPriorityClass = alarm.priorityClass;
1626         }
1627 
isBroadcast()1628         boolean isBroadcast() {
1629             return mPendingIntent != null && mPendingIntent.isBroadcast();
1630         }
1631 
1632         @Override
toString()1633         public String toString() {
1634             return "InFlight{"
1635                     + "pendingIntent=" + mPendingIntent
1636                     + ", when=" + mWhenElapsed
1637                     + ", workSource=" + mWorkSource
1638                     + ", uid=" + mUid
1639                     + ", creatorUid=" + mCreatorUid
1640                     + ", tag=" + mTag
1641                     + ", broadcastStats=" + mBroadcastStats
1642                     + ", filterStats=" + mFilterStats
1643                     + ", alarmType=" + mAlarmType
1644                     + ", priorityClass=" + mPriorityClass
1645                     + "}";
1646         }
1647 
dumpDebug(ProtoOutputStream proto, long fieldId)1648         public void dumpDebug(ProtoOutputStream proto, long fieldId) {
1649             final long token = proto.start(fieldId);
1650 
1651             proto.write(InFlightProto.UID, mUid);
1652             proto.write(InFlightProto.TAG, mTag);
1653             proto.write(InFlightProto.WHEN_ELAPSED_MS, mWhenElapsed);
1654             proto.write(InFlightProto.ALARM_TYPE, mAlarmType);
1655             if (mPendingIntent != null) {
1656                 mPendingIntent.dumpDebug(proto, InFlightProto.PENDING_INTENT);
1657             }
1658             if (mBroadcastStats != null) {
1659                 mBroadcastStats.dumpDebug(proto, InFlightProto.BROADCAST_STATS);
1660             }
1661             if (mFilterStats != null) {
1662                 mFilterStats.dumpDebug(proto, InFlightProto.FILTER_STATS);
1663             }
1664             if (mWorkSource != null) {
1665                 mWorkSource.dumpDebug(proto, InFlightProto.WORK_SOURCE);
1666             }
1667 
1668             proto.end(token);
1669         }
1670     }
1671 
notifyBroadcastAlarmPendingLocked(int uid)1672     private void notifyBroadcastAlarmPendingLocked(int uid) {
1673         final int numListeners = mInFlightListeners.size();
1674         for (int i = 0; i < numListeners; i++) {
1675             mInFlightListeners.get(i).broadcastAlarmPending(uid);
1676         }
1677     }
1678 
notifyBroadcastAlarmCompleteLocked(int uid)1679     private void notifyBroadcastAlarmCompleteLocked(int uid) {
1680         final int numListeners = mInFlightListeners.size();
1681         for (int i = 0; i < numListeners; i++) {
1682             mInFlightListeners.get(i).broadcastAlarmComplete(uid);
1683         }
1684     }
1685 
1686     static final class FilterStats {
1687         final BroadcastStats mBroadcastStats;
1688         final String mTag;
1689 
1690         long lastTime;
1691         long aggregateTime;
1692         int count;
1693         int numWakeup;
1694         long startTime;
1695         int nesting;
1696 
FilterStats(BroadcastStats broadcastStats, String tag)1697         FilterStats(BroadcastStats broadcastStats, String tag) {
1698             mBroadcastStats = broadcastStats;
1699             mTag = tag;
1700         }
1701 
1702         @Override
toString()1703         public String toString() {
1704             return "FilterStats{"
1705                     + "tag=" + mTag
1706                     + ", lastTime=" + lastTime
1707                     + ", aggregateTime=" + aggregateTime
1708                     + ", count=" + count
1709                     + ", numWakeup=" + numWakeup
1710                     + ", startTime=" + startTime
1711                     + ", nesting=" + nesting
1712                     + "}";
1713         }
1714 
dumpDebug(ProtoOutputStream proto, long fieldId)1715         public void dumpDebug(ProtoOutputStream proto, long fieldId) {
1716             final long token = proto.start(fieldId);
1717 
1718             proto.write(FilterStatsProto.TAG, mTag);
1719             proto.write(FilterStatsProto.LAST_FLIGHT_TIME_REALTIME, lastTime);
1720             proto.write(FilterStatsProto.TOTAL_FLIGHT_DURATION_MS, aggregateTime);
1721             proto.write(FilterStatsProto.COUNT, count);
1722             proto.write(FilterStatsProto.WAKEUP_COUNT, numWakeup);
1723             proto.write(FilterStatsProto.START_TIME_REALTIME, startTime);
1724             proto.write(FilterStatsProto.NESTING, nesting);
1725 
1726             proto.end(token);
1727         }
1728     }
1729 
1730     static final class BroadcastStats {
1731         final int mUid;
1732         final String mPackageName;
1733 
1734         long aggregateTime;
1735         int count;
1736         int numWakeup;
1737         long startTime;
1738         int nesting;
1739         final ArrayMap<String, FilterStats> filterStats = new ArrayMap<String, FilterStats>();
1740 
BroadcastStats(int uid, String packageName)1741         BroadcastStats(int uid, String packageName) {
1742             mUid = uid;
1743             mPackageName = packageName;
1744         }
1745 
1746         @Override
toString()1747         public String toString() {
1748             return "BroadcastStats{"
1749                     + "uid=" + mUid
1750                     + ", packageName=" + mPackageName
1751                     + ", aggregateTime=" + aggregateTime
1752                     + ", count=" + count
1753                     + ", numWakeup=" + numWakeup
1754                     + ", startTime=" + startTime
1755                     + ", nesting=" + nesting
1756                     + "}";
1757         }
1758 
dumpDebug(ProtoOutputStream proto, long fieldId)1759         public void dumpDebug(ProtoOutputStream proto, long fieldId) {
1760             final long token = proto.start(fieldId);
1761 
1762             proto.write(BroadcastStatsProto.UID, mUid);
1763             proto.write(BroadcastStatsProto.PACKAGE_NAME, mPackageName);
1764             proto.write(BroadcastStatsProto.TOTAL_FLIGHT_DURATION_MS, aggregateTime);
1765             proto.write(BroadcastStatsProto.COUNT, count);
1766             proto.write(BroadcastStatsProto.WAKEUP_COUNT, numWakeup);
1767             proto.write(BroadcastStatsProto.START_TIME_REALTIME, startTime);
1768             proto.write(BroadcastStatsProto.NESTING, nesting);
1769 
1770             proto.end(token);
1771         }
1772     }
1773 
1774     final SparseArray<ArrayMap<String, BroadcastStats>> mBroadcastStats
1775             = new SparseArray<ArrayMap<String, BroadcastStats>>();
1776 
1777     int mNumDelayedAlarms = 0;
1778     long mTotalDelayTime = 0;
1779     long mMaxDelayTime = 0;
1780 
1781     @Override
onStart()1782     public void onStart() {
1783         mInjector.init();
1784         mHandler = new AlarmHandler();
1785 
1786         mOptsWithFgs.setPendingIntentBackgroundActivityLaunchAllowed(false);
1787         mOptsWithFgsForAlarmClock.setPendingIntentBackgroundActivityLaunchAllowed(false);
1788         mOptsWithoutFgs.setPendingIntentBackgroundActivityLaunchAllowed(false);
1789         mOptsTimeBroadcast.setPendingIntentBackgroundActivityLaunchAllowed(false);
1790         mActivityOptsRestrictBal.setPendingIntentBackgroundActivityLaunchAllowed(false);
1791         mBroadcastOptsRestrictBal.setPendingIntentBackgroundActivityLaunchAllowed(false);
1792 
1793         mMetricsHelper = new MetricsHelper(getContext(), mLock);
1794         mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
1795 
1796         mUseFrozenStateToDropListenerAlarms = Flags.useFrozenStateToDropListenerAlarms();
1797         mStartUserBeforeScheduledAlarms = Flags.startUserBeforeScheduledAlarms();
1798         if (mStartUserBeforeScheduledAlarms) {
1799             mUserWakeupStore = new UserWakeupStore();
1800             mUserWakeupStore.init();
1801         }
1802         if (mUseFrozenStateToDropListenerAlarms) {
1803             final ActivityManager.UidFrozenStateChangedCallback callback = (uids, frozenStates) -> {
1804                 final int size = frozenStates.length;
1805                 if (uids.length != size) {
1806                     Slog.wtf(TAG, "Got different length arrays in frozen state callback!"
1807                             + " uids.length: " + uids.length + " frozenStates.length: " + size);
1808                     // Cannot process received data in any meaningful way.
1809                     return;
1810                 }
1811                 final IntArray affectedUids = new IntArray();
1812                 for (int i = 0; i < size; i++) {
1813                     if (frozenStates[i] != UID_FROZEN_STATE_FROZEN) {
1814                         continue;
1815                     }
1816                     if (!CompatChanges.isChangeEnabled(EXACT_LISTENER_ALARMS_DROPPED_ON_CACHED,
1817                             uids[i])) {
1818                         continue;
1819                     }
1820                     affectedUids.add(uids[i]);
1821                 }
1822                 if (affectedUids.size() > 0) {
1823                     removeExactListenerAlarms(affectedUids.toArray());
1824                 }
1825             };
1826             final ActivityManager am = getContext().getSystemService(ActivityManager.class);
1827             am.registerUidFrozenStateChangedCallback(new HandlerExecutor(mHandler), callback);
1828         }
1829 
1830         mListenerDeathRecipient = new IBinder.DeathRecipient() {
1831             @Override
1832             public void binderDied() {
1833             }
1834 
1835             @Override
1836             public void binderDied(IBinder who) {
1837                 final IAlarmListener listener = IAlarmListener.Stub.asInterface(who);
1838                 synchronized (mLock) {
1839                     removeLocked(null, listener, REMOVE_REASON_LISTENER_BINDER_DIED);
1840                 }
1841             }
1842         };
1843 
1844         synchronized (mLock) {
1845             mConstants = new Constants(mHandler);
1846 
1847             mAlarmStore = new LazyAlarmStore();
1848             mAlarmStore.setAlarmClockRemovalListener(mAlarmClockUpdater);
1849 
1850             mAppWakeupHistory = new AppWakeupHistory(Constants.DEFAULT_APP_STANDBY_WINDOW);
1851             mAllowWhileIdleHistory = new AppWakeupHistory(INTERVAL_HOUR);
1852             mAllowWhileIdleCompatHistory = new AppWakeupHistory(INTERVAL_HOUR);
1853 
1854             mTemporaryQuotaReserve = new TemporaryQuotaReserve(TEMPORARY_QUOTA_DURATION);
1855 
1856             mNextWakeup = mNextNonWakeup = 0;
1857 
1858             // Ensure that we're booting with a halfway sensible current time.
1859             mInjector.initializeTimeIfRequired();
1860 
1861             mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
1862             // Determine SysUI's uid
1863             mSystemUiUid = mInjector.getSystemUiUid(mPackageManagerInternal);
1864             if (mSystemUiUid <= 0) {
1865                 Slog.wtf(TAG, "SysUI package not found!");
1866             }
1867             mWakeLock = mInjector.getAlarmWakeLock();
1868 
1869             mTimeTickIntent = new Intent(Intent.ACTION_TIME_TICK).addFlags(
1870                     Intent.FLAG_RECEIVER_REGISTERED_ONLY
1871                             | Intent.FLAG_RECEIVER_FOREGROUND
1872                             | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
1873             mTimeTickOptions = BroadcastOptions.makeBasic()
1874                     .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
1875                     .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE)
1876                     .toBundle();
1877             mTimeTickTrigger = new IAlarmListener.Stub() {
1878                 @Override
1879                 public void doAlarm(final IAlarmCompleteListener callback) throws RemoteException {
1880                     if (DEBUG_BATCH) {
1881                         Slog.v(TAG, "Received TIME_TICK alarm; rescheduling");
1882                     }
1883 
1884                     // Via handler because dispatch invokes this within its lock.  OnAlarmListener
1885                     // takes care of this automatically, but we're using the direct internal
1886                     // interface here rather than that client-side wrapper infrastructure.
1887                     mHandler.post(() -> {
1888                         getContext().sendBroadcastAsUser(mTimeTickIntent, UserHandle.ALL, null,
1889                                 mTimeTickOptions);
1890                         try {
1891                             callback.alarmComplete(this);
1892                         } catch (RemoteException e) { /* local method call */ }
1893                     });
1894 
1895                     synchronized (mLock) {
1896                         mLastTickReceived = mInjector.getCurrentTimeMillis();
1897                     }
1898                     mClockReceiver.scheduleTimeTickEvent();
1899                 }
1900             };
1901 
1902             Intent intent = new Intent(Intent.ACTION_DATE_CHANGED);
1903             intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
1904                     | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
1905             mDateChangeSender = PendingIntent.getBroadcastAsUser(getContext(), 0, intent,
1906                     Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT, UserHandle.ALL);
1907 
1908             mClockReceiver = mInjector.getClockReceiver(this);
1909             new ChargingReceiver();
1910             new InteractiveStateReceiver();
1911             new UninstallReceiver();
1912 
1913             if (mInjector.isAlarmDriverPresent()) {
1914                 AlarmThread waitThread = new AlarmThread();
1915                 waitThread.start();
1916             } else {
1917                 Slog.w(TAG, "Failed to open alarm driver. Falling back to a handler.");
1918             }
1919         }
1920         publishLocalService(AlarmManagerInternal.class, new LocalService());
1921         publishBinderService(Context.ALARM_SERVICE, mService);
1922     }
1923 
removeExactListenerAlarms(int... whichUids)1924     private void removeExactListenerAlarms(int... whichUids) {
1925         synchronized (mLock) {
1926             removeAlarmsInternalLocked(a -> {
1927                 if (!ArrayUtils.contains(whichUids, a.uid) || a.listener == null
1928                         || a.windowLength != 0) {
1929                     return false;
1930                 }
1931                 Slog.w(TAG, "Alarm " + a.listenerTag + " being removed for "
1932                         + UserHandle.formatUid(a.uid) + ":" + a.packageName
1933                         + " because the app got frozen");
1934                 return true;
1935             }, REMOVE_REASON_LISTENER_CACHED);
1936         }
1937     }
1938 
refreshExactAlarmCandidates()1939     void refreshExactAlarmCandidates() {
1940         final String[] candidates = mLocalPermissionManager.getAppOpPermissionPackages(
1941                 Manifest.permission.SCHEDULE_EXACT_ALARM);
1942         final Set<Integer> newAppIds = new ArraySet<>(candidates.length);
1943         for (final String candidate : candidates) {
1944             final int uid = mPackageManagerInternal.getPackageUid(candidate,
1945                     PackageManager.MATCH_ANY_USER, USER_SYSTEM);
1946             if (uid > 0) {
1947                 newAppIds.add(UserHandle.getAppId(uid));
1948             }
1949         }
1950         // Some packages may have lost permission to schedule exact alarms on update, their alarms
1951         // will be removed while handling CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE after this.
1952 
1953         // No need to lock. Assignment is always atomic.
1954         mExactAlarmCandidates = Collections.unmodifiableSet(newAppIds);
1955     }
1956 
1957     @Override
onUserStarting(TargetUser user)1958     public void onUserStarting(TargetUser user) {
1959         super.onUserStarting(user);
1960         final int userId = user.getUserIdentifier();
1961         if (mStartUserBeforeScheduledAlarms) {
1962             mUserWakeupStore.onUserStarting(userId);
1963         }
1964         mHandler.post(() -> {
1965             for (final int appId : mExactAlarmCandidates) {
1966                 final int uid = UserHandle.getUid(userId, appId);
1967                 final AndroidPackage androidPackage = mPackageManagerInternal.getPackage(uid);
1968                 // It will be null if it is not installed on the starting user.
1969                 if (androidPackage != null) {
1970                     final int mode = mAppOps.checkOpNoThrow(AppOpsManager.OP_SCHEDULE_EXACT_ALARM,
1971                             uid, androidPackage.getPackageName());
1972                     synchronized (mLock) {
1973                         mLastOpScheduleExactAlarm.put(uid, mode);
1974                     }
1975                 }
1976             }
1977         });
1978     }
1979 
1980     @Override
onBootPhase(int phase)1981     public void onBootPhase(int phase) {
1982         if (phase == PHASE_SYSTEM_SERVICES_READY) {
1983             synchronized (mLock) {
1984                 mConstants.start();
1985 
1986                 mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE);
1987 
1988                 mLocalDeviceIdleController =
1989                         LocalServices.getService(DeviceIdleInternal.class);
1990                 mUsageStatsManagerInternal =
1991                         LocalServices.getService(UsageStatsManagerInternal.class);
1992 
1993                 mAppStateTracker =
1994                         (AppStateTrackerImpl) LocalServices.getService(AppStateTracker.class);
1995                 mAppStateTracker.addListener(mForceAppStandbyListener);
1996 
1997                 final BatteryManager bm = getContext().getSystemService(BatteryManager.class);
1998                 mAppStandbyParole = bm.isCharging();
1999 
2000                 mClockReceiver.scheduleTimeTickEvent();
2001                 mClockReceiver.scheduleDateChangedEvent();
2002             }
2003             IAppOpsService iAppOpsService = mInjector.getAppOpsService();
2004             try {
2005                 iAppOpsService.startWatchingMode(AppOpsManager.OP_SCHEDULE_EXACT_ALARM, null,
2006                         new IAppOpsCallback.Stub() {
2007                             @Override
2008                             public void opChanged(int op, int uid, String packageName,
2009                                     String persistentDeviceId) throws RemoteException {
2010                                 final int userId = UserHandle.getUserId(uid);
2011                                 if (op != AppOpsManager.OP_SCHEDULE_EXACT_ALARM
2012                                         || !isExactAlarmChangeEnabled(packageName, userId)) {
2013                                     return;
2014                                 }
2015                                 if (hasUseExactAlarmInternal(packageName, uid)) {
2016                                     return;
2017                                 }
2018                                 if (!mExactAlarmCandidates.contains(UserHandle.getAppId(uid))) {
2019                                     // Permission not requested, app op doesn't matter.
2020                                     return;
2021                                 }
2022 
2023                                 final int newMode = mAppOps.checkOpNoThrow(
2024                                         AppOpsManager.OP_SCHEDULE_EXACT_ALARM, uid, packageName);
2025 
2026                                 final int oldMode;
2027                                 synchronized (mLock) {
2028                                     final int index = mLastOpScheduleExactAlarm.indexOfKey(uid);
2029                                     if (index < 0) {
2030                                         oldMode = AppOpsManager.opToDefaultMode(
2031                                                 AppOpsManager.OP_SCHEDULE_EXACT_ALARM);
2032                                         mLastOpScheduleExactAlarm.put(uid, newMode);
2033                                     } else {
2034                                         oldMode = mLastOpScheduleExactAlarm.valueAt(index);
2035                                         mLastOpScheduleExactAlarm.setValueAt(index, newMode);
2036                                     }
2037                                 }
2038                                 if (oldMode == newMode) {
2039                                     return;
2040                                 }
2041                                 final boolean deniedByDefault = isScheduleExactAlarmDeniedByDefault(
2042                                         packageName, UserHandle.getUserId(uid));
2043 
2044                                 final boolean hadPermission;
2045                                 final boolean hasPermission;
2046 
2047                                 if (deniedByDefault) {
2048                                     final boolean permissionState = getContext().checkPermission(
2049                                             Manifest.permission.SCHEDULE_EXACT_ALARM, PID_UNKNOWN,
2050                                             uid) == PackageManager.PERMISSION_GRANTED;
2051                                     hadPermission = (oldMode == AppOpsManager.MODE_DEFAULT)
2052                                             ? permissionState
2053                                             : (oldMode == AppOpsManager.MODE_ALLOWED);
2054                                     hasPermission = (newMode == AppOpsManager.MODE_DEFAULT)
2055                                             ? permissionState
2056                                             : (newMode == AppOpsManager.MODE_ALLOWED);
2057                                 } else {
2058                                     hadPermission = (oldMode == AppOpsManager.MODE_DEFAULT)
2059                                             || (oldMode == AppOpsManager.MODE_ALLOWED);
2060                                     hasPermission = (newMode == AppOpsManager.MODE_DEFAULT)
2061                                             || (newMode == AppOpsManager.MODE_ALLOWED);
2062                                 }
2063 
2064                                 if (hadPermission && !hasPermission) {
2065                                     mHandler.obtainMessage(AlarmHandler.REMOVE_EXACT_ALARMS,
2066                                             uid, 0, packageName).sendToTarget();
2067                                 } else if (!hadPermission && hasPermission) {
2068                                     sendScheduleExactAlarmPermissionStateChangedBroadcast(
2069                                             packageName, userId);
2070                                 }
2071                             }
2072                         });
2073             } catch (RemoteException e) {
2074             }
2075 
2076             mLocalPermissionManager = LocalServices.getService(
2077                     PermissionManagerServiceInternal.class);
2078             refreshExactAlarmCandidates();
2079 
2080             AppStandbyInternal appStandbyInternal =
2081                     LocalServices.getService(AppStandbyInternal.class);
2082             appStandbyInternal.addListener(new AppStandbyTracker());
2083 
2084             mBatteryStatsInternal = LocalServices.getService(BatteryStatsInternal.class);
2085 
2086             mRoleManager = getContext().getSystemService(RoleManager.class);
2087 
2088             mMetricsHelper.registerPuller(() -> mAlarmStore);
2089         }
2090     }
2091 
2092     @Override
finalize()2093     protected void finalize() throws Throwable {
2094         try {
2095             mInjector.close();
2096         } finally {
2097             super.finalize();
2098         }
2099     }
2100 
setTimeImpl( @urrentTimeMillisLong long newSystemClockTimeMillis, @TimeConfidence int confidence, @NonNull String logMsg)2101     boolean setTimeImpl(
2102             @CurrentTimeMillisLong long newSystemClockTimeMillis, @TimeConfidence int confidence,
2103             @NonNull String logMsg) {
2104         synchronized (mLock) {
2105             mInjector.setCurrentTimeMillis(newSystemClockTimeMillis, confidence, logMsg);
2106 
2107             // The native implementation of setKernelTime can return -1 even when the kernel
2108             // time was set correctly, so assume setting kernel time was successful and always
2109             // return true.
2110             return true;
2111         }
2112     }
2113 
setTimeZoneImpl(String tzId, @TimeZoneConfidence int confidence, String logInfo)2114     void setTimeZoneImpl(String tzId, @TimeZoneConfidence int confidence, String logInfo) {
2115         if (TextUtils.isEmpty(tzId)) {
2116             return;
2117         }
2118 
2119         TimeZone newZone = TimeZone.getTimeZone(tzId);
2120         // Prevent reentrant calls from stepping on each other when writing
2121         // the time zone property
2122         boolean timeZoneWasChanged;
2123         synchronized (this) {
2124             // TimeZone.getTimeZone() can return a time zone with a different ID (e.g. it can return
2125             // "GMT" if the ID is unrecognized). The parameter ID is used here rather than
2126             // newZone.getId(). It will be rejected if it is invalid.
2127             timeZoneWasChanged = SystemTimeZone.setTimeZoneId(tzId, confidence, logInfo);
2128 
2129             final int gmtOffset = newZone.getOffset(mInjector.getCurrentTimeMillis());
2130             SystemProperties.set(TIMEOFFSET_PROPERTY, String.valueOf(gmtOffset));
2131 
2132             final ZoneRules rules = newZone.toZoneId().getRules();
2133             final ZoneOffsetTransition transition = rules.nextTransition(Instant.now());
2134             if (null != transition) {
2135                 // Get the offset between the time after the DST transition and before.
2136                 final long transitionOffset = TimeUnit.SECONDS.toMillis((
2137                         transition.getOffsetAfter().getTotalSeconds()
2138                         - transition.getOffsetBefore().getTotalSeconds()));
2139                 // Time when the next DST transition is programmed.
2140                 final long nextTransition = TimeUnit.SECONDS.toMillis(transition.toEpochSecond());
2141                 SystemProperties.set(DST_TRANSITION_PROPERTY, String.valueOf(nextTransition));
2142                 SystemProperties.set(DST_OFFSET_PROPERTY, String.valueOf(transitionOffset));
2143             }
2144         }
2145 
2146         // Clear the default time zone in the system server process. This forces the next call
2147         // to TimeZone.getDefault() to re-read the device settings.
2148         TimeZone.setDefault(null);
2149 
2150         if (timeZoneWasChanged) {
2151             // Don't wait for broadcasts to update our midnight alarm
2152             mClockReceiver.scheduleDateChangedEvent();
2153 
2154             // And now let everyone else know
2155             Intent intent = new Intent(Intent.ACTION_TIMEZONE_CHANGED);
2156             intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
2157                     | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
2158                     | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
2159                     | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
2160             intent.putExtra(Intent.EXTRA_TIMEZONE, newZone.getID());
2161             mOptsTimeBroadcast.setTemporaryAppAllowlist(
2162                     mActivityManagerInternal.getBootTimeTempAllowListDuration(),
2163                     TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
2164                     PowerExemptionManager.REASON_TIMEZONE_CHANGED, "");
2165             mOptsTimeBroadcast.setDeliveryGroupPolicy(
2166                     BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT);
2167             getContext().sendBroadcastAsUser(intent, UserHandle.ALL,
2168                     null /* receiverPermission */, mOptsTimeBroadcast.toBundle());
2169         }
2170     }
2171 
removeImpl(PendingIntent operation, IAlarmListener listener)2172     void removeImpl(PendingIntent operation, IAlarmListener listener) {
2173         synchronized (mLock) {
2174             removeLocked(operation, listener, REMOVE_REASON_UNDEFINED);
2175         }
2176     }
2177 
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, Bundle idleOptions, int exactAllowReason)2178     void setImpl(int type, long triggerAtTime, long windowLength, long interval,
2179             PendingIntent operation, IAlarmListener directReceiver, String listenerTag,
2180             int flags, WorkSource workSource, AlarmManager.AlarmClockInfo alarmClock,
2181             int callingUid, String callingPackage, Bundle idleOptions, int exactAllowReason) {
2182         if ((operation == null && directReceiver == null)
2183                 || (operation != null && directReceiver != null)) {
2184             Slog.w(TAG, "Alarms must either supply a PendingIntent or an AlarmReceiver");
2185             // NB: previous releases failed silently here, so we are continuing to do the same
2186             // rather than throw an IllegalArgumentException.
2187             return;
2188         }
2189 
2190         if (directReceiver != null) {
2191             try {
2192                 directReceiver.asBinder().linkToDeath(mListenerDeathRecipient, 0);
2193             } catch (RemoteException e) {
2194                 Slog.w(TAG, "Dropping unreachable alarm listener " + listenerTag);
2195                 return;
2196             }
2197         }
2198 
2199         // Validate the recurrence interval.  This will catch people who supply
2200         // seconds when the API expects milliseconds, or apps trying shenanigans
2201         // around intentional period overflow, etc.
2202         final long minInterval = mConstants.MIN_INTERVAL;
2203         if (interval > 0 && interval < minInterval) {
2204             Slog.w(TAG, "Suspiciously short interval " + interval
2205                     + " millis; expanding to " + (minInterval / 1000)
2206                     + " seconds");
2207             interval = minInterval;
2208         } else if (interval > mConstants.MAX_INTERVAL) {
2209             Slog.w(TAG, "Suspiciously long interval " + interval
2210                     + " millis; clamping");
2211             interval = mConstants.MAX_INTERVAL;
2212         }
2213 
2214         if (type < RTC_WAKEUP || type > ELAPSED_REALTIME) {
2215             throw new IllegalArgumentException("Invalid alarm type " + type);
2216         }
2217 
2218         if (triggerAtTime < 0) {
2219             final long what = Binder.getCallingPid();
2220             Slog.w(TAG, "Invalid alarm trigger time! " + triggerAtTime + " from uid=" + callingUid
2221                     + " pid=" + what);
2222             triggerAtTime = 0;
2223         }
2224 
2225         final long nowElapsed = mInjector.getElapsedRealtimeMillis();
2226         final long nominalTrigger = convertToElapsed(triggerAtTime, type);
2227         // Try to prevent spamming by making sure apps aren't firing alarms in the immediate future
2228         final long minTrigger = nowElapsed
2229                 + (UserHandle.isCore(callingUid) ? 0L : mConstants.MIN_FUTURITY);
2230         final long triggerElapsed = Math.max(minTrigger, nominalTrigger);
2231 
2232         final long maxElapsed;
2233         if (windowLength == 0) {
2234             maxElapsed = triggerElapsed;
2235         } else if (windowLength < 0) {
2236             maxElapsed = maxTriggerTime(nowElapsed, triggerElapsed, interval);
2237             // Fix this window in place, so that as time approaches we don't collapse it.
2238             windowLength = maxElapsed - triggerElapsed;
2239         } else {
2240             // The window was explicitly requested. Snap it to allowable limits.
2241             final long minAllowedWindow = getMinimumAllowedWindow(nowElapsed, triggerElapsed);
2242             if (windowLength > INTERVAL_DAY) {
2243                 Slog.w(TAG, "Window length " + windowLength + "ms too long; limiting to 1 day");
2244                 windowLength = INTERVAL_DAY;
2245             } else if ((flags & FLAG_PRIORITIZE) == 0 && windowLength < minAllowedWindow) {
2246                 // Prioritized alarms are exempt from minimum window limits.
2247                 if (!isExemptFromMinWindowRestrictions(callingUid) && CompatChanges.isChangeEnabled(
2248                         AlarmManager.ENFORCE_MINIMUM_WINDOW_ON_INEXACT_ALARMS, callingPackage,
2249                         UserHandle.getUserHandleForUid(callingUid))) {
2250                     Slog.w(TAG, "Window length " + windowLength + "ms too short; expanding to "
2251                             + minAllowedWindow + "ms.");
2252                     windowLength = minAllowedWindow;
2253                 }
2254             }
2255             maxElapsed = triggerElapsed + windowLength;
2256         }
2257         synchronized (mLock) {
2258             if (DEBUG_BATCH) {
2259                 Slog.v(TAG, "set(" + operation + ") : type=" + type
2260                         + " triggerAtTime=" + triggerAtTime + " win=" + windowLength
2261                         + " tElapsed=" + triggerElapsed + " maxElapsed=" + maxElapsed
2262                         + " interval=" + interval + " flags=0x" + Integer.toHexString(flags));
2263             }
2264             if (mAlarmsPerUid.get(callingUid, 0) >= mConstants.MAX_ALARMS_PER_UID) {
2265                 final String errorMsg =
2266                         "Maximum limit of concurrent alarms " + mConstants.MAX_ALARMS_PER_UID
2267                                 + " reached for uid: " + UserHandle.formatUid(callingUid)
2268                                 + ", callingPackage: " + callingPackage;
2269                 Slog.w(TAG, errorMsg);
2270                 if (callingUid != Process.SYSTEM_UID) {
2271                     throw new IllegalStateException(errorMsg);
2272                 } else {
2273                     EventLog.writeEvent(0x534e4554, "234441463", -1, errorMsg);
2274                 }
2275             }
2276             setImplLocked(type, triggerAtTime, triggerElapsed, windowLength, interval, operation,
2277                     directReceiver, listenerTag, flags, workSource, alarmClock, callingUid,
2278                     callingPackage, idleOptions, exactAllowReason);
2279         }
2280     }
2281 
2282     @GuardedBy("mLock")
setImplLocked(int type, long when, long whenElapsed, long windowLength, long interval, PendingIntent operation, IAlarmListener directReceiver, String listenerTag, int flags, WorkSource workSource, AlarmManager.AlarmClockInfo alarmClock, int callingUid, String callingPackage, Bundle idleOptions, int exactAllowReason)2283     private void setImplLocked(int type, long when, long whenElapsed, long windowLength,
2284             long interval, PendingIntent operation, IAlarmListener directReceiver,
2285             String listenerTag, int flags, WorkSource workSource,
2286             AlarmManager.AlarmClockInfo alarmClock, int callingUid, String callingPackage,
2287             Bundle idleOptions, int exactAllowReason) {
2288         final Alarm a = new Alarm(type, when, whenElapsed, windowLength, interval,
2289                 operation, directReceiver, listenerTag, workSource, flags, alarmClock,
2290                 callingUid, callingPackage, idleOptions, exactAllowReason);
2291         if (mActivityManagerInternal.isAppStartModeDisabled(callingUid, callingPackage)) {
2292             Slog.w(TAG, "Not setting alarm from " + callingUid + ":" + a
2293                     + " -- package not allowed to start");
2294             return;
2295         }
2296         final int callerProcState = mActivityManagerInternal.getUidProcessState(callingUid);
2297         removeLocked(operation, directReceiver, REMOVE_REASON_UNDEFINED);
2298         incrementAlarmCount(a.uid);
2299         setImplLocked(a);
2300         MetricsHelper.pushAlarmScheduled(a, callerProcState);
2301     }
2302 
2303     /**
2304      * Returns the maximum alarms that an app in the specified bucket can receive in a rolling time
2305      * window given by {@link Constants#APP_STANDBY_WINDOW}
2306      */
2307     @VisibleForTesting
getQuotaForBucketLocked(int bucket)2308     int getQuotaForBucketLocked(int bucket) {
2309         final int index;
2310         if (bucket <= UsageStatsManager.STANDBY_BUCKET_ACTIVE) {
2311             index = ACTIVE_INDEX;
2312         } else if (bucket <= UsageStatsManager.STANDBY_BUCKET_WORKING_SET) {
2313             index = WORKING_INDEX;
2314         } else if (bucket <= UsageStatsManager.STANDBY_BUCKET_FREQUENT) {
2315             index = FREQUENT_INDEX;
2316         } else if (bucket < UsageStatsManager.STANDBY_BUCKET_NEVER) {
2317             index = RARE_INDEX;
2318         } else {
2319             index = NEVER_INDEX;
2320         }
2321         return mConstants.APP_STANDBY_QUOTAS[index];
2322     }
2323 
2324     /**
2325      * An alarm with {@link AlarmManager#FLAG_IDLE_UNTIL} is a special alarm that will put the
2326      * system into idle until it goes off. We need to pull it earlier if there are existing alarms
2327      * that have requested to bring us out of idle at an earlier time.
2328      *
2329      * @param alarm The alarm to adjust
2330      * @return true if the alarm delivery time was updated.
2331      */
adjustIdleUntilTime(Alarm alarm)2332     private boolean adjustIdleUntilTime(Alarm alarm) {
2333         if ((alarm.flags & AlarmManager.FLAG_IDLE_UNTIL) == 0) {
2334             return false;
2335         }
2336         final boolean changedBeforeFuzz = restoreRequestedTime(alarm);
2337         if (mNextWakeFromIdle == null) {
2338             // No need to change anything in the absence of a wake-from-idle request.
2339             return changedBeforeFuzz;
2340         }
2341         final long upcomingWakeFromIdle = mNextWakeFromIdle.getWhenElapsed();
2342         // Add fuzz to make the alarm go off some time before the next upcoming wake-from-idle, as
2343         // these alarms are usually wall-clock aligned.
2344         if (alarm.getWhenElapsed() < (upcomingWakeFromIdle - mConstants.MIN_DEVICE_IDLE_FUZZ)) {
2345             // No need to fuzz as this is already earlier than the coming wake-from-idle.
2346             return changedBeforeFuzz;
2347         }
2348         final long nowElapsed = mInjector.getElapsedRealtimeMillis();
2349         final long futurity = upcomingWakeFromIdle - nowElapsed;
2350 
2351         if (futurity <= mConstants.MIN_DEVICE_IDLE_FUZZ) {
2352             // No point in fuzzing as the minimum fuzz will take the time in the past.
2353             alarm.setPolicyElapsed(REQUESTER_POLICY_INDEX, nowElapsed);
2354         } else {
2355             final ThreadLocalRandom random = ThreadLocalRandom.current();
2356             final long upperBoundExcl = Math.min(mConstants.MAX_DEVICE_IDLE_FUZZ, futurity) + 1;
2357             final long fuzz = random.nextLong(mConstants.MIN_DEVICE_IDLE_FUZZ, upperBoundExcl);
2358             alarm.setPolicyElapsed(REQUESTER_POLICY_INDEX, upcomingWakeFromIdle - fuzz);
2359         }
2360         return true;
2361     }
2362 
2363     /**
2364      * Adjusts the delivery time of the alarm based on battery saver rules.
2365      *
2366      * @param alarm The alarm to adjust
2367      * @return {@code true} if the alarm delivery time was updated.
2368      */
adjustDeliveryTimeBasedOnBatterySaver(Alarm alarm)2369     private boolean adjustDeliveryTimeBasedOnBatterySaver(Alarm alarm) {
2370         final long nowElapsed = mInjector.getElapsedRealtimeMillis();
2371         if (isExemptFromBatterySaver(alarm)) {
2372             return false;
2373         }
2374 
2375         if (mAppStateTracker == null || !mAppStateTracker.areAlarmsRestrictedByBatterySaver(
2376                 alarm.creatorUid, alarm.sourcePackage)) {
2377             return alarm.setPolicyElapsed(BATTERY_SAVER_POLICY_INDEX, nowElapsed);
2378         }
2379 
2380         final long batterySaverPolicyElapsed;
2381         if ((alarm.flags & (FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED)) != 0) {
2382             // Unrestricted.
2383             batterySaverPolicyElapsed = nowElapsed;
2384         } else if (isAllowedWhileIdleRestricted(alarm)) {
2385             // Allowed but limited.
2386             final int userId = UserHandle.getUserId(alarm.creatorUid);
2387             final int quota;
2388             final long window;
2389             final AppWakeupHistory history;
2390             if ((alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0) {
2391                 quota = mConstants.ALLOW_WHILE_IDLE_QUOTA;
2392                 window = mConstants.ALLOW_WHILE_IDLE_WINDOW;
2393                 history = mAllowWhileIdleHistory;
2394             } else {
2395                 quota = mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA;
2396                 window = mConstants.ALLOW_WHILE_IDLE_COMPAT_WINDOW;
2397                 history = mAllowWhileIdleCompatHistory;
2398             }
2399             final int dispatchesInHistory = history.getTotalWakeupsInWindow(
2400                     alarm.sourcePackage, userId);
2401             if (dispatchesInHistory < quota) {
2402                 // fine to go out immediately.
2403                 batterySaverPolicyElapsed = nowElapsed;
2404             } else {
2405                 batterySaverPolicyElapsed = history.getNthLastWakeupForPackage(
2406                         alarm.sourcePackage, userId, quota) + window;
2407             }
2408         } else if ((alarm.flags & FLAG_PRIORITIZE) != 0) {
2409             final long lastDispatch = mLastPriorityAlarmDispatch.get(alarm.creatorUid, 0);
2410             batterySaverPolicyElapsed = (lastDispatch == 0)
2411                     ? nowElapsed
2412                     : lastDispatch + mConstants.PRIORITY_ALARM_DELAY;
2413         } else {
2414             // Not allowed.
2415             batterySaverPolicyElapsed = nowElapsed + INDEFINITE_DELAY;
2416         }
2417         return alarm.setPolicyElapsed(BATTERY_SAVER_POLICY_INDEX, batterySaverPolicyElapsed);
2418     }
2419 
2420     /**
2421      * Returns {@code true} if the given alarm has the flag
2422      * {@link AlarmManager#FLAG_ALLOW_WHILE_IDLE} or
2423      * {@link AlarmManager#FLAG_ALLOW_WHILE_IDLE_COMPAT}
2424      *
2425      */
isAllowedWhileIdleRestricted(Alarm a)2426     private static boolean isAllowedWhileIdleRestricted(Alarm a) {
2427         return (a.flags & (FLAG_ALLOW_WHILE_IDLE | FLAG_ALLOW_WHILE_IDLE_COMPAT)) != 0;
2428     }
2429 
2430     /**
2431      * Adjusts the delivery time of the alarm based on device_idle (doze) rules.
2432      *
2433      * @param alarm The alarm to adjust
2434      * @return {@code true} if the alarm delivery time was updated.
2435      */
adjustDeliveryTimeBasedOnDeviceIdle(Alarm alarm)2436     private boolean adjustDeliveryTimeBasedOnDeviceIdle(Alarm alarm) {
2437         final long nowElapsed = mInjector.getElapsedRealtimeMillis();
2438         if (mPendingIdleUntil == null || mPendingIdleUntil == alarm) {
2439             return alarm.setPolicyElapsed(DEVICE_IDLE_POLICY_INDEX, nowElapsed);
2440         }
2441 
2442         final long deviceIdlePolicyTime;
2443         if ((alarm.flags & (FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED | FLAG_WAKE_FROM_IDLE)) != 0) {
2444             // Unrestricted.
2445             deviceIdlePolicyTime = nowElapsed;
2446         } else if (isAllowedWhileIdleRestricted(alarm)) {
2447             // Allowed but limited.
2448             final int userId = UserHandle.getUserId(alarm.creatorUid);
2449             final int quota;
2450             final long window;
2451             final AppWakeupHistory history;
2452             if ((alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0) {
2453                 quota = mConstants.ALLOW_WHILE_IDLE_QUOTA;
2454                 window = mConstants.ALLOW_WHILE_IDLE_WINDOW;
2455                 history = mAllowWhileIdleHistory;
2456             } else {
2457                 quota = mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA;
2458                 window = mConstants.ALLOW_WHILE_IDLE_COMPAT_WINDOW;
2459                 history = mAllowWhileIdleCompatHistory;
2460             }
2461             final int dispatchesInHistory = history.getTotalWakeupsInWindow(
2462                     alarm.sourcePackage, userId);
2463             if (dispatchesInHistory < quota) {
2464                 // fine to go out immediately.
2465                 deviceIdlePolicyTime = nowElapsed;
2466             } else {
2467                 final long whenInQuota = history.getNthLastWakeupForPackage(
2468                         alarm.sourcePackage, userId, quota) + window;
2469                 deviceIdlePolicyTime = Math.min(whenInQuota, mPendingIdleUntil.getWhenElapsed());
2470             }
2471         } else if ((alarm.flags & FLAG_PRIORITIZE) != 0) {
2472             final long lastDispatch = mLastPriorityAlarmDispatch.get(alarm.creatorUid, 0);
2473             final long whenAllowed = (lastDispatch == 0)
2474                     ? nowElapsed
2475                     : lastDispatch + mConstants.PRIORITY_ALARM_DELAY;
2476             deviceIdlePolicyTime = Math.min(whenAllowed, mPendingIdleUntil.getWhenElapsed());
2477         } else {
2478             // Not allowed.
2479             deviceIdlePolicyTime = mPendingIdleUntil.getWhenElapsed();
2480         }
2481         return alarm.setPolicyElapsed(DEVICE_IDLE_POLICY_INDEX, deviceIdlePolicyTime);
2482     }
2483 
2484     /**
2485      * Adjusts the alarm's policy time for app_standby.
2486      *
2487      * @param alarm The alarm to update.
2488      * @return {@code true} if the actual delivery time of the given alarm was updated due to
2489      *         adjustments made in this call.
2490      */
adjustDeliveryTimeBasedOnBucketLocked(Alarm alarm)2491     private boolean adjustDeliveryTimeBasedOnBucketLocked(Alarm alarm) {
2492         final long nowElapsed = mInjector.getElapsedRealtimeMillis();
2493         if (isExemptFromAppStandby(alarm) || mAppStandbyParole) {
2494             return alarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, nowElapsed);
2495         }
2496 
2497         final String sourcePackage = alarm.sourcePackage;
2498         final int sourceUserId = UserHandle.getUserId(alarm.creatorUid);
2499         final int standbyBucket = mUsageStatsManagerInternal.getAppStandbyBucket(
2500                 sourcePackage, sourceUserId, nowElapsed);
2501 
2502         final int wakeupsInWindow = mAppWakeupHistory.getTotalWakeupsInWindow(sourcePackage,
2503                 sourceUserId);
2504         if (standbyBucket == UsageStatsManager.STANDBY_BUCKET_RESTRICTED) {
2505             // Special case because it's 1/day instead of 1/hour.
2506             // AppWakeupHistory doesn't delete old wakeup times until a new one is logged, so we
2507             // should always have the last wakeup available.
2508             if (wakeupsInWindow > 0) {
2509                 final long lastWakeupTime = mAppWakeupHistory.getNthLastWakeupForPackage(
2510                         sourcePackage, sourceUserId, mConstants.APP_STANDBY_RESTRICTED_QUOTA);
2511                 if ((nowElapsed - lastWakeupTime) < mConstants.APP_STANDBY_RESTRICTED_WINDOW) {
2512                     return alarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX,
2513                             lastWakeupTime + mConstants.APP_STANDBY_RESTRICTED_WINDOW);
2514                 }
2515             }
2516         } else {
2517             final int quotaForBucket = getQuotaForBucketLocked(standbyBucket);
2518             if (wakeupsInWindow >= quotaForBucket) {
2519                 final long minElapsed;
2520                 if (mTemporaryQuotaReserve.hasQuota(sourcePackage, sourceUserId, nowElapsed)) {
2521                     // We will let this alarm go out as usual, but mark it so it consumes the quota
2522                     // at the time of delivery.
2523                     alarm.mUsingReserveQuota = true;
2524                     return alarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, nowElapsed);
2525                 }
2526                 if (quotaForBucket <= 0) {
2527                     // Just keep deferring indefinitely till the quota changes.
2528                     minElapsed = nowElapsed + INDEFINITE_DELAY;
2529                 } else {
2530                     // Suppose the quota for window was q, and the qth last delivery time for this
2531                     // package was t(q) then the next delivery must be after t(q) + <window_size>.
2532                     final long t = mAppWakeupHistory.getNthLastWakeupForPackage(
2533                             sourcePackage, sourceUserId, quotaForBucket);
2534                     minElapsed = t + mConstants.APP_STANDBY_WINDOW;
2535                 }
2536                 return alarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, minElapsed);
2537             }
2538         }
2539         // wakeupsInWindow are less than the permitted quota, hence no deferring is needed.
2540         alarm.mUsingReserveQuota = false;
2541         return alarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, nowElapsed);
2542     }
2543 
2544     @GuardedBy("mLock")
setImplLocked(Alarm a)2545     private void setImplLocked(Alarm a) {
2546         if ((a.flags & AlarmManager.FLAG_IDLE_UNTIL) != 0) {
2547             adjustIdleUntilTime(a);
2548 
2549             if (RECORD_DEVICE_IDLE_ALARMS) {
2550                 IdleDispatchEntry ent = new IdleDispatchEntry();
2551                 ent.uid = a.uid;
2552                 ent.pkg = a.sourcePackage;
2553                 ent.tag = a.statsTag;
2554                 ent.op = "START IDLE";
2555                 ent.elapsedRealtime = mInjector.getElapsedRealtimeMillis();
2556                 ent.argRealtime = a.getWhenElapsed();
2557                 mAllowWhileIdleDispatches.add(ent);
2558             }
2559             if ((mPendingIdleUntil != a) && (mPendingIdleUntil != null)) {
2560                 Slog.wtfStack(TAG, "setImplLocked: idle until changed from " + mPendingIdleUntil
2561                         + " to " + a);
2562                 mAlarmStore.remove(mPendingIdleUntil::equals);
2563             }
2564             mPendingIdleUntil = a;
2565             mAlarmStore.updateAlarmDeliveries(alarm -> adjustDeliveryTimeBasedOnDeviceIdle(alarm));
2566         } else if (mPendingIdleUntil != null) {
2567             adjustDeliveryTimeBasedOnDeviceIdle(a);
2568         }
2569         if ((a.flags & FLAG_WAKE_FROM_IDLE) != 0) {
2570             if (mNextWakeFromIdle == null || mNextWakeFromIdle.getWhenElapsed()
2571                     > a.getWhenElapsed()) {
2572                 mNextWakeFromIdle = a;
2573                 // If this wake from idle is earlier than whatever was previously scheduled,
2574                 // and we are currently idling, then the idle-until time needs to be updated.
2575                 if (mPendingIdleUntil != null) {
2576                     final boolean updated = mAlarmStore.updateAlarmDeliveries(
2577                             alarm -> (alarm == mPendingIdleUntil) && adjustIdleUntilTime(alarm));
2578                     if (updated) {
2579                         // idle-until got updated, so also update all alarms not allowed while idle.
2580                         mAlarmStore.updateAlarmDeliveries(
2581                                 alarm -> adjustDeliveryTimeBasedOnDeviceIdle(alarm));
2582                     }
2583                 }
2584             }
2585         }
2586         if (a.alarmClock != null) {
2587             mNextAlarmClockMayChange = true;
2588         }
2589         adjustDeliveryTimeBasedOnBatterySaver(a);
2590         adjustDeliveryTimeBasedOnBucketLocked(a);
2591         mAlarmStore.add(a);
2592         rescheduleKernelAlarmsLocked();
2593         updateNextAlarmClockLocked();
2594     }
2595 
2596     /**
2597      * System-process internal API
2598      */
2599     private final class LocalService implements AlarmManagerInternal {
2600         @Override
isIdling()2601         public boolean isIdling() {
2602             return isIdlingImpl();
2603         }
2604 
2605         @Override
removeAlarmsForUid(int uid)2606         public void removeAlarmsForUid(int uid) {
2607             synchronized (mLock) {
2608                 removeLocked(uid, REMOVE_REASON_DATA_CLEARED);
2609             }
2610         }
2611 
2612         @Override
remove(PendingIntent pi)2613         public void remove(PendingIntent pi) {
2614             mHandler.obtainMessage(AlarmHandler.REMOVE_FOR_CANCELED, pi).sendToTarget();
2615         }
2616 
2617         @Override
shouldGetBucketElevation(String packageName, int uid)2618         public boolean shouldGetBucketElevation(String packageName, int uid) {
2619             return hasUseExactAlarmInternal(packageName, uid) || (!CompatChanges.isChangeEnabled(
2620                     AlarmManager.SCHEDULE_EXACT_ALARM_DOES_NOT_ELEVATE_BUCKET, packageName,
2621                     UserHandle.getUserHandleForUid(uid)) && hasScheduleExactAlarmInternal(
2622                     packageName, uid));
2623         }
2624 
2625         @Override
setTimeZone(String tzId, @TimeZoneConfidence int confidence, String logInfo)2626         public void setTimeZone(String tzId, @TimeZoneConfidence int confidence,
2627                 String logInfo) {
2628             setTimeZoneImpl(tzId, confidence, logInfo);
2629         }
2630 
2631         @Override
setTime( @urrentTimeMillisLong long unixEpochTimeMillis, int confidence, String logMsg)2632         public void setTime(
2633                 @CurrentTimeMillisLong long unixEpochTimeMillis, int confidence,
2634                 String logMsg) {
2635             setTimeImpl(unixEpochTimeMillis, confidence, logMsg);
2636         }
2637 
2638         @Override
registerInFlightListener(InFlightListener callback)2639         public void registerInFlightListener(InFlightListener callback) {
2640             synchronized (mLock) {
2641                 mInFlightListeners.add(callback);
2642             }
2643         }
2644     }
2645 
hasUseExactAlarmInternal(String packageName, int uid)2646     boolean hasUseExactAlarmInternal(String packageName, int uid) {
2647         return isUseExactAlarmEnabled(packageName, UserHandle.getUserId(uid))
2648                 && (checkPermissionForPreflight(getContext(), Manifest.permission.USE_EXACT_ALARM,
2649                 PID_UNKNOWN, uid, packageName) == PERMISSION_GRANTED);
2650     }
2651 
hasScheduleExactAlarmInternal(String packageName, int uid)2652     boolean hasScheduleExactAlarmInternal(String packageName, int uid) {
2653         final long start = mStatLogger.getTime();
2654 
2655         // Not using #mLastOpScheduleExactAlarm as it may contain stale values.
2656         // No locking needed as all internal containers being queried are immutable.
2657         final boolean hasPermission;
2658         if (!mExactAlarmCandidates.contains(UserHandle.getAppId(uid))) {
2659             hasPermission = false;
2660         } else if (!isExactAlarmChangeEnabled(packageName, UserHandle.getUserId(uid))) {
2661             hasPermission = false;
2662         } else if (isScheduleExactAlarmDeniedByDefault(packageName, UserHandle.getUserId(uid))) {
2663             hasPermission = (checkPermissionForPreflight(getContext(),
2664                     Manifest.permission.SCHEDULE_EXACT_ALARM, PID_UNKNOWN, uid, packageName)
2665                     == PERMISSION_GRANTED);
2666         } else {
2667             // Compatibility permission check for older apps.
2668             final int mode = mAppOps.checkOpNoThrow(AppOpsManager.OP_SCHEDULE_EXACT_ALARM, uid,
2669                     packageName);
2670             hasPermission = (mode == AppOpsManager.MODE_DEFAULT)
2671                     || (mode == AppOpsManager.MODE_ALLOWED);
2672         }
2673         mStatLogger.logDurationStat(Stats.HAS_SCHEDULE_EXACT_ALARM, start);
2674         return hasPermission;
2675     }
2676 
2677     /**
2678      * Returns true if the given uid can set window to be as small as it wants.
2679      */
isExemptFromMinWindowRestrictions(int uid)2680     boolean isExemptFromMinWindowRestrictions(int uid) {
2681         return isExemptFromExactAlarmPermissionNoLock(uid);
2682     }
2683 
2684     /**
2685      * Returns true if the given uid does not require SCHEDULE_EXACT_ALARM to set exact,
2686      * allow-while-idle alarms.
2687      * <b> Note: This should not be called with {@link #mLock} held.</b>
2688      */
isExemptFromExactAlarmPermissionNoLock(int uid)2689     boolean isExemptFromExactAlarmPermissionNoLock(int uid) {
2690         if (Build.IS_DEBUGGABLE && Thread.holdsLock(mLock)) {
2691             Slog.wtfStack(TAG, "Alarm lock held while calling into DeviceIdleController");
2692         }
2693         return (UserHandle.isSameApp(mSystemUiUid, uid)
2694                 || UserHandle.isCore(uid)
2695                 || mLocalDeviceIdleController == null
2696                 || mLocalDeviceIdleController.isAppOnWhitelist(UserHandle.getAppId(uid)));
2697     }
2698 
2699     /**
2700      * Public-facing binder interface
2701      */
2702     private final IBinder mService = new IAlarmManager.Stub() {
2703         @Override
2704         public void set(String callingPackage,
2705                 int type, long triggerAtTime, long windowLength, long interval, int flags,
2706                 PendingIntent operation, IAlarmListener directReceiver, String listenerTag,
2707                 WorkSource workSource, AlarmManager.AlarmClockInfo alarmClock) {
2708             final int callingUid = mInjector.getCallingUid();
2709             final int callingUserId = UserHandle.getUserId(callingUid);
2710 
2711             // make sure the caller is not lying about which package should be blamed for
2712             // wakelock time spent in alarm delivery
2713             if (callingUid != mPackageManagerInternal.getPackageUid(callingPackage, 0,
2714                     callingUserId)) {
2715                 throw new SecurityException("Package " + callingPackage
2716                         + " does not belong to the calling uid " + callingUid);
2717             }
2718 
2719             // Repeating alarms must use PendingIntent, not direct listener
2720             if (interval != 0 && directReceiver != null) {
2721                 throw new IllegalArgumentException("Repeating alarms cannot use AlarmReceivers");
2722             }
2723 
2724             if (workSource != null) {
2725                 getContext().enforcePermission(
2726                         android.Manifest.permission.UPDATE_DEVICE_STATS,
2727                         Binder.getCallingPid(), callingUid, "AlarmManager.set");
2728             }
2729 
2730             if ((flags & AlarmManager.FLAG_IDLE_UNTIL) != 0) {
2731                 // Only the system can use FLAG_IDLE_UNTIL -- this is used to tell the alarm
2732                 // manager when to come out of idle mode, which is only for DeviceIdleController.
2733                 if (callingUid != Process.SYSTEM_UID) {
2734                     // TODO (b/169463012): Throw instead of tolerating this mistake.
2735                     flags &= ~AlarmManager.FLAG_IDLE_UNTIL;
2736                 } else {
2737                     // Do not support windows for idle-until alarms.
2738                     windowLength = 0;
2739                 }
2740             }
2741 
2742             // Remove flags reserved for the service, we will apply those later as appropriate.
2743             flags &= ~(FLAG_WAKE_FROM_IDLE | FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED
2744                     | FLAG_ALLOW_WHILE_IDLE_COMPAT);
2745 
2746             // If this alarm is for an alarm clock, then it must be exact and we will
2747             // use it to wake early from idle if needed.
2748             if (alarmClock != null) {
2749                 flags |= FLAG_WAKE_FROM_IDLE;
2750                 windowLength = 0;
2751 
2752             // If the caller is a core system component or on the user's allowlist, and not calling
2753             // to do work on behalf of someone else, then always set ALLOW_WHILE_IDLE_UNRESTRICTED.
2754             // This means we will allow these alarms to go off as normal even while idle, with no
2755             // timing restrictions.
2756             } else if (workSource == null && (UserHandle.isCore(callingUid)
2757                     || UserHandle.isSameApp(callingUid, mSystemUiUid)
2758                     || ((mAppStateTracker != null)
2759                     && mAppStateTracker.isUidPowerSaveUserExempt(callingUid)))) {
2760                 flags |= FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
2761                 flags &= ~(FLAG_ALLOW_WHILE_IDLE | FLAG_PRIORITIZE);
2762             }
2763 
2764             final boolean allowWhileIdle = (flags & FLAG_ALLOW_WHILE_IDLE) != 0;
2765             final boolean exact = (windowLength == 0);
2766 
2767             // Make sure the caller is allowed to use the requested kind of alarm, and also
2768             // decide what quota and broadcast options to use.
2769             int exactAllowReason = EXACT_ALLOW_REASON_NOT_APPLICABLE;
2770             Bundle idleOptions = null;
2771             if ((flags & FLAG_PRIORITIZE) != 0) {
2772                 getContext().enforcePermission(
2773                         Manifest.permission.SCHEDULE_PRIORITIZED_ALARM,
2774                         Binder.getCallingPid(), callingUid, "AlarmManager.setPrioritized");
2775                 // The API doesn't allow using both together.
2776                 flags &= ~FLAG_ALLOW_WHILE_IDLE;
2777                 // Prioritized alarms don't need any extra permission to be exact.
2778                 if (exact) {
2779                     exactAllowReason = EXACT_ALLOW_REASON_PRIORITIZED;
2780                 }
2781             } else if (exact || allowWhileIdle) {
2782                 final boolean needsPermission;
2783                 boolean lowerQuota;
2784                 if (isExactAlarmChangeEnabled(callingPackage, callingUserId)) {
2785                     if (directReceiver == null) {
2786                         needsPermission = exact;
2787                         lowerQuota = !exact;
2788                     } else {
2789                         needsPermission = false;
2790                         lowerQuota = allowWhileIdle;
2791                         if (exact) {
2792                             exactAllowReason = EXACT_ALLOW_REASON_LISTENER;
2793                         }
2794                     }
2795                     if (exact) {
2796                         idleOptions = (alarmClock != null) ? mOptsWithFgsForAlarmClock.toBundle()
2797                                 : mOptsWithFgs.toBundle();
2798                     } else {
2799                         idleOptions = mOptsWithoutFgs.toBundle();
2800                     }
2801                 } else {
2802                     needsPermission = false;
2803                     lowerQuota = allowWhileIdle;
2804                     idleOptions = (allowWhileIdle || (alarmClock != null))
2805                             // This avoids exceptions on existing alarms when the app upgrades to
2806                             // target S. Note that FGS from pre-S apps isn't restricted anyway.
2807                             ? mOptsWithFgs.toBundle()
2808                             : null;
2809                     if (exact) {
2810                         exactAllowReason = EXACT_ALLOW_REASON_COMPAT;
2811                     }
2812                 }
2813                 if (needsPermission) {
2814                     if (hasUseExactAlarmInternal(callingPackage, callingUid)) {
2815                         exactAllowReason = EXACT_ALLOW_REASON_POLICY_PERMISSION;
2816                     } else if (hasScheduleExactAlarmInternal(callingPackage, callingUid)) {
2817                         exactAllowReason = EXACT_ALLOW_REASON_PERMISSION;
2818                     } else {
2819                         if (isExemptFromExactAlarmPermissionNoLock(callingUid)) {
2820                             exactAllowReason = EXACT_ALLOW_REASON_ALLOW_LIST;
2821                         } else {
2822                             final String errorMessage =
2823                                     "Caller " + callingPackage + " needs to hold "
2824                                             + Manifest.permission.SCHEDULE_EXACT_ALARM + " or "
2825                                             + Manifest.permission.USE_EXACT_ALARM + " to set "
2826                                             + "exact alarms.";
2827                             throw new SecurityException(errorMessage);
2828                         }
2829                         // If the app is on the full system power allow-list (not except-idle),
2830                         // or the user-elected allow-list, we allow exact alarms.
2831                         // ALLOW_WHILE_IDLE alarms get a lower quota equivalent to what pre-S apps
2832                         // got. Note that user-allow-listed apps don't use FLAG_ALLOW_WHILE_IDLE.
2833                         // We grant temporary allow-list to allow-while-idle alarms but without FGS
2834                         // capability. AlarmClock alarms do not get the temporary allow-list.
2835                         // This is consistent with pre-S behavior. Note that apps that are in
2836                         // either of the power-save allow-lists do not need it.
2837                         idleOptions = allowWhileIdle ? mOptsWithoutFgs.toBundle() : null;
2838                         lowerQuota = allowWhileIdle;
2839                     }
2840                 }
2841                 if (lowerQuota) {
2842                     flags &= ~FLAG_ALLOW_WHILE_IDLE;
2843                     flags |= FLAG_ALLOW_WHILE_IDLE_COMPAT;
2844                 }
2845             }
2846             if (exact) {
2847                 // If this is an exact time alarm, then it can't be batched with other alarms.
2848                 flags |= AlarmManager.FLAG_STANDALONE;
2849 
2850             }
2851 
2852             setImpl(type, triggerAtTime, windowLength, interval, operation, directReceiver,
2853                     listenerTag, flags, workSource, alarmClock, callingUid, callingPackage,
2854                     idleOptions, exactAllowReason);
2855         }
2856 
2857         @Override
2858         public boolean canScheduleExactAlarms(String packageName) {
2859             final int callingUid = mInjector.getCallingUid();
2860             final int userId = UserHandle.getUserId(callingUid);
2861             final int packageUid = mPackageManagerInternal.getPackageUid(packageName, 0, userId);
2862             if (callingUid != packageUid) {
2863                 throw new SecurityException("Uid " + callingUid
2864                         + " cannot query canScheduleExactAlarms for package " + packageName);
2865             }
2866             if (!isExactAlarmChangeEnabled(packageName, userId)) {
2867                 return true;
2868             }
2869             return isExemptFromExactAlarmPermissionNoLock(packageUid)
2870                     || hasScheduleExactAlarmInternal(packageName, packageUid)
2871                     || hasUseExactAlarmInternal(packageName, packageUid);
2872         }
2873 
2874         @Override
2875         public boolean hasScheduleExactAlarm(String packageName, int userId) {
2876             final int callingUid = mInjector.getCallingUid();
2877             if (UserHandle.getUserId(callingUid) != userId) {
2878                 getContext().enforceCallingOrSelfPermission(
2879                         Manifest.permission.INTERACT_ACROSS_USERS_FULL, "hasScheduleExactAlarm");
2880             }
2881             final int uid = mPackageManagerInternal.getPackageUid(packageName, 0, userId);
2882             if (callingUid != uid && !UserHandle.isCore(callingUid)) {
2883                 throw new SecurityException("Uid " + callingUid
2884                         + " cannot query hasScheduleExactAlarm for package " + packageName);
2885             }
2886             return (uid > 0) ? hasScheduleExactAlarmInternal(packageName, uid) : false;
2887         }
2888 
2889         @EnforcePermission(android.Manifest.permission.SET_TIME)
2890         @Override
2891         public boolean setTime(@CurrentTimeMillisLong long millis) {
2892             setTime_enforcePermission();
2893 
2894             // The public API (and the shell command that also uses this method) have no concept
2895             // of confidence, but since the time should come either from apps working on behalf of
2896             // the user or a developer, confidence is assumed "high".
2897             final int timeConfidence = TIME_CONFIDENCE_HIGH;
2898             return setTimeImpl(millis, timeConfidence, "AlarmManager.setTime() called");
2899         }
2900 
2901         @EnforcePermission(android.Manifest.permission.SET_TIME_ZONE)
2902         @Override
2903         public void setTimeZone(String tz) {
2904             setTimeZone_enforcePermission();
2905 
2906             final long oldId = Binder.clearCallingIdentity();
2907             try {
2908                 // The public API (and the shell command that also uses this method) have no concept
2909                 // of confidence, but since the time zone ID should come either from apps working on
2910                 // behalf of the user or a developer, confidence is assumed "high".
2911                 final int timeZoneConfidence = TIME_ZONE_CONFIDENCE_HIGH;
2912                 setTimeZoneImpl(tz, timeZoneConfidence, "AlarmManager.setTimeZone() called");
2913             } finally {
2914                 Binder.restoreCallingIdentity(oldId);
2915             }
2916         }
2917 
2918         @Override
2919         public void remove(PendingIntent operation, IAlarmListener listener) {
2920             if (operation == null && listener == null) {
2921                 Slog.w(TAG, "remove() with no intent or listener");
2922                 return;
2923             }
2924             synchronized (mLock) {
2925                 removeLocked(operation, listener, REMOVE_REASON_ALARM_CANCELLED);
2926             }
2927         }
2928 
2929         @Override
2930         public void removeAll(String callingPackage) {
2931             final int callingUid = mInjector.getCallingUid();
2932             if (callingUid == Process.SYSTEM_UID) {
2933                 Slog.wtfStack(TAG, "Attempt to remove all alarms from the system uid package: "
2934                         + callingPackage);
2935                 return;
2936             }
2937             if (callingUid != mPackageManagerInternal.getPackageUid(callingPackage, 0,
2938                     UserHandle.getUserId(callingUid))) {
2939                 throw new SecurityException("Package " + callingPackage
2940                         + " does not belong to the calling uid " + callingUid);
2941             }
2942             synchronized (mLock) {
2943                 removeAlarmsInternalLocked(
2944                         a -> (a.matches(callingPackage) && a.creatorUid == callingUid),
2945                         REMOVE_REASON_ALARM_CANCELLED);
2946             }
2947         }
2948 
2949         @Override
2950         public long getNextWakeFromIdleTime() {
2951             return getNextWakeFromIdleTimeImpl();
2952         }
2953 
2954         @Override
2955         public AlarmManager.AlarmClockInfo getNextAlarmClock(int userId) {
2956             userId = mActivityManagerInternal.handleIncomingUser(Binder.getCallingPid(),
2957                     Binder.getCallingUid(), userId, /*allowAll=*/false, ALLOW_NON_FULL,
2958                     "getNextAlarmClock", null);
2959             return getNextAlarmClockImpl(userId);
2960         }
2961 
2962         @EnforcePermission(android.Manifest.permission.DUMP)
2963         @Override
2964         public int getConfigVersion() {
2965             getConfigVersion_enforcePermission();
2966             return mConstants.getVersion();
2967         }
2968 
2969         @Override
2970         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2971             if (!DumpUtils.checkDumpAndUsageStatsPermission(getContext(), TAG, pw)) return;
2972 
2973             if (args.length > 0 && "--proto".equals(args[0])) {
2974                 dumpProto(fd);
2975             } else {
2976                 dumpImpl(new IndentingPrintWriter(pw, "  "));
2977             }
2978         }
2979 
2980         @Override
2981         public void onShellCommand(FileDescriptor in, FileDescriptor out,
2982                 FileDescriptor err, String[] args, ShellCallback callback,
2983                 ResultReceiver resultReceiver) {
2984             (new ShellCmd()).exec(this, in, out, err, args, callback, resultReceiver);
2985         }
2986     };
2987 
isExactAlarmChangeEnabled(String packageName, int userId)2988     private static boolean isExactAlarmChangeEnabled(String packageName, int userId) {
2989         return CompatChanges.isChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION,
2990                 packageName, UserHandle.of(userId));
2991     }
2992 
isUseExactAlarmEnabled(String packageName, int userId)2993     private static boolean isUseExactAlarmEnabled(String packageName, int userId) {
2994         return CompatChanges.isChangeEnabled(AlarmManager.ENABLE_USE_EXACT_ALARM,
2995                 packageName, UserHandle.of(userId));
2996     }
2997 
isScheduleExactAlarmDeniedByDefault(String packageName, int userId)2998     private boolean isScheduleExactAlarmDeniedByDefault(String packageName, int userId) {
2999         return CompatChanges.isChangeEnabled(AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT,
3000                 packageName, UserHandle.of(userId));
3001     }
3002 
3003     @NeverCompile // Avoid size overhead of debugging code.
dumpImpl(IndentingPrintWriter pw)3004     void dumpImpl(IndentingPrintWriter pw) {
3005         synchronized (mLock) {
3006             pw.println("Current Alarm Manager state:");
3007             pw.increaseIndent();
3008 
3009             mConstants.dump(pw);
3010             pw.println();
3011 
3012             pw.println("Feature Flags:");
3013             pw.increaseIndent();
3014             pw.print(Flags.FLAG_USE_FROZEN_STATE_TO_DROP_LISTENER_ALARMS,
3015                     mUseFrozenStateToDropListenerAlarms);
3016             pw.println();
3017             pw.print(Flags.FLAG_START_USER_BEFORE_SCHEDULED_ALARMS,
3018                     mStartUserBeforeScheduledAlarms);
3019             pw.decreaseIndent();
3020             pw.println();
3021             pw.println();
3022 
3023             pw.println("App Standby Parole: " + mAppStandbyParole);
3024             pw.println();
3025 
3026             if (mAppStateTracker != null) {
3027                 mAppStateTracker.dump(pw);
3028                 pw.println();
3029             }
3030 
3031             final long nowELAPSED = mInjector.getElapsedRealtimeMillis();
3032             final long nowUPTIME = SystemClock.uptimeMillis();
3033             final long nowRTC = mInjector.getCurrentTimeMillis();
3034             SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
3035 
3036             pw.print("nowRTC=");
3037             pw.print(nowRTC);
3038             pw.print("=");
3039             pw.print(sdf.format(new Date(nowRTC)));
3040             pw.print(" nowELAPSED=");
3041             pw.print(nowELAPSED);
3042             pw.println();
3043 
3044             pw.print("mLastTimeChangeClockTime=");
3045             pw.print(mLastTimeChangeClockTime);
3046             pw.print("=");
3047             pw.println(sdf.format(new Date(mLastTimeChangeClockTime)));
3048 
3049             pw.print("mLastTimeChangeRealtime=");
3050             pw.println(mLastTimeChangeRealtime);
3051 
3052             pw.print("mLastTickReceived=");
3053             pw.println(sdf.format(new Date(mLastTickReceived)));
3054 
3055             pw.print("mLastTickSet=");
3056             pw.println(sdf.format(new Date(mLastTickSet)));
3057 
3058             if (RECORD_ALARMS_IN_HISTORY) {
3059                 pw.println();
3060                 pw.println("Recent TIME_TICK history:");
3061                 pw.increaseIndent();
3062                 int i = mNextTickHistory;
3063                 do {
3064                     i--;
3065                     if (i < 0) i = TICK_HISTORY_DEPTH - 1;
3066                     final long time = mTickHistory[i];
3067                     pw.println((time > 0)
3068                             ? sdf.format(new Date(nowRTC - (nowELAPSED - time)))
3069                             : "-");
3070                 } while (i != mNextTickHistory);
3071                 pw.decreaseIndent();
3072             }
3073 
3074             SystemServiceManager ssm = LocalServices.getService(SystemServiceManager.class);
3075             if (ssm != null) {
3076                 pw.println();
3077                 pw.print("RuntimeStarted=");
3078                 pw.print(sdf.format(
3079                         new Date(nowRTC - nowELAPSED + ssm.getRuntimeStartElapsedTime())));
3080                 if (ssm.isRuntimeRestarted()) {
3081                     pw.print("  (Runtime restarted)");
3082                 }
3083                 pw.println();
3084 
3085                 pw.print("Runtime uptime (elapsed): ");
3086                 TimeUtils.formatDuration(nowELAPSED, ssm.getRuntimeStartElapsedTime(), pw);
3087                 pw.println();
3088 
3089                 pw.print("Runtime uptime (uptime): ");
3090                 TimeUtils.formatDuration(nowUPTIME, ssm.getRuntimeStartUptime(), pw);
3091                 pw.println();
3092             }
3093 
3094             pw.println();
3095             if (!mInteractive) {
3096                 pw.print("Time since non-interactive: ");
3097                 TimeUtils.formatDuration(nowELAPSED - mNonInteractiveStartTime, pw);
3098                 pw.println();
3099             }
3100             pw.print("Max wakeup delay: ");
3101             TimeUtils.formatDuration(currentNonWakeupFuzzLocked(nowELAPSED), pw);
3102             pw.println();
3103 
3104             pw.print("Time since last dispatch: ");
3105             TimeUtils.formatDuration(nowELAPSED - mLastAlarmDeliveryTime, pw);
3106             pw.println();
3107 
3108             pw.print("Next non-wakeup delivery time: ");
3109             TimeUtils.formatDuration(mNextNonWakeupDeliveryTime, nowELAPSED, pw);
3110             pw.println();
3111 
3112             long nextWakeupRTC = mNextWakeup + (nowRTC - nowELAPSED);
3113             long nextNonWakeupRTC = mNextNonWakeup + (nowRTC - nowELAPSED);
3114             pw.print("Next non-wakeup alarm: ");
3115             TimeUtils.formatDuration(mNextNonWakeup, nowELAPSED, pw);
3116             pw.print(" = ");
3117             pw.print(mNextNonWakeup);
3118             pw.print(" = ");
3119             pw.println(sdf.format(new Date(nextNonWakeupRTC)));
3120 
3121             pw.increaseIndent();
3122             pw.print("set at ");
3123             TimeUtils.formatDuration(mNextNonWakeUpSetAt, nowELAPSED, pw);
3124             pw.decreaseIndent();
3125             pw.println();
3126 
3127             pw.print("Next wakeup alarm: ");
3128             TimeUtils.formatDuration(mNextWakeup, nowELAPSED, pw);
3129             pw.print(" = ");
3130             pw.print(mNextWakeup);
3131             pw.print(" = ");
3132             pw.println(sdf.format(new Date(nextWakeupRTC)));
3133 
3134             pw.increaseIndent();
3135             pw.print("set at ");
3136             TimeUtils.formatDuration(mNextWakeUpSetAt, nowELAPSED, pw);
3137             pw.decreaseIndent();
3138             pw.println();
3139 
3140             pw.print("Next kernel non-wakeup alarm: ");
3141             TimeUtils.formatDuration(mInjector.getNextAlarm(ELAPSED_REALTIME), pw);
3142             pw.println();
3143             pw.print("Next kernel wakeup alarm: ");
3144             TimeUtils.formatDuration(mInjector.getNextAlarm(ELAPSED_REALTIME_WAKEUP), pw);
3145             pw.println();
3146 
3147             pw.print("Last wakeup: ");
3148             TimeUtils.formatDuration(mLastWakeup, nowELAPSED, pw);
3149             pw.print(" = ");
3150             pw.println(mLastWakeup);
3151 
3152             pw.print("Last trigger: ");
3153             TimeUtils.formatDuration(mLastTrigger, nowELAPSED, pw);
3154             pw.print(" = ");
3155             pw.println(mLastTrigger);
3156 
3157             pw.print("Num time change events: ");
3158             pw.println(mNumTimeChanged);
3159 
3160             pw.println();
3161             pw.println("App ids requesting SCHEDULE_EXACT_ALARM: " + mExactAlarmCandidates);
3162 
3163             pw.println();
3164             pw.print("Last OP_SCHEDULE_EXACT_ALARM: [");
3165             for (int i = 0; i < mLastOpScheduleExactAlarm.size(); i++) {
3166                 if (i > 0) {
3167                     pw.print(", ");
3168                 }
3169                 UserHandle.formatUid(pw, mLastOpScheduleExactAlarm.keyAt(i));
3170                 pw.print(":" + AppOpsManager.modeToName(mLastOpScheduleExactAlarm.valueAt(i)));
3171             }
3172             pw.println("]");
3173 
3174             pw.println();
3175             pw.println("Next alarm clock information: ");
3176             pw.increaseIndent();
3177             final TreeSet<Integer> users = new TreeSet<>();
3178             for (int i = 0; i < mNextAlarmClockForUser.size(); i++) {
3179                 users.add(mNextAlarmClockForUser.keyAt(i));
3180             }
3181             for (int i = 0; i < mPendingSendNextAlarmClockChangedForUser.size(); i++) {
3182                 users.add(mPendingSendNextAlarmClockChangedForUser.keyAt(i));
3183             }
3184             for (int user : users) {
3185                 final AlarmManager.AlarmClockInfo next = mNextAlarmClockForUser.get(user);
3186                 final long time = next != null ? next.getTriggerTime() : 0;
3187                 final boolean pendingSend = mPendingSendNextAlarmClockChangedForUser.get(user);
3188                 pw.print("user:");
3189                 pw.print(user);
3190                 pw.print(" pendingSend:");
3191                 pw.print(pendingSend);
3192                 pw.print(" time:");
3193                 pw.print(time);
3194                 if (time > 0) {
3195                     pw.print(" = ");
3196                     pw.print(sdf.format(new Date(time)));
3197                     pw.print(" = ");
3198                     TimeUtils.formatDuration(time, nowRTC, pw);
3199                 }
3200                 pw.println();
3201             }
3202             pw.decreaseIndent();
3203 
3204             if (mAlarmStore.size() > 0) {
3205                 pw.println();
3206                 mAlarmStore.dump(pw, nowELAPSED, sdf);
3207             }
3208             pw.println();
3209 
3210             pw.println("Pending user blocked background alarms: ");
3211             pw.increaseIndent();
3212             boolean blocked = false;
3213             for (int i = 0; i < mPendingBackgroundAlarms.size(); i++) {
3214                 final ArrayList<Alarm> blockedAlarms = mPendingBackgroundAlarms.valueAt(i);
3215                 if (blockedAlarms != null && blockedAlarms.size() > 0) {
3216                     blocked = true;
3217                     dumpAlarmList(pw, blockedAlarms, nowELAPSED, sdf);
3218                 }
3219             }
3220             if (!blocked) {
3221                 pw.println("none");
3222             }
3223             pw.decreaseIndent();
3224             pw.println();
3225 
3226             pw.print("Pending alarms per uid: [");
3227             for (int i = 0; i < mAlarmsPerUid.size(); i++) {
3228                 if (i > 0) {
3229                     pw.print(", ");
3230                 }
3231                 UserHandle.formatUid(pw, mAlarmsPerUid.keyAt(i));
3232                 pw.print(":");
3233                 pw.print(mAlarmsPerUid.valueAt(i));
3234             }
3235             pw.println("]");
3236             pw.println();
3237 
3238             if (mStartUserBeforeScheduledAlarms) {
3239                 pw.println("Scheduled user wakeups:");
3240                 mUserWakeupStore.dump(pw, nowELAPSED);
3241                 pw.println();
3242             }
3243 
3244             pw.println("App Alarm history:");
3245             mAppWakeupHistory.dump(pw, nowELAPSED);
3246 
3247             pw.println();
3248             pw.println("Temporary Quota Reserves:");
3249             mTemporaryQuotaReserve.dump(pw, nowELAPSED);
3250 
3251             if (mPendingIdleUntil != null) {
3252                 pw.println();
3253                 pw.println("Idle mode state:");
3254 
3255                 pw.increaseIndent();
3256                 pw.print("Idling until: ");
3257                 if (mPendingIdleUntil != null) {
3258                     pw.println(mPendingIdleUntil);
3259                     mPendingIdleUntil.dump(pw, nowELAPSED, sdf);
3260                 } else {
3261                     pw.println("null");
3262                 }
3263                 pw.decreaseIndent();
3264             }
3265             if (mNextWakeFromIdle != null) {
3266                 pw.println();
3267                 pw.print("Next wake from idle: ");
3268                 pw.println(mNextWakeFromIdle);
3269 
3270                 pw.increaseIndent();
3271                 mNextWakeFromIdle.dump(pw, nowELAPSED, sdf);
3272                 pw.decreaseIndent();
3273             }
3274 
3275             pw.println();
3276             pw.print("Past-due non-wakeup alarms: ");
3277             if (mPendingNonWakeupAlarms.size() > 0) {
3278                 pw.println(mPendingNonWakeupAlarms.size());
3279 
3280                 pw.increaseIndent();
3281                 dumpAlarmList(pw, mPendingNonWakeupAlarms, nowELAPSED, sdf);
3282                 pw.decreaseIndent();
3283             } else {
3284                 pw.println("(none)");
3285             }
3286             pw.increaseIndent();
3287             pw.print("Number of delayed alarms: ");
3288             pw.print(mNumDelayedAlarms);
3289             pw.print(", total delay time: ");
3290             TimeUtils.formatDuration(mTotalDelayTime, pw);
3291             pw.println();
3292 
3293             pw.print("Max delay time: ");
3294             TimeUtils.formatDuration(mMaxDelayTime, pw);
3295             pw.print(", max non-interactive time: ");
3296             TimeUtils.formatDuration(mNonInteractiveTime, pw);
3297             pw.println();
3298             pw.decreaseIndent();
3299 
3300             pw.println();
3301             pw.print("Broadcast ref count: ");
3302             pw.println(mBroadcastRefCount);
3303             pw.print("PendingIntent send count: ");
3304             pw.println(mSendCount);
3305             pw.print("PendingIntent finish count: ");
3306             pw.println(mSendFinishCount);
3307             pw.print("Listener send count: ");
3308             pw.println(mListenerCount);
3309             pw.print("Listener finish count: ");
3310             pw.println(mListenerFinishCount);
3311             pw.println();
3312 
3313             if (mInFlight.size() > 0) {
3314                 pw.println("Outstanding deliveries:");
3315                 pw.increaseIndent();
3316                 for (int i = 0; i < mInFlight.size(); i++) {
3317                     pw.print("#");
3318                     pw.print(i);
3319                     pw.print(": ");
3320                     pw.println(mInFlight.get(i));
3321                 }
3322                 pw.decreaseIndent();
3323                 pw.println();
3324             }
3325 
3326             pw.println("Allow while idle history:");
3327             mAllowWhileIdleHistory.dump(pw, nowELAPSED);
3328             pw.println();
3329 
3330             pw.println("Allow while idle compat history:");
3331             mAllowWhileIdleCompatHistory.dump(pw, nowELAPSED);
3332             pw.println();
3333 
3334             if (mLastPriorityAlarmDispatch.size() > 0) {
3335                 pw.println("Last priority alarm dispatches:");
3336                 pw.increaseIndent();
3337                 for (int i = 0; i < mLastPriorityAlarmDispatch.size(); i++) {
3338                     pw.print("UID: ");
3339                     UserHandle.formatUid(pw, mLastPriorityAlarmDispatch.keyAt(i));
3340                     pw.print(": ");
3341                     TimeUtils.formatDuration(mLastPriorityAlarmDispatch.valueAt(i), nowELAPSED, pw);
3342                     pw.println();
3343                 }
3344                 pw.decreaseIndent();
3345             }
3346 
3347             if (mRemovalHistory.size() > 0) {
3348                 pw.println("Removal history:");
3349                 pw.increaseIndent();
3350                 for (int i = 0; i < mRemovalHistory.size(); i++) {
3351                     UserHandle.formatUid(pw, mRemovalHistory.keyAt(i));
3352                     pw.println(":");
3353                     pw.increaseIndent();
3354                     final RemovedAlarm[] historyForUid = mRemovalHistory.valueAt(i).toArray();
3355                     for (int index = historyForUid.length - 1; index >= 0; index--) {
3356                         pw.print("#" + (historyForUid.length - index) + ": ");
3357                         historyForUid[index].dump(pw, nowELAPSED, sdf);
3358                     }
3359                     pw.decreaseIndent();
3360                 }
3361                 pw.decreaseIndent();
3362                 pw.println();
3363             }
3364 
3365             if (mLog.dump(pw, "Recent problems:")) {
3366                 pw.println();
3367             }
3368 
3369             final FilterStats[] topFilters = new FilterStats[10];
3370             final Comparator<FilterStats> comparator = new Comparator<FilterStats>() {
3371                 @Override
3372                 public int compare(FilterStats lhs, FilterStats rhs) {
3373                     if (lhs.aggregateTime < rhs.aggregateTime) {
3374                         return 1;
3375                     } else if (lhs.aggregateTime > rhs.aggregateTime) {
3376                         return -1;
3377                     }
3378                     return 0;
3379                 }
3380             };
3381             int len = 0;
3382             // Get the top 10 FilterStats, ordered by aggregateTime.
3383             for (int iu = 0; iu < mBroadcastStats.size(); iu++) {
3384                 ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(iu);
3385                 for (int ip = 0; ip < uidStats.size(); ip++) {
3386                     BroadcastStats bs = uidStats.valueAt(ip);
3387                     for (int is = 0; is < bs.filterStats.size(); is++) {
3388                         FilterStats fs = bs.filterStats.valueAt(is);
3389                         int pos = len > 0
3390                                 ? Arrays.binarySearch(topFilters, 0, len, fs, comparator) : 0;
3391                         if (pos < 0) {
3392                             pos = -pos - 1;
3393                         }
3394                         if (pos < topFilters.length) {
3395                             int copylen = topFilters.length - pos - 1;
3396                             if (copylen > 0) {
3397                                 System.arraycopy(topFilters, pos, topFilters, pos + 1, copylen);
3398                             }
3399                             topFilters[pos] = fs;
3400                             if (len < topFilters.length) {
3401                                 len++;
3402                             }
3403                         }
3404                     }
3405                 }
3406             }
3407             if (len > 0) {
3408                 pw.println("Top Alarms:");
3409                 pw.increaseIndent();
3410                 for (int i = 0; i < len; i++) {
3411                     FilterStats fs = topFilters[i];
3412                     if (fs.nesting > 0) pw.print("*ACTIVE* ");
3413                     TimeUtils.formatDuration(fs.aggregateTime, pw);
3414                     pw.print(" running, ");
3415                     pw.print(fs.numWakeup);
3416                     pw.print(" wakeups, ");
3417                     pw.print(fs.count);
3418                     pw.print(" alarms: ");
3419                     UserHandle.formatUid(pw, fs.mBroadcastStats.mUid);
3420                     pw.print(":");
3421                     pw.print(fs.mBroadcastStats.mPackageName);
3422                     pw.println();
3423 
3424                     pw.increaseIndent();
3425                     pw.print(fs.mTag);
3426                     pw.println();
3427                     pw.decreaseIndent();
3428                 }
3429                 pw.decreaseIndent();
3430             }
3431 
3432             pw.println();
3433             pw.println("Alarm Stats:");
3434             final ArrayList<FilterStats> tmpFilters = new ArrayList<FilterStats>();
3435             for (int iu = 0; iu < mBroadcastStats.size(); iu++) {
3436                 ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(iu);
3437                 for (int ip = 0; ip < uidStats.size(); ip++) {
3438                     BroadcastStats bs = uidStats.valueAt(ip);
3439                     if (bs.nesting > 0) pw.print("*ACTIVE* ");
3440                     UserHandle.formatUid(pw, bs.mUid);
3441                     pw.print(":");
3442                     pw.print(bs.mPackageName);
3443                     pw.print(" ");
3444                     TimeUtils.formatDuration(bs.aggregateTime, pw);
3445                     pw.print(" running, ");
3446                     pw.print(bs.numWakeup);
3447                     pw.println(" wakeups:");
3448 
3449                     tmpFilters.clear();
3450                     for (int is = 0; is < bs.filterStats.size(); is++) {
3451                         tmpFilters.add(bs.filterStats.valueAt(is));
3452                     }
3453                     Collections.sort(tmpFilters, comparator);
3454                     pw.increaseIndent();
3455                     for (int i = 0; i < tmpFilters.size(); i++) {
3456                         FilterStats fs = tmpFilters.get(i);
3457                         if (fs.nesting > 0) pw.print("*ACTIVE* ");
3458                         TimeUtils.formatDuration(fs.aggregateTime, pw);
3459                         pw.print(" ");
3460                         pw.print(fs.numWakeup);
3461                         pw.print(" wakes ");
3462                         pw.print(fs.count);
3463                         pw.print(" alarms, last ");
3464                         TimeUtils.formatDuration(fs.lastTime, nowELAPSED, pw);
3465                         pw.println(":");
3466 
3467                         pw.increaseIndent();
3468                         pw.print(fs.mTag);
3469                         pw.println();
3470                         pw.decreaseIndent();
3471                     }
3472                     pw.decreaseIndent();
3473                 }
3474             }
3475             pw.println();
3476             mStatLogger.dump(pw);
3477 
3478             if (RECORD_DEVICE_IDLE_ALARMS) {
3479                 pw.println();
3480                 pw.println("Allow while idle dispatches:");
3481                 pw.increaseIndent();
3482                 for (int i = 0; i < mAllowWhileIdleDispatches.size(); i++) {
3483                     IdleDispatchEntry ent = mAllowWhileIdleDispatches.get(i);
3484                     TimeUtils.formatDuration(ent.elapsedRealtime, nowELAPSED, pw);
3485                     pw.print(": ");
3486                     UserHandle.formatUid(pw, ent.uid);
3487                     pw.print(":");
3488                     pw.println(ent.pkg);
3489 
3490                     pw.increaseIndent();
3491                     if (ent.op != null) {
3492                         pw.print(ent.op);
3493                         pw.print(" / ");
3494                         pw.print(ent.tag);
3495                         if (ent.argRealtime != 0) {
3496                             pw.print(" (");
3497                             TimeUtils.formatDuration(ent.argRealtime, nowELAPSED, pw);
3498                             pw.print(")");
3499                         }
3500                         pw.println();
3501                     }
3502                     pw.decreaseIndent();
3503                 }
3504                 pw.decreaseIndent();
3505             }
3506         }
3507     }
3508 
dumpProto(FileDescriptor fd)3509     void dumpProto(FileDescriptor fd) {
3510         final ProtoOutputStream proto = new ProtoOutputStream(fd);
3511 
3512         synchronized (mLock) {
3513             final long nowRTC = mInjector.getCurrentTimeMillis();
3514             final long nowElapsed = mInjector.getElapsedRealtimeMillis();
3515             proto.write(AlarmManagerServiceDumpProto.CURRENT_TIME, nowRTC);
3516             proto.write(AlarmManagerServiceDumpProto.ELAPSED_REALTIME, nowElapsed);
3517             proto.write(AlarmManagerServiceDumpProto.LAST_TIME_CHANGE_CLOCK_TIME,
3518                     mLastTimeChangeClockTime);
3519             proto.write(AlarmManagerServiceDumpProto.LAST_TIME_CHANGE_REALTIME,
3520                     mLastTimeChangeRealtime);
3521 
3522             mConstants.dumpProto(proto, AlarmManagerServiceDumpProto.SETTINGS);
3523 
3524             if (mAppStateTracker != null) {
3525                 mAppStateTracker.dumpProto(proto, AlarmManagerServiceDumpProto.APP_STATE_TRACKER);
3526             }
3527 
3528             proto.write(AlarmManagerServiceDumpProto.IS_INTERACTIVE, mInteractive);
3529             if (!mInteractive) {
3530                 // Durations
3531                 proto.write(AlarmManagerServiceDumpProto.TIME_SINCE_NON_INTERACTIVE_MS,
3532                         nowElapsed - mNonInteractiveStartTime);
3533                 proto.write(AlarmManagerServiceDumpProto.MAX_WAKEUP_DELAY_MS,
3534                         currentNonWakeupFuzzLocked(nowElapsed));
3535                 proto.write(AlarmManagerServiceDumpProto.TIME_SINCE_LAST_DISPATCH_MS,
3536                         nowElapsed - mLastAlarmDeliveryTime);
3537                 proto.write(AlarmManagerServiceDumpProto.TIME_UNTIL_NEXT_NON_WAKEUP_DELIVERY_MS,
3538                         nowElapsed - mNextNonWakeupDeliveryTime);
3539             }
3540 
3541             proto.write(AlarmManagerServiceDumpProto.TIME_UNTIL_NEXT_NON_WAKEUP_ALARM_MS,
3542                     mNextNonWakeup - nowElapsed);
3543             proto.write(AlarmManagerServiceDumpProto.TIME_UNTIL_NEXT_WAKEUP_MS,
3544                     mNextWakeup - nowElapsed);
3545             proto.write(AlarmManagerServiceDumpProto.TIME_SINCE_LAST_WAKEUP_MS,
3546                     nowElapsed - mLastWakeup);
3547             proto.write(AlarmManagerServiceDumpProto.TIME_SINCE_LAST_WAKEUP_SET_MS,
3548                     nowElapsed - mNextWakeUpSetAt);
3549             proto.write(AlarmManagerServiceDumpProto.TIME_CHANGE_EVENT_COUNT, mNumTimeChanged);
3550 
3551             final TreeSet<Integer> users = new TreeSet<>();
3552             final int nextAlarmClockForUserSize = mNextAlarmClockForUser.size();
3553             for (int i = 0; i < nextAlarmClockForUserSize; i++) {
3554                 users.add(mNextAlarmClockForUser.keyAt(i));
3555             }
3556             final int pendingSendNextAlarmClockChangedForUserSize =
3557                     mPendingSendNextAlarmClockChangedForUser.size();
3558             for (int i = 0; i < pendingSendNextAlarmClockChangedForUserSize; i++) {
3559                 users.add(mPendingSendNextAlarmClockChangedForUser.keyAt(i));
3560             }
3561             for (int user : users) {
3562                 final AlarmManager.AlarmClockInfo next = mNextAlarmClockForUser.get(user);
3563                 final long time = next != null ? next.getTriggerTime() : 0;
3564                 final boolean pendingSend = mPendingSendNextAlarmClockChangedForUser.get(user);
3565                 final long aToken = proto.start(
3566                         AlarmManagerServiceDumpProto.NEXT_ALARM_CLOCK_METADATA);
3567                 proto.write(AlarmClockMetadataProto.USER, user);
3568                 proto.write(AlarmClockMetadataProto.IS_PENDING_SEND, pendingSend);
3569                 proto.write(AlarmClockMetadataProto.TRIGGER_TIME_MS, time);
3570                 proto.end(aToken);
3571             }
3572             mAlarmStore.dumpProto(proto, nowElapsed);
3573 
3574             for (int i = 0; i < mPendingBackgroundAlarms.size(); i++) {
3575                 final ArrayList<Alarm> blockedAlarms = mPendingBackgroundAlarms.valueAt(i);
3576                 if (blockedAlarms != null) {
3577                     for (Alarm a : blockedAlarms) {
3578                         a.dumpDebug(proto,
3579                                 AlarmManagerServiceDumpProto.PENDING_USER_BLOCKED_BACKGROUND_ALARMS,
3580                                 nowElapsed);
3581                     }
3582                 }
3583             }
3584             if (mPendingIdleUntil != null) {
3585                 mPendingIdleUntil.dumpDebug(
3586                         proto, AlarmManagerServiceDumpProto.PENDING_IDLE_UNTIL, nowElapsed);
3587             }
3588             if (mNextWakeFromIdle != null) {
3589                 mNextWakeFromIdle.dumpDebug(proto, AlarmManagerServiceDumpProto.NEXT_WAKE_FROM_IDLE,
3590                         nowElapsed);
3591             }
3592 
3593             for (Alarm a : mPendingNonWakeupAlarms) {
3594                 a.dumpDebug(proto, AlarmManagerServiceDumpProto.PAST_DUE_NON_WAKEUP_ALARMS,
3595                         nowElapsed);
3596             }
3597 
3598             proto.write(AlarmManagerServiceDumpProto.DELAYED_ALARM_COUNT, mNumDelayedAlarms);
3599             proto.write(AlarmManagerServiceDumpProto.TOTAL_DELAY_TIME_MS, mTotalDelayTime);
3600             proto.write(AlarmManagerServiceDumpProto.MAX_DELAY_DURATION_MS, mMaxDelayTime);
3601             proto.write(AlarmManagerServiceDumpProto.MAX_NON_INTERACTIVE_DURATION_MS,
3602                     mNonInteractiveTime);
3603 
3604             proto.write(AlarmManagerServiceDumpProto.BROADCAST_REF_COUNT, mBroadcastRefCount);
3605             proto.write(AlarmManagerServiceDumpProto.PENDING_INTENT_SEND_COUNT, mSendCount);
3606             proto.write(AlarmManagerServiceDumpProto.PENDING_INTENT_FINISH_COUNT, mSendFinishCount);
3607             proto.write(AlarmManagerServiceDumpProto.LISTENER_SEND_COUNT, mListenerCount);
3608             proto.write(AlarmManagerServiceDumpProto.LISTENER_FINISH_COUNT, mListenerFinishCount);
3609 
3610             for (InFlight f : mInFlight) {
3611                 f.dumpDebug(proto, AlarmManagerServiceDumpProto.OUTSTANDING_DELIVERIES);
3612             }
3613 
3614             mLog.dumpDebug(proto, AlarmManagerServiceDumpProto.RECENT_PROBLEMS);
3615 
3616             final FilterStats[] topFilters = new FilterStats[10];
3617             final Comparator<FilterStats> comparator = new Comparator<FilterStats>() {
3618                 @Override
3619                 public int compare(FilterStats lhs, FilterStats rhs) {
3620                     if (lhs.aggregateTime < rhs.aggregateTime) {
3621                         return 1;
3622                     } else if (lhs.aggregateTime > rhs.aggregateTime) {
3623                         return -1;
3624                     }
3625                     return 0;
3626                 }
3627             };
3628             int len = 0;
3629             // Get the top 10 FilterStats, ordered by aggregateTime.
3630             for (int iu = 0; iu < mBroadcastStats.size(); ++iu) {
3631                 ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(iu);
3632                 for (int ip = 0; ip < uidStats.size(); ++ip) {
3633                     BroadcastStats bs = uidStats.valueAt(ip);
3634                     for (int is = 0; is < bs.filterStats.size(); ++is) {
3635                         FilterStats fs = bs.filterStats.valueAt(is);
3636                         int pos = len > 0
3637                                 ? Arrays.binarySearch(topFilters, 0, len, fs, comparator) : 0;
3638                         if (pos < 0) {
3639                             pos = -pos - 1;
3640                         }
3641                         if (pos < topFilters.length) {
3642                             int copylen = topFilters.length - pos - 1;
3643                             if (copylen > 0) {
3644                                 System.arraycopy(topFilters, pos, topFilters, pos + 1, copylen);
3645                             }
3646                             topFilters[pos] = fs;
3647                             if (len < topFilters.length) {
3648                                 len++;
3649                             }
3650                         }
3651                     }
3652                 }
3653             }
3654             for (int i = 0; i < len; ++i) {
3655                 final long token = proto.start(AlarmManagerServiceDumpProto.TOP_ALARMS);
3656                 FilterStats fs = topFilters[i];
3657 
3658                 proto.write(AlarmManagerServiceDumpProto.TopAlarm.UID, fs.mBroadcastStats.mUid);
3659                 proto.write(AlarmManagerServiceDumpProto.TopAlarm.PACKAGE_NAME,
3660                         fs.mBroadcastStats.mPackageName);
3661                 fs.dumpDebug(proto, AlarmManagerServiceDumpProto.TopAlarm.FILTER);
3662 
3663                 proto.end(token);
3664             }
3665 
3666             final ArrayList<FilterStats> tmpFilters = new ArrayList<FilterStats>();
3667             for (int iu = 0; iu < mBroadcastStats.size(); ++iu) {
3668                 ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(iu);
3669                 for (int ip = 0; ip < uidStats.size(); ++ip) {
3670                     final long token = proto.start(AlarmManagerServiceDumpProto.ALARM_STATS);
3671 
3672                     BroadcastStats bs = uidStats.valueAt(ip);
3673                     bs.dumpDebug(proto, AlarmManagerServiceDumpProto.AlarmStat.BROADCAST);
3674 
3675                     // uidStats is an ArrayMap, which we can't sort.
3676                     tmpFilters.clear();
3677                     for (int is = 0; is < bs.filterStats.size(); ++is) {
3678                         tmpFilters.add(bs.filterStats.valueAt(is));
3679                     }
3680                     Collections.sort(tmpFilters, comparator);
3681                     for (FilterStats fs : tmpFilters) {
3682                         fs.dumpDebug(proto, AlarmManagerServiceDumpProto.AlarmStat.FILTERS);
3683                     }
3684 
3685                     proto.end(token);
3686                 }
3687             }
3688 
3689             if (RECORD_DEVICE_IDLE_ALARMS) {
3690                 for (int i = 0; i < mAllowWhileIdleDispatches.size(); i++) {
3691                     IdleDispatchEntry ent = mAllowWhileIdleDispatches.get(i);
3692                     final long token = proto.start(
3693                             AlarmManagerServiceDumpProto.ALLOW_WHILE_IDLE_DISPATCHES);
3694 
3695                     proto.write(IdleDispatchEntryProto.UID, ent.uid);
3696                     proto.write(IdleDispatchEntryProto.PKG, ent.pkg);
3697                     proto.write(IdleDispatchEntryProto.TAG, ent.tag);
3698                     proto.write(IdleDispatchEntryProto.OP, ent.op);
3699                     proto.write(IdleDispatchEntryProto.ENTRY_CREATION_REALTIME,
3700                             ent.elapsedRealtime);
3701                     proto.write(IdleDispatchEntryProto.ARG_REALTIME, ent.argRealtime);
3702 
3703                     proto.end(token);
3704                 }
3705             }
3706         }
3707 
3708         proto.flush();
3709     }
3710 
getNextWakeFromIdleTimeImpl()3711     long getNextWakeFromIdleTimeImpl() {
3712         synchronized (mLock) {
3713             return mNextWakeFromIdle != null ? mNextWakeFromIdle.getWhenElapsed() : Long.MAX_VALUE;
3714         }
3715     }
3716 
isIdlingImpl()3717     private boolean isIdlingImpl() {
3718         synchronized (mLock) {
3719             return mPendingIdleUntil != null;
3720         }
3721     }
3722 
getNextAlarmClockImpl(int userId)3723     AlarmManager.AlarmClockInfo getNextAlarmClockImpl(int userId) {
3724         synchronized (mLock) {
3725             return mNextAlarmClockForUser.get(userId);
3726         }
3727     }
3728 
3729     /**
3730      * Recomputes the next alarm clock for all users.
3731      */
updateNextAlarmClockLocked()3732     private void updateNextAlarmClockLocked() {
3733         if (!mNextAlarmClockMayChange) {
3734             return;
3735         }
3736         mNextAlarmClockMayChange = false;
3737 
3738         final SparseArray<AlarmManager.AlarmClockInfo> nextForUser = mTmpSparseAlarmClockArray;
3739         nextForUser.clear();
3740 
3741         final ArrayList<Alarm> allAlarms = mAlarmStore.asList();
3742         for (final Alarm a : allAlarms) {
3743             if (a.alarmClock != null) {
3744                 final int userId = UserHandle.getUserId(a.uid);
3745                 final AlarmManager.AlarmClockInfo current = mNextAlarmClockForUser.get(userId);
3746 
3747                 if (DEBUG_ALARM_CLOCK) {
3748                     Log.v(TAG, "Found AlarmClockInfo " + a.alarmClock + " at "
3749                             + formatNextAlarm(getContext(), a.alarmClock, userId)
3750                             + " for user " + userId);
3751                 }
3752 
3753                 // AlarmClocks are sorted by time, so no need to compare times here.
3754                 if (nextForUser.get(userId) == null) {
3755                     nextForUser.put(userId, a.alarmClock);
3756                 } else if (a.alarmClock.equals(current)
3757                         && current.getTriggerTime() <= nextForUser.get(userId).getTriggerTime()) {
3758                     // same/earlier time and it's the one we cited before, so stick with it
3759                     nextForUser.put(userId, current);
3760                 }
3761             }
3762         }
3763 
3764         final int newUserCount = nextForUser.size();
3765         for (int i = 0; i < newUserCount; i++) {
3766             AlarmManager.AlarmClockInfo newAlarm = nextForUser.valueAt(i);
3767             int userId = nextForUser.keyAt(i);
3768             AlarmManager.AlarmClockInfo currentAlarm = mNextAlarmClockForUser.get(userId);
3769             if (!newAlarm.equals(currentAlarm)) {
3770                 updateNextAlarmInfoForUserLocked(userId, newAlarm);
3771             }
3772         }
3773 
3774         final int oldUserCount = mNextAlarmClockForUser.size();
3775         for (int i = oldUserCount - 1; i >= 0; i--) {
3776             int userId = mNextAlarmClockForUser.keyAt(i);
3777             if (nextForUser.get(userId) == null) {
3778                 updateNextAlarmInfoForUserLocked(userId, null);
3779             }
3780         }
3781     }
3782 
updateNextAlarmInfoForUserLocked(int userId, AlarmManager.AlarmClockInfo alarmClock)3783     private void updateNextAlarmInfoForUserLocked(int userId,
3784             AlarmManager.AlarmClockInfo alarmClock) {
3785         if (alarmClock != null) {
3786             if (DEBUG_ALARM_CLOCK) {
3787                 Log.v(TAG, "Next AlarmClockInfoForUser(" + userId + "): " +
3788                         formatNextAlarm(getContext(), alarmClock, userId));
3789             }
3790             mNextAlarmClockForUser.put(userId, alarmClock);
3791             if (mStartUserBeforeScheduledAlarms) {
3792                 mUserWakeupStore.addUserWakeup(userId, convertToElapsed(
3793                         mNextAlarmClockForUser.get(userId).getTriggerTime(), RTC));
3794             }
3795         } else {
3796             if (DEBUG_ALARM_CLOCK) {
3797                 Log.v(TAG, "Next AlarmClockInfoForUser(" + userId + "): None");
3798             }
3799             if (mStartUserBeforeScheduledAlarms) {
3800                 if (mActivityManagerInternal.isUserRunning(userId, 0)) {
3801                     mUserWakeupStore.removeUserWakeup(userId);
3802                 }
3803             }
3804             mNextAlarmClockForUser.remove(userId);
3805         }
3806 
3807         mPendingSendNextAlarmClockChangedForUser.put(userId, true);
3808         mHandler.removeMessages(AlarmHandler.SEND_NEXT_ALARM_CLOCK_CHANGED);
3809         mHandler.sendEmptyMessage(AlarmHandler.SEND_NEXT_ALARM_CLOCK_CHANGED);
3810     }
3811 
3812     /**
3813      * Updates NEXT_ALARM_FORMATTED and sends NEXT_ALARM_CLOCK_CHANGED_INTENT for all users
3814      * for which alarm clocks have changed since the last call to this.
3815      *
3816      * Do not call with a lock held. Only call from mHandler's thread.
3817      *
3818      * @see AlarmHandler#SEND_NEXT_ALARM_CLOCK_CHANGED
3819      */
sendNextAlarmClockChanged()3820     private void sendNextAlarmClockChanged() {
3821         SparseArray<AlarmManager.AlarmClockInfo> pendingUsers = mHandlerSparseAlarmClockArray;
3822         pendingUsers.clear();
3823 
3824         synchronized (mLock) {
3825             final int n = mPendingSendNextAlarmClockChangedForUser.size();
3826             for (int i = 0; i < n; i++) {
3827                 int userId = mPendingSendNextAlarmClockChangedForUser.keyAt(i);
3828                 pendingUsers.append(userId, mNextAlarmClockForUser.get(userId));
3829             }
3830             mPendingSendNextAlarmClockChangedForUser.clear();
3831         }
3832 
3833         final int n = pendingUsers.size();
3834         for (int i = 0; i < n; i++) {
3835             int userId = pendingUsers.keyAt(i);
3836             AlarmManager.AlarmClockInfo alarmClock = pendingUsers.valueAt(i);
3837             Settings.System.putStringForUser(getContext().getContentResolver(),
3838                     Settings.System.NEXT_ALARM_FORMATTED,
3839                     formatNextAlarm(getContext(), alarmClock, userId),
3840                     userId);
3841 
3842             getContext().sendBroadcastAsUser(NEXT_ALARM_CLOCK_CHANGED_INTENT,
3843                     new UserHandle(userId));
3844         }
3845     }
3846 
3847     /**
3848      * Formats an alarm like platform/packages/apps/DeskClock used to.
3849      */
formatNextAlarm(final Context context, AlarmManager.AlarmClockInfo info, int userId)3850     private static String formatNextAlarm(final Context context, AlarmManager.AlarmClockInfo info,
3851             int userId) {
3852         String skeleton = DateFormat.is24HourFormat(context, userId) ? "EHm" : "Ehma";
3853         String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton);
3854         return (info == null) ? "" :
3855                 DateFormat.format(pattern, info.getTriggerTime()).toString();
3856     }
3857 
3858     @GuardedBy("mLock")
rescheduleKernelAlarmsLocked()3859     void rescheduleKernelAlarmsLocked() {
3860         // Schedule the next upcoming wakeup alarm.  If there is a deliverable batch
3861         // prior to that which contains no wakeups, we schedule that as well.
3862         final long nowElapsed = mInjector.getElapsedRealtimeMillis();
3863         long nextNonWakeup = 0;
3864         if (mAlarmStore.size() > 0) {
3865             long firstWakeup = mAlarmStore.getNextWakeupDeliveryTime();
3866             if (mStartUserBeforeScheduledAlarms && mUserWakeupStore != null) {
3867                 final long firstUserWakeup = mUserWakeupStore.getNextWakeupTime();
3868                 if (firstUserWakeup >= 0 && firstUserWakeup < firstWakeup) {
3869                     firstWakeup = firstUserWakeup;
3870                 }
3871             }
3872             final long first = mAlarmStore.getNextDeliveryTime();
3873             if (firstWakeup != 0) {
3874                 mNextWakeup = firstWakeup;
3875                 mNextWakeUpSetAt = nowElapsed;
3876                 setLocked(ELAPSED_REALTIME_WAKEUP, firstWakeup);
3877             }
3878             if (first != firstWakeup) {
3879                 nextNonWakeup = first;
3880             }
3881         }
3882         if (mPendingNonWakeupAlarms.size() > 0) {
3883             if (nextNonWakeup == 0 || mNextNonWakeupDeliveryTime < nextNonWakeup) {
3884                 nextNonWakeup = mNextNonWakeupDeliveryTime;
3885             }
3886         }
3887         if (nextNonWakeup != 0) {
3888             mNextNonWakeup = nextNonWakeup;
3889             mNextNonWakeUpSetAt = nowElapsed;
3890             setLocked(ELAPSED_REALTIME, nextNonWakeup);
3891         }
3892     }
3893 
3894     /**
3895      * Called when an app loses the permission to use exact alarms. This will happen when the app
3896      * no longer has either {@link Manifest.permission#SCHEDULE_EXACT_ALARM} or
3897      * {@link Manifest.permission#USE_EXACT_ALARM}.
3898      *
3899      * This is not expected to get called frequently.
3900      */
removeExactAlarmsOnPermissionRevoked(int uid, String packageName, boolean killUid)3901     void removeExactAlarmsOnPermissionRevoked(int uid, String packageName, boolean killUid) {
3902         if (isExemptFromExactAlarmPermissionNoLock(uid)
3903                 || !isExactAlarmChangeEnabled(packageName, UserHandle.getUserId(uid))) {
3904             return;
3905         }
3906         Slog.w(TAG, "Package " + packageName + ", uid " + uid
3907                 + " lost permission to set exact alarms!");
3908 
3909         final Predicate<Alarm> whichAlarms = a -> (a.uid == uid && a.packageName.equals(packageName)
3910                 && a.windowLength == 0);
3911         synchronized (mLock) {
3912             removeAlarmsInternalLocked(whichAlarms, REMOVE_REASON_EXACT_PERMISSION_REVOKED);
3913         }
3914 
3915         if (killUid) {
3916             PermissionManagerService.killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid),
3917                     "schedule_exact_alarm revoked");
3918         }
3919     }
3920 
3921     @GuardedBy("mLock")
removeAlarmsInternalLocked(Predicate<Alarm> whichAlarms, int reason)3922     private void removeAlarmsInternalLocked(Predicate<Alarm> whichAlarms, int reason) {
3923         final long nowRtc = mInjector.getCurrentTimeMillis();
3924         final long nowElapsed = mInjector.getElapsedRealtimeMillis();
3925 
3926         final ArrayList<Alarm> removedAlarms = mAlarmStore.remove(whichAlarms);
3927         final boolean removedFromStore = !removedAlarms.isEmpty();
3928 
3929         for (int i = mPendingBackgroundAlarms.size() - 1; i >= 0; i--) {
3930             final ArrayList<Alarm> alarmsForUid = mPendingBackgroundAlarms.valueAt(i);
3931             for (int j = alarmsForUid.size() - 1; j >= 0; j--) {
3932                 final Alarm alarm = alarmsForUid.get(j);
3933                 if (whichAlarms.test(alarm)) {
3934                     removedAlarms.add(alarmsForUid.remove(j));
3935                 }
3936             }
3937             if (alarmsForUid.size() == 0) {
3938                 mPendingBackgroundAlarms.removeAt(i);
3939             }
3940         }
3941         for (int i = mPendingNonWakeupAlarms.size() - 1; i >= 0; i--) {
3942             final Alarm a = mPendingNonWakeupAlarms.get(i);
3943             if (whichAlarms.test(a)) {
3944                 removedAlarms.add(mPendingNonWakeupAlarms.remove(i));
3945             }
3946         }
3947 
3948         for (final Alarm removed : removedAlarms) {
3949             decrementAlarmCount(removed.uid, 1);
3950             if (removed.listener != null) {
3951                 removed.listener.asBinder().unlinkToDeath(mListenerDeathRecipient, 0);
3952             }
3953             if (!RemovedAlarm.isLoggable(reason)) {
3954                 continue;
3955             }
3956             RingBuffer<RemovedAlarm> bufferForUid = mRemovalHistory.get(removed.uid);
3957             if (bufferForUid == null) {
3958                 bufferForUid = new RingBuffer<>(RemovedAlarm.class, REMOVAL_HISTORY_SIZE_PER_UID);
3959                 mRemovalHistory.put(removed.uid, bufferForUid);
3960             }
3961             bufferForUid.append(new RemovedAlarm(removed, reason, nowRtc, nowElapsed));
3962         }
3963 
3964         if (removedFromStore) {
3965             boolean idleUntilUpdated = false;
3966             if (mPendingIdleUntil != null && whichAlarms.test(mPendingIdleUntil)) {
3967                 mPendingIdleUntil = null;
3968                 idleUntilUpdated = true;
3969             }
3970             if (mNextWakeFromIdle != null && whichAlarms.test(mNextWakeFromIdle)) {
3971                 mNextWakeFromIdle = mAlarmStore.getNextWakeFromIdleAlarm();
3972                 if (mPendingIdleUntil != null) {
3973                     idleUntilUpdated |= mAlarmStore.updateAlarmDeliveries(alarm ->
3974                             (alarm == mPendingIdleUntil && adjustIdleUntilTime(alarm)));
3975                 }
3976             }
3977             if (idleUntilUpdated) {
3978                 mAlarmStore.updateAlarmDeliveries(
3979                         alarm -> adjustDeliveryTimeBasedOnDeviceIdle(alarm));
3980             }
3981             rescheduleKernelAlarmsLocked();
3982             updateNextAlarmClockLocked();
3983         }
3984     }
3985 
3986     @GuardedBy("mLock")
removeLocked(PendingIntent operation, IAlarmListener directReceiver, int reason)3987     void removeLocked(PendingIntent operation, IAlarmListener directReceiver, int reason) {
3988         if (operation == null && directReceiver == null) {
3989             if (localLOGV) {
3990                 Slog.w(TAG, "requested remove() of null operation",
3991                         new RuntimeException("here"));
3992             }
3993             return;
3994         }
3995         removeAlarmsInternalLocked(a -> a.matches(operation, directReceiver), reason);
3996     }
3997 
3998     @GuardedBy("mLock")
removeLocked(final int uid, int reason)3999     void removeLocked(final int uid, int reason) {
4000         if (uid == Process.SYSTEM_UID) {
4001             // If a force-stop occurs for a system-uid package, ignore it.
4002             return;
4003         }
4004         removeAlarmsInternalLocked(a -> a.uid == uid, reason);
4005     }
4006 
4007     @GuardedBy("mLock")
removeLocked(final String packageName, int reason)4008     void removeLocked(final String packageName, int reason) {
4009         if (packageName == null) {
4010             if (localLOGV) {
4011                 Slog.w(TAG, "requested remove() of null packageName",
4012                         new RuntimeException("here"));
4013             }
4014             return;
4015         }
4016         removeAlarmsInternalLocked(a -> a.matches(packageName), reason);
4017     }
4018 
4019     // Only called for ephemeral apps
4020     @GuardedBy("mLock")
removeForStoppedLocked(final int uid)4021     void removeForStoppedLocked(final int uid) {
4022         if (uid == Process.SYSTEM_UID) {
4023             // If a force-stop occurs for a system-uid package, ignore it.
4024             return;
4025         }
4026         final Predicate<Alarm> whichAlarms = (a) -> (a.uid == uid
4027                 && mActivityManagerInternal.isAppStartModeDisabled(uid, a.packageName));
4028         removeAlarmsInternalLocked(whichAlarms, REMOVE_REASON_UNDEFINED);
4029     }
4030 
4031     @GuardedBy("mLock")
removeUserLocked(int userHandle)4032     void removeUserLocked(int userHandle) {
4033         if (userHandle == USER_SYSTEM) {
4034             Slog.w(TAG, "Ignoring attempt to remove system-user state!");
4035             return;
4036         }
4037         final Predicate<Alarm> whichAlarms =
4038                 (Alarm a) -> UserHandle.getUserId(a.uid) == userHandle;
4039         removeAlarmsInternalLocked(whichAlarms, REMOVE_REASON_UNDEFINED);
4040 
4041         for (int i = mLastPriorityAlarmDispatch.size() - 1; i >= 0; i--) {
4042             if (UserHandle.getUserId(mLastPriorityAlarmDispatch.keyAt(i)) == userHandle) {
4043                 mLastPriorityAlarmDispatch.removeAt(i);
4044             }
4045         }
4046         for (int i = mRemovalHistory.size() - 1; i >= 0; i--) {
4047             if (UserHandle.getUserId(mRemovalHistory.keyAt(i)) == userHandle) {
4048                 mRemovalHistory.removeAt(i);
4049             }
4050         }
4051         for (int i = mLastOpScheduleExactAlarm.size() - 1; i >= 0; i--) {
4052             if (UserHandle.getUserId(mLastOpScheduleExactAlarm.keyAt(i)) == userHandle) {
4053                 mLastOpScheduleExactAlarm.removeAt(i);
4054             }
4055         }
4056     }
4057 
4058     @GuardedBy("mLock")
interactiveStateChangedLocked(boolean interactive)4059     void interactiveStateChangedLocked(boolean interactive) {
4060         if (mInteractive != interactive) {
4061             mInteractive = interactive;
4062             final long nowELAPSED = mInjector.getElapsedRealtimeMillis();
4063             if (interactive) {
4064                 if (mPendingNonWakeupAlarms.size() > 0) {
4065                     final long thisDelayTime = nowELAPSED - mStartCurrentDelayTime;
4066                     mTotalDelayTime += thisDelayTime;
4067                     if (mMaxDelayTime < thisDelayTime) {
4068                         mMaxDelayTime = thisDelayTime;
4069                     }
4070                     final ArrayList<Alarm> triggerList = new ArrayList<>(mPendingNonWakeupAlarms);
4071                     deliverAlarmsLocked(triggerList, nowELAPSED);
4072                     mPendingNonWakeupAlarms.clear();
4073                 }
4074                 if (mNonInteractiveStartTime > 0) {
4075                     long dur = nowELAPSED - mNonInteractiveStartTime;
4076                     if (dur > mNonInteractiveTime) {
4077                         mNonInteractiveTime = dur;
4078                     }
4079                 }
4080                 // And send a TIME_TICK right now, since it is important to get the UI updated.
4081                 mHandler.post(() -> getContext().sendBroadcastAsUser(mTimeTickIntent,
4082                         UserHandle.ALL, null, mTimeTickOptions));
4083             } else {
4084                 mNonInteractiveStartTime = nowELAPSED;
4085             }
4086         }
4087     }
4088 
4089     @GuardedBy("mLock")
lookForPackageLocked(String packageName, int uid)4090     boolean lookForPackageLocked(String packageName, int uid) {
4091         // This is called extremely rarely, e.g. when the user opens the force-stop page in settings
4092         // so the loops using an iterator should be fine.
4093         for (final Alarm alarm : mAlarmStore.asList()) {
4094             if (alarm.matches(packageName) && alarm.creatorUid == uid) {
4095                 return true;
4096             }
4097         }
4098         final ArrayList<Alarm> alarmsForUid = mPendingBackgroundAlarms.get(uid);
4099         if (alarmsForUid != null) {
4100             for (final Alarm alarm : alarmsForUid) {
4101                 if (alarm.matches(packageName)) {
4102                     return true;
4103                 }
4104             }
4105         }
4106         for (final Alarm alarm : mPendingNonWakeupAlarms) {
4107             if (alarm.matches(packageName) && alarm.creatorUid == uid) {
4108                 return true;
4109             }
4110         }
4111         return false;
4112     }
4113 
setLocked(int type, long when)4114     private void setLocked(int type, long when) {
4115         if (mInjector.isAlarmDriverPresent()) {
4116             mInjector.setAlarm(type, when);
4117         } else {
4118             Message msg = Message.obtain();
4119             msg.what = AlarmHandler.ALARM_EVENT;
4120 
4121             mHandler.removeMessages(msg.what);
4122             mHandler.sendMessageAtTime(msg, when);
4123         }
4124     }
4125 
dumpAlarmList(IndentingPrintWriter ipw, ArrayList<Alarm> list, long nowELAPSED, SimpleDateFormat sdf)4126     static final void dumpAlarmList(IndentingPrintWriter ipw, ArrayList<Alarm> list,
4127             long nowELAPSED, SimpleDateFormat sdf) {
4128         final int n = list.size();
4129         for (int i = n - 1; i >= 0; i--) {
4130             final Alarm a = list.get(i);
4131             final String label = Alarm.typeToString(a.type);
4132             ipw.print(label);
4133             ipw.print(" #");
4134             ipw.print(n - i);
4135             ipw.print(": ");
4136             ipw.println(a);
4137             ipw.increaseIndent();
4138             a.dump(ipw, nowELAPSED, sdf);
4139             ipw.decreaseIndent();
4140         }
4141     }
4142 
isExemptFromBatterySaver(Alarm alarm)4143     private static boolean isExemptFromBatterySaver(Alarm alarm) {
4144         if (alarm.alarmClock != null) {
4145             return true;
4146         }
4147         if ((alarm.operation != null)
4148                 && (alarm.operation.isActivity() || alarm.operation.isForegroundService())) {
4149             return true;
4150         }
4151         if (UserHandle.isCore(alarm.creatorUid)) {
4152             return true;
4153         }
4154         return false;
4155     }
4156 
isBackgroundRestricted(Alarm alarm)4157     private boolean isBackgroundRestricted(Alarm alarm) {
4158         if (alarm.alarmClock != null) {
4159             // Don't defer alarm clocks
4160             return false;
4161         }
4162         if (alarm.operation != null && alarm.operation.isActivity()) {
4163             // Don't defer starting actual UI
4164             return false;
4165         }
4166         final String sourcePackage = alarm.sourcePackage;
4167         final int sourceUid = alarm.creatorUid;
4168         if (UserHandle.isCore(sourceUid)) {
4169             return false;
4170         }
4171         return (mAppStateTracker != null) && mAppStateTracker.areAlarmsRestricted(sourceUid,
4172                 sourcePackage);
4173     }
4174 
init()4175     private static native long init();
close(long nativeData)4176     private static native void close(long nativeData);
set(long nativeData, int type, long seconds, long nanoseconds)4177     private static native int set(long nativeData, int type, long seconds, long nanoseconds);
waitForAlarm(long nativeData)4178     private static native int waitForAlarm(long nativeData);
getNextAlarm(long nativeData, int type)4179     private static native long getNextAlarm(long nativeData, int type);
4180 
4181     @GuardedBy("mLock")
triggerAlarmsLocked(ArrayList<Alarm> triggerList, final long nowELAPSED)4182     int triggerAlarmsLocked(ArrayList<Alarm> triggerList, final long nowELAPSED) {
4183         int wakeUps = 0;
4184         final ArrayList<Alarm> pendingAlarms = mAlarmStore.removePendingAlarms(nowELAPSED);
4185         for (final Alarm alarm : pendingAlarms) {
4186             if (isBackgroundRestricted(alarm)) {
4187                 // Alarms with FLAG_WAKE_FROM_IDLE or mPendingIdleUntil alarm are not deferred
4188                 if (DEBUG_BG_LIMIT) {
4189                     Slog.d(TAG, "Deferring alarm " + alarm + " due to user forced app standby");
4190                 }
4191                 ArrayList<Alarm> alarmsForUid = mPendingBackgroundAlarms.get(alarm.creatorUid);
4192                 if (alarmsForUid == null) {
4193                     alarmsForUid = new ArrayList<>();
4194                     mPendingBackgroundAlarms.put(alarm.creatorUid, alarmsForUid);
4195                 }
4196                 alarmsForUid.add(alarm);
4197                 continue;
4198             }
4199 
4200             alarm.count = 1;
4201             triggerList.add(alarm);
4202             if ((alarm.flags & FLAG_WAKE_FROM_IDLE) != 0) {
4203                 EventLogTags.writeDeviceIdleWakeFromIdle(mPendingIdleUntil != null ? 1 : 0,
4204                         alarm.statsTag);
4205             }
4206             if (mPendingIdleUntil == alarm) {
4207                 mPendingIdleUntil = null;
4208                 mAlarmStore.updateAlarmDeliveries(a -> adjustDeliveryTimeBasedOnDeviceIdle(a));
4209                 if (RECORD_DEVICE_IDLE_ALARMS) {
4210                     IdleDispatchEntry ent = new IdleDispatchEntry();
4211                     ent.uid = alarm.uid;
4212                     ent.pkg = alarm.sourcePackage;
4213                     ent.tag = alarm.statsTag;
4214                     ent.op = "END IDLE";
4215                     ent.elapsedRealtime = mInjector.getElapsedRealtimeMillis();
4216                     ent.argRealtime = alarm.getWhenElapsed();
4217                     mAllowWhileIdleDispatches.add(ent);
4218                 }
4219             }
4220             if (mNextWakeFromIdle == alarm) {
4221                 mNextWakeFromIdle = mAlarmStore.getNextWakeFromIdleAlarm();
4222                 // Note that we don't need to update mPendingIdleUntil because it should already
4223                 // be removed from the alarm store.
4224             }
4225 
4226             // Recurring alarms may have passed several alarm intervals while the
4227             // phone was asleep or off, so pass a trigger count when sending them.
4228             if (alarm.repeatInterval > 0) {
4229                 // this adjustment will be zero if we're late by
4230                 // less than one full repeat interval
4231                 alarm.count += (nowELAPSED - alarm.getRequestedElapsed()) / alarm.repeatInterval;
4232                 // Also schedule its next recurrence
4233                 final long delta = alarm.count * alarm.repeatInterval;
4234                 final long nextElapsed = alarm.getRequestedElapsed() + delta;
4235                 final long nextMaxElapsed = maxTriggerTime(nowELAPSED, nextElapsed,
4236                         alarm.repeatInterval);
4237                 setImplLocked(alarm.type, alarm.origWhen + delta, nextElapsed,
4238                         nextMaxElapsed - nextElapsed, alarm.repeatInterval, alarm.operation, null,
4239                         null, alarm.flags, alarm.workSource, alarm.alarmClock, alarm.uid,
4240                         alarm.packageName, null, EXACT_ALLOW_REASON_NOT_APPLICABLE);
4241             }
4242 
4243             if (alarm.wakeup) {
4244                 wakeUps++;
4245             }
4246 
4247             // We removed an alarm clock. Let the caller recompute the next alarm clock.
4248             if (alarm.alarmClock != null) {
4249                 mNextAlarmClockMayChange = true;
4250             }
4251         }
4252 
4253         calculateDeliveryPriorities(triggerList);
4254         Collections.sort(triggerList, mAlarmDispatchComparator);
4255 
4256         if (localLOGV) {
4257             for (int i = 0; i < triggerList.size(); i++) {
4258                 Slog.v(TAG, "Triggering alarm #" + i + ": " + triggerList.get(i));
4259             }
4260         }
4261 
4262         return wakeUps;
4263     }
4264 
currentNonWakeupFuzzLocked(long nowELAPSED)4265     long currentNonWakeupFuzzLocked(long nowELAPSED) {
4266         long timeSinceOn = nowELAPSED - mNonInteractiveStartTime;
4267         if (timeSinceOn < 5 * 60 * 1000) {
4268             // If the screen has been off for 5 minutes, only delay by at most two minutes.
4269             return 2 * 60 * 1000;
4270         } else if (timeSinceOn < 30 * 60 * 1000) {
4271             // If the screen has been off for 30 minutes, only delay by at most 15 minutes.
4272             return 15 * 60 * 1000;
4273         } else {
4274             // Otherwise, we will delay by at most an hour.
4275             return 60 * 60 * 1000;
4276         }
4277     }
4278 
4279     @GuardedBy("mLock")
checkAllowNonWakeupDelayLocked(long nowELAPSED)4280     boolean checkAllowNonWakeupDelayLocked(long nowELAPSED) {
4281         if (!mConstants.DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF) {
4282             return false;
4283         }
4284         if (mInteractive) {
4285             return false;
4286         }
4287         if (mLastAlarmDeliveryTime <= 0) {
4288             return false;
4289         }
4290         if (mPendingNonWakeupAlarms.size() > 0 && mNextNonWakeupDeliveryTime < nowELAPSED) {
4291             // This is just a little paranoia, if somehow we have pending non-wakeup alarms
4292             // and the next delivery time is in the past, then just deliver them all.  This
4293             // avoids bugs where we get stuck in a loop trying to poll for alarms.
4294             return false;
4295         }
4296         long timeSinceLast = nowELAPSED - mLastAlarmDeliveryTime;
4297         return timeSinceLast <= currentNonWakeupFuzzLocked(nowELAPSED);
4298     }
4299 
4300     @GuardedBy("mLock")
deliverAlarmsLocked(ArrayList<Alarm> triggerList, long nowELAPSED)4301     void deliverAlarmsLocked(ArrayList<Alarm> triggerList, long nowELAPSED) {
4302         mLastAlarmDeliveryTime = nowELAPSED;
4303         for (int i = 0; i < triggerList.size(); i++) {
4304             Alarm alarm = triggerList.get(i);
4305             if (alarm.wakeup) {
4306                 Trace.traceBegin(Trace.TRACE_TAG_POWER,
4307                         "Dispatch wakeup alarm to " + alarm.packageName);
4308             } else {
4309                 Trace.traceBegin(Trace.TRACE_TAG_POWER,
4310                         "Dispatch non-wakeup alarm to " + alarm.packageName);
4311             }
4312             try {
4313                 if (localLOGV) {
4314                     Slog.v(TAG, "sending alarm " + alarm);
4315                 }
4316                 if (RECORD_ALARMS_IN_HISTORY) {
4317                     mActivityManagerInternal.noteAlarmStart(alarm.operation, alarm.workSource,
4318                             alarm.uid, alarm.statsTag);
4319                 }
4320                 mDeliveryTracker.deliverLocked(alarm, nowELAPSED);
4321             } catch (RuntimeException e) {
4322                 Slog.w(TAG, "Failure sending alarm.", e);
4323             }
4324             Trace.traceEnd(Trace.TRACE_TAG_POWER);
4325             decrementAlarmCount(alarm.uid, 1);
4326         }
4327     }
4328 
4329     @VisibleForTesting
isExemptFromAppStandby(Alarm a)4330     static boolean isExemptFromAppStandby(Alarm a) {
4331         return a.alarmClock != null || UserHandle.isCore(a.creatorUid)
4332                 || (a.flags & (FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED | FLAG_ALLOW_WHILE_IDLE)) != 0;
4333     }
4334 
4335     @VisibleForTesting
4336     static class Injector {
4337         private long mNativeData;
4338         private Context mContext;
4339 
Injector(Context context)4340         Injector(Context context) {
4341             mContext = context;
4342         }
4343 
init()4344         void init() {
4345             System.loadLibrary("alarm_jni");
4346             mNativeData = AlarmManagerService.init();
4347         }
4348 
waitForAlarm()4349         int waitForAlarm() {
4350             return AlarmManagerService.waitForAlarm(mNativeData);
4351         }
4352 
isAlarmDriverPresent()4353         boolean isAlarmDriverPresent() {
4354             return mNativeData != 0;
4355         }
4356 
setAlarm(int type, long millis)4357         void setAlarm(int type, long millis) {
4358             // The kernel never triggers alarms with negative wakeup times
4359             // so we ensure they are positive.
4360             final long alarmSeconds, alarmNanoseconds;
4361             if (millis < 0) {
4362                 alarmSeconds = 0;
4363                 alarmNanoseconds = 0;
4364             } else {
4365                 alarmSeconds = millis / 1000;
4366                 alarmNanoseconds = (millis % 1000) * 1000 * 1000;
4367             }
4368 
4369             final int result = AlarmManagerService.set(mNativeData, type, alarmSeconds,
4370                     alarmNanoseconds);
4371             if (result != 0) {
4372                 final long nowElapsed = SystemClock.elapsedRealtime();
4373                 Slog.wtf(TAG, "Unable to set kernel alarm, now=" + nowElapsed
4374                         + " type=" + type + " @ (" + alarmSeconds + "," + alarmNanoseconds
4375                         + "), ret = " + result + " = " + Os.strerror(result));
4376             }
4377         }
4378 
getCallingUid()4379         int getCallingUid() {
4380             return Binder.getCallingUid();
4381         }
4382 
getNextAlarm(int type)4383         long getNextAlarm(int type) {
4384             return AlarmManagerService.getNextAlarm(mNativeData, type);
4385         }
4386 
initializeTimeIfRequired()4387         void initializeTimeIfRequired() {
4388             SystemClockTime.initializeIfRequired();
4389         }
4390 
setCurrentTimeMillis( @urrentTimeMillisLong long unixEpochMillis, @TimeConfidence int confidence, @NonNull String logMsg)4391         void setCurrentTimeMillis(
4392                 @CurrentTimeMillisLong long unixEpochMillis,
4393                 @TimeConfidence int confidence,
4394                 @NonNull String logMsg) {
4395             SystemClockTime.setTimeAndConfidence(unixEpochMillis, confidence, logMsg);
4396         }
4397 
close()4398         void close() {
4399             AlarmManagerService.close(mNativeData);
4400         }
4401 
4402         @ElapsedRealtimeLong
getElapsedRealtimeMillis()4403         long getElapsedRealtimeMillis() {
4404             return SystemClock.elapsedRealtime();
4405         }
4406 
4407         @CurrentTimeMillisLong
getCurrentTimeMillis()4408         long getCurrentTimeMillis() {
4409             return System.currentTimeMillis();
4410         }
4411 
getAlarmWakeLock()4412         PowerManager.WakeLock getAlarmWakeLock() {
4413             final PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
4414             return pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*alarm*");
4415         }
4416 
getSystemUiUid(PackageManagerInternal pm)4417         int getSystemUiUid(PackageManagerInternal pm) {
4418             return pm.getPackageUid(pm.getSystemUiServiceComponent().getPackageName(),
4419                     MATCH_SYSTEM_ONLY, USER_SYSTEM);
4420         }
4421 
getAppOpsService()4422         IAppOpsService getAppOpsService() {
4423             return IAppOpsService.Stub.asInterface(
4424                     ServiceManager.getService(Context.APP_OPS_SERVICE));
4425         }
4426 
getClockReceiver(AlarmManagerService service)4427         ClockReceiver getClockReceiver(AlarmManagerService service) {
4428             return service.new ClockReceiver();
4429         }
4430 
registerDeviceConfigListener(DeviceConfig.OnPropertiesChangedListener listener)4431         void registerDeviceConfigListener(DeviceConfig.OnPropertiesChangedListener listener) {
4432             DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_ALARM_MANAGER,
4433                     AppSchedulingModuleThread.getExecutor(), listener);
4434         }
4435     }
4436 
4437     private class AlarmThread extends Thread {
4438         private int mFalseWakeups;
4439         private int mWtfThreshold;
4440 
AlarmThread()4441         AlarmThread() {
4442             super("AlarmManager");
4443             mFalseWakeups = 0;
4444             mWtfThreshold = 100;
4445         }
4446 
run()4447         public void run() {
4448             ArrayList<Alarm> triggerList = new ArrayList<Alarm>();
4449 
4450             while (true) {
4451                 int result = mInjector.waitForAlarm();
4452                 final long nowRTC = mInjector.getCurrentTimeMillis();
4453                 final long nowELAPSED = mInjector.getElapsedRealtimeMillis();
4454                 synchronized (mLock) {
4455                     mLastWakeup = nowELAPSED;
4456                 }
4457                 if (result == 0) {
4458                     Slog.wtf(TAG, "waitForAlarm returned 0, nowRTC = " + nowRTC
4459                             + ", nowElapsed = " + nowELAPSED);
4460                 }
4461                 triggerList.clear();
4462 
4463                 if ((result & TIME_CHANGED_MASK) != 0) {
4464                     // The kernel can give us spurious time change notifications due to
4465                     // small adjustments it makes internally; we want to filter those out.
4466                     final long lastTimeChangeClockTime;
4467                     final long expectedClockTime;
4468                     synchronized (mLock) {
4469                         lastTimeChangeClockTime = mLastTimeChangeClockTime;
4470                         expectedClockTime = lastTimeChangeClockTime
4471                                 + (nowELAPSED - mLastTimeChangeRealtime);
4472                     }
4473                     if (lastTimeChangeClockTime == 0 || nowRTC < (expectedClockTime - 1000)
4474                             || nowRTC > (expectedClockTime + 1000)) {
4475                         // The change is by at least +/- 1000 ms (or this is the first change),
4476                         // let's do it!
4477                         if (DEBUG_BATCH) {
4478                             Slog.v(TAG, "Time changed notification from kernel; rebatching");
4479                         }
4480                         // StatsLog requires currentTimeMillis(), which == nowRTC to within usecs.
4481                         FrameworkStatsLog.write(FrameworkStatsLog.WALL_CLOCK_TIME_SHIFTED, nowRTC);
4482                         removeImpl(null, mTimeTickTrigger);
4483                         removeImpl(mDateChangeSender, null);
4484                         reevaluateRtcAlarms();
4485                         mClockReceiver.scheduleTimeTickEvent();
4486                         mClockReceiver.scheduleDateChangedEvent();
4487                         synchronized (mLock) {
4488                             mNumTimeChanged++;
4489                             mLastTimeChangeClockTime = nowRTC;
4490                             mLastTimeChangeRealtime = nowELAPSED;
4491                         }
4492                         Intent intent = new Intent(Intent.ACTION_TIME_CHANGED);
4493                         intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
4494                                 | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
4495                                 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
4496                                 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4497                         mOptsTimeBroadcast.setTemporaryAppAllowlist(
4498                                 mActivityManagerInternal.getBootTimeTempAllowListDuration(),
4499                                 TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
4500                                 PowerExemptionManager.REASON_TIME_CHANGED, "");
4501                         mOptsTimeBroadcast.setDeliveryGroupPolicy(
4502                                 BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT);
4503                         getContext().sendBroadcastAsUser(intent, UserHandle.ALL,
4504                                 null /* receiverPermission */, mOptsTimeBroadcast.toBundle());
4505                         // The world has changed on us, so we need to re-evaluate alarms
4506                         // regardless of whether the kernel has told us one went off.
4507                         result |= IS_WAKEUP_MASK;
4508                     }
4509                 }
4510 
4511                 if (result != TIME_CHANGED_MASK) {
4512                     // If this was anything besides just a time change, then figure what if
4513                     // anything to do about alarms.
4514                     synchronized (mLock) {
4515                         if (localLOGV) {
4516                             Slog.v(TAG, "Checking for alarms... rtc=" + nowRTC
4517                                             + ", elapsed=" + nowELAPSED);
4518                         }
4519 
4520                         if (mStartUserBeforeScheduledAlarms) {
4521                             final int[] userIds =
4522                                     mUserWakeupStore.getUserIdsToWakeup(nowELAPSED);
4523                             for (int i = 0; i < userIds.length; i++) {
4524                                 if (!mActivityManagerInternal.startUserInBackground(
4525                                         userIds[i])) {
4526                                     mUserWakeupStore.removeUserWakeup(userIds[i]);
4527                                 }
4528                             }
4529                         }
4530                         mLastTrigger = nowELAPSED;
4531                         final int wakeUps = triggerAlarmsLocked(triggerList, nowELAPSED);
4532                         if (wakeUps == 0 && checkAllowNonWakeupDelayLocked(nowELAPSED)) {
4533                             // if there are no wakeup alarms and the screen is off, we can
4534                             // delay what we have so far until the future.
4535                             if (mPendingNonWakeupAlarms.size() == 0) {
4536                                 mStartCurrentDelayTime = nowELAPSED;
4537                                 mNextNonWakeupDeliveryTime = nowELAPSED
4538                                         + ((currentNonWakeupFuzzLocked(nowELAPSED) * 3) / 2);
4539                             }
4540                             mPendingNonWakeupAlarms.addAll(triggerList);
4541                             mNumDelayedAlarms += triggerList.size();
4542                             rescheduleKernelAlarmsLocked();
4543                             updateNextAlarmClockLocked();
4544                         } else {
4545                             // now deliver the alarm intents; if there are pending non-wakeup
4546                             // alarms, we need to merge them in to the list.  note we don't
4547                             // just deliver them first because we generally want non-wakeup
4548                             // alarms delivered after wakeup alarms.
4549                             if (mPendingNonWakeupAlarms.size() > 0) {
4550                                 calculateDeliveryPriorities(mPendingNonWakeupAlarms);
4551                                 triggerList.addAll(mPendingNonWakeupAlarms);
4552                                 Collections.sort(triggerList, mAlarmDispatchComparator);
4553                                 final long thisDelayTime = nowELAPSED - mStartCurrentDelayTime;
4554                                 mTotalDelayTime += thisDelayTime;
4555                                 if (mMaxDelayTime < thisDelayTime) {
4556                                     mMaxDelayTime = thisDelayTime;
4557                                 }
4558                                 mPendingNonWakeupAlarms.clear();
4559                             }
4560                             if (mLastTimeChangeRealtime != nowELAPSED && triggerList.isEmpty()) {
4561                                 if (++mFalseWakeups >= mWtfThreshold) {
4562                                     Slog.wtf(TAG, "Too many (" + mFalseWakeups
4563                                             + ") false wakeups, nowElapsed=" + nowELAPSED);
4564                                     if (mWtfThreshold < 100_000) {
4565                                         mWtfThreshold *= 10;
4566                                     } else {
4567                                         mFalseWakeups = 0;
4568                                     }
4569                                 }
4570                             }
4571                             final ArraySet<UserPackage> triggerPackages = new ArraySet<>();
4572                             final IntArray wakeupUids = new IntArray();
4573                             final SparseIntArray countsPerUid = new SparseIntArray();
4574                             final SparseIntArray wakeupCountsPerUid = new SparseIntArray();
4575                             for (int i = 0; i < triggerList.size(); i++) {
4576                                 final Alarm a = triggerList.get(i);
4577                                 increment(countsPerUid, a.uid);
4578                                 if (a.wakeup) {
4579                                     wakeupUids.add(a.uid);
4580                                     increment(wakeupCountsPerUid, a.uid);
4581                                 }
4582                                 if (!isExemptFromAppStandby(a)) {
4583                                     triggerPackages.add(UserPackage.of(
4584                                             UserHandle.getUserId(a.creatorUid), a.sourcePackage));
4585                                 }
4586                             }
4587                             if (wakeupUids.size() > 0 && mBatteryStatsInternal != null) {
4588                                 mBatteryStatsInternal.noteWakingAlarmBatch(nowELAPSED,
4589                                         wakeupUids.toArray());
4590                             }
4591                             deliverAlarmsLocked(triggerList, nowELAPSED);
4592                             mTemporaryQuotaReserve.cleanUpExpiredQuotas(nowELAPSED);
4593                             reorderAlarmsBasedOnStandbyBuckets(triggerPackages);
4594                             rescheduleKernelAlarmsLocked();
4595                             updateNextAlarmClockLocked();
4596                             logAlarmBatchDelivered(
4597                                     triggerList.size(), wakeUps, countsPerUid, wakeupCountsPerUid);
4598                         }
4599                     }
4600 
4601                 } else {
4602                     // Just in case -- even though no wakeup flag was set, make sure
4603                     // we have updated the kernel to the next alarm time.
4604                     synchronized (mLock) {
4605                         rescheduleKernelAlarmsLocked();
4606                     }
4607                 }
4608             }
4609         }
4610     }
4611 
increment(SparseIntArray array, int key)4612     private static void increment(SparseIntArray array, int key) {
4613         final int index = array.indexOfKey(key);
4614         if (index >= 0) {
4615             array.setValueAt(index, array.valueAt(index) + 1);
4616         } else {
4617             array.put(key, 1);
4618         }
4619     }
4620 
logAlarmBatchDelivered( int alarms, int wakeups, SparseIntArray countsPerUid, SparseIntArray wakeupCountsPerUid)4621     private void logAlarmBatchDelivered(
4622             int alarms,
4623             int wakeups,
4624             SparseIntArray countsPerUid,
4625             SparseIntArray wakeupCountsPerUid) {
4626         final int[] uids = new int[countsPerUid.size()];
4627         final int[] countsArray = new int[countsPerUid.size()];
4628         final int[] wakeupCountsArray = new int[countsPerUid.size()];
4629         for (int i = 0; i < countsPerUid.size(); i++) {
4630             uids[i] = countsPerUid.keyAt(i);
4631             countsArray[i] = countsPerUid.valueAt(i);
4632             wakeupCountsArray[i] = wakeupCountsPerUid.get(uids[i], 0);
4633         }
4634         MetricsHelper.pushAlarmBatchDelivered(
4635                 alarms, wakeups, uids, countsArray, wakeupCountsArray);
4636     }
4637 
4638     /**
4639      * Attribute blame for a WakeLock.
4640      *
4641      * @param ws       WorkSource to attribute blame.
4642      * @param knownUid attribution uid; < 0 values are ignored.
4643      */
setWakelockWorkSource(WorkSource ws, int knownUid, String tag, boolean first)4644     void setWakelockWorkSource(WorkSource ws, int knownUid, String tag, boolean first) {
4645         try {
4646             mWakeLock.setHistoryTag(first ? tag : null);
4647 
4648             if (ws != null) {
4649                 mWakeLock.setWorkSource(ws);
4650                 return;
4651             }
4652 
4653             if (knownUid >= 0) {
4654                 mWakeLock.setWorkSource(new WorkSource(knownUid));
4655                 return;
4656             }
4657         } catch (Exception e) {
4658         }
4659 
4660         // Something went wrong; fall back to attributing the lock to the OS
4661         mWakeLock.setWorkSource(null);
4662     }
4663 
getAlarmAttributionUid(Alarm alarm)4664     private static int getAlarmAttributionUid(Alarm alarm) {
4665         if (alarm.workSource != null && !alarm.workSource.isEmpty()) {
4666             return alarm.workSource.getAttributionUid();
4667         }
4668 
4669         return alarm.creatorUid;
4670     }
4671 
getAlarmOperationBundle(Alarm alarm)4672     private Bundle getAlarmOperationBundle(Alarm alarm) {
4673         if (alarm.mIdleOptions != null) {
4674             return alarm.mIdleOptions;
4675         } else {
4676             if (alarm.operation.isActivity()) {
4677                 return mActivityOptsRestrictBal.toBundle();
4678             } else {
4679                 return mBroadcastOptsRestrictBal.toBundle();
4680             }
4681         }
4682     }
4683 
4684     @VisibleForTesting
4685     class AlarmHandler extends Handler {
4686         public static final int ALARM_EVENT = 1;
4687         public static final int SEND_NEXT_ALARM_CLOCK_CHANGED = 2;
4688         public static final int LISTENER_TIMEOUT = 3;
4689         public static final int REPORT_ALARMS_ACTIVE = 4;
4690         public static final int APP_STANDBY_BUCKET_CHANGED = 5;
4691         public static final int CHARGING_STATUS_CHANGED = 6;
4692         public static final int REMOVE_FOR_CANCELED = 7;
4693         public static final int REMOVE_EXACT_ALARMS = 8;
4694         // Unused id 9
4695         // Unused id 10
4696         public static final int REFRESH_EXACT_ALARM_CANDIDATES = 11;
4697         public static final int CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE = 13;
4698         public static final int TEMPORARY_QUOTA_CHANGED = 14;
4699         public static final int REMOVE_EXACT_LISTENER_ALARMS_ON_CACHED = 15;
4700 
AlarmHandler()4701         AlarmHandler() {
4702             super(Looper.myLooper());
4703         }
4704 
4705         @Override
handleMessage(Message msg)4706         public void handleMessage(Message msg) {
4707             switch (msg.what) {
4708                 case ALARM_EVENT: {
4709                     // This code is used when the kernel timer driver is not available, which
4710                     // shouldn't happen. Here, we try our best to simulate it, which may be useful
4711                     // when porting Android to a new device. Note that we can't wake up a device
4712                     // this way, so WAKE_UP alarms will be delivered only when the device is awake.
4713                     ArrayList<Alarm> triggerList = new ArrayList<Alarm>();
4714                     synchronized (mLock) {
4715                         final long nowELAPSED = mInjector.getElapsedRealtimeMillis();
4716                         triggerAlarmsLocked(triggerList, nowELAPSED);
4717                         updateNextAlarmClockLocked();
4718                     }
4719 
4720                     // now trigger the alarms without the lock held
4721                     for (int i = 0; i < triggerList.size(); i++) {
4722                         Alarm alarm = triggerList.get(i);
4723                         try {
4724                             // Disallow AlarmManager to start random background activity.
4725                             final Bundle bundle = getAlarmOperationBundle(alarm);
4726                             alarm.operation.send(/* context */ null, /* code */0, /* intent */
4727                                     null, /* onFinished */null, /* handler */
4728                                     null, /* requiredPermission */ null, bundle);
4729                         } catch (PendingIntent.CanceledException e) {
4730                             if (alarm.repeatInterval > 0) {
4731                                 // This IntentSender is no longer valid, but this
4732                                 // is a repeating alarm, so toss the hoser.
4733                                 removeImpl(alarm.operation, null);
4734                             }
4735                         }
4736                         decrementAlarmCount(alarm.uid, 1);
4737                     }
4738                     break;
4739                 }
4740 
4741                 case SEND_NEXT_ALARM_CLOCK_CHANGED:
4742                     sendNextAlarmClockChanged();
4743                     break;
4744 
4745                 case LISTENER_TIMEOUT:
4746                     mDeliveryTracker.alarmTimedOut((IBinder) msg.obj);
4747                     break;
4748 
4749                 case REPORT_ALARMS_ACTIVE:
4750                     if (mLocalDeviceIdleController != null) {
4751                         mLocalDeviceIdleController.setAlarmsActive(msg.arg1 != 0);
4752                     }
4753                     break;
4754 
4755                 case CHARGING_STATUS_CHANGED:
4756                     synchronized (mLock) {
4757                         mAppStandbyParole = (Boolean) msg.obj;
4758                         if (reorderAlarmsBasedOnStandbyBuckets(null)) {
4759                             rescheduleKernelAlarmsLocked();
4760                             updateNextAlarmClockLocked();
4761                         }
4762                     }
4763                     break;
4764 
4765                 case TEMPORARY_QUOTA_CHANGED:
4766                 case APP_STANDBY_BUCKET_CHANGED:
4767                     synchronized (mLock) {
4768                         final ArraySet<UserPackage> filterPackages = new ArraySet<>();
4769                         filterPackages.add(UserPackage.of(msg.arg1, (String) msg.obj));
4770                         if (reorderAlarmsBasedOnStandbyBuckets(filterPackages)) {
4771                             rescheduleKernelAlarmsLocked();
4772                             updateNextAlarmClockLocked();
4773                         }
4774                     }
4775                     break;
4776 
4777                 case REMOVE_FOR_CANCELED:
4778                     final PendingIntent operation = (PendingIntent) msg.obj;
4779                     synchronized (mLock) {
4780                         removeLocked(operation, null, REMOVE_REASON_PI_CANCELLED);
4781                     }
4782                     break;
4783 
4784                 case REMOVE_EXACT_ALARMS:
4785                     int uid = msg.arg1;
4786                     String packageName = (String) msg.obj;
4787                     removeExactAlarmsOnPermissionRevoked(uid, packageName, /*killUid = */true);
4788                     break;
4789                 case REFRESH_EXACT_ALARM_CANDIDATES:
4790                     refreshExactAlarmCandidates();
4791                     break;
4792                 case CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE:
4793                     packageName = (String) msg.obj;
4794                     uid = msg.arg1;
4795                     if (!hasScheduleExactAlarmInternal(packageName, uid)
4796                             && !hasUseExactAlarmInternal(packageName, uid)) {
4797                         removeExactAlarmsOnPermissionRevoked(uid, packageName, /*killUid = */false);
4798                     }
4799                     break;
4800                 case REMOVE_EXACT_LISTENER_ALARMS_ON_CACHED:
4801                     uid = (Integer) msg.obj;
4802                     removeExactListenerAlarms(uid);
4803                     break;
4804                 default:
4805                     // nope, just ignore it
4806                     break;
4807             }
4808         }
4809     }
4810 
4811     @VisibleForTesting
4812     class ChargingReceiver extends BroadcastReceiver {
ChargingReceiver()4813         ChargingReceiver() {
4814             IntentFilter filter = new IntentFilter();
4815             filter.addAction(BatteryManager.ACTION_CHARGING);
4816             filter.addAction(BatteryManager.ACTION_DISCHARGING);
4817             getContext().registerReceiver(this, filter);
4818         }
4819 
4820         @Override
onReceive(Context context, Intent intent)4821         public void onReceive(Context context, Intent intent) {
4822             final String action = intent.getAction();
4823             final boolean charging;
4824             if (BatteryManager.ACTION_CHARGING.equals(action)) {
4825                 if (DEBUG_STANDBY) {
4826                     Slog.d(TAG, "Device is charging.");
4827                 }
4828                 charging = true;
4829             } else {
4830                 if (DEBUG_STANDBY) {
4831                     Slog.d(TAG, "Disconnected from power.");
4832                 }
4833                 charging = false;
4834             }
4835             mHandler.removeMessages(AlarmHandler.CHARGING_STATUS_CHANGED);
4836             mHandler.obtainMessage(AlarmHandler.CHARGING_STATUS_CHANGED, charging)
4837                     .sendToTarget();
4838         }
4839     }
4840 
4841     @VisibleForTesting
4842     class ClockReceiver extends BroadcastReceiver {
ClockReceiver()4843         public ClockReceiver() {
4844             IntentFilter filter = new IntentFilter();
4845             filter.addAction(Intent.ACTION_DATE_CHANGED);
4846             getContext().registerReceiver(this, filter);
4847         }
4848 
4849         @Override
onReceive(Context context, Intent intent)4850         public void onReceive(Context context, Intent intent) {
4851             if (intent.getAction().equals(Intent.ACTION_DATE_CHANGED)) {
4852                 scheduleDateChangedEvent();
4853             }
4854         }
4855 
scheduleTimeTickEvent()4856         public void scheduleTimeTickEvent() {
4857             final long currentTime = mInjector.getCurrentTimeMillis();
4858             final long nextTime = 60000 * ((currentTime / 60000) + 1);
4859 
4860             // Schedule this event for the amount of time that it would take to get to
4861             // the top of the next minute.
4862             final long tickEventDelay = nextTime - currentTime;
4863 
4864             final WorkSource workSource = null; // Let system take blame for time tick events.
4865 
4866             int flags = AlarmManager.FLAG_STANDALONE;
4867             flags |= mConstants.TIME_TICK_ALLOWED_WHILE_IDLE ? FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED
4868                     : 0;
4869 
4870             setImpl(ELAPSED_REALTIME, mInjector.getElapsedRealtimeMillis() + tickEventDelay, 0,
4871                     0, null, mTimeTickTrigger, TIME_TICK_TAG, flags, workSource, null,
4872                     Process.myUid(), "android", null, EXACT_ALLOW_REASON_ALLOW_LIST);
4873 
4874             // Finally, remember when we set the tick alarm
4875             synchronized (mLock) {
4876                 mLastTickSet = currentTime;
4877             }
4878         }
4879 
scheduleDateChangedEvent()4880         public void scheduleDateChangedEvent() {
4881             Calendar calendar = Calendar.getInstance();
4882             calendar.setTimeInMillis(mInjector.getCurrentTimeMillis());
4883             calendar.set(Calendar.HOUR_OF_DAY, 0);
4884             calendar.set(Calendar.MINUTE, 0);
4885             calendar.set(Calendar.SECOND, 0);
4886             calendar.set(Calendar.MILLISECOND, 0);
4887             calendar.add(Calendar.DAY_OF_MONTH, 1);
4888 
4889             final WorkSource workSource = null; // Let system take blame for date change events.
4890             setImpl(RTC, calendar.getTimeInMillis(), 0, 0, mDateChangeSender, null, null,
4891                     AlarmManager.FLAG_STANDALONE, workSource, null,
4892                     Process.myUid(), "android", null, EXACT_ALLOW_REASON_ALLOW_LIST);
4893         }
4894     }
4895 
4896     class InteractiveStateReceiver extends BroadcastReceiver {
InteractiveStateReceiver()4897         public InteractiveStateReceiver() {
4898             IntentFilter filter = new IntentFilter();
4899             filter.addAction(Intent.ACTION_SCREEN_OFF);
4900             filter.addAction(Intent.ACTION_SCREEN_ON);
4901             filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
4902             getContext().registerReceiver(this, filter);
4903         }
4904 
4905         @Override
onReceive(Context context, Intent intent)4906         public void onReceive(Context context, Intent intent) {
4907             synchronized (mLock) {
4908                 interactiveStateChangedLocked(Intent.ACTION_SCREEN_ON.equals(intent.getAction()));
4909             }
4910         }
4911     }
4912 
4913     class UninstallReceiver extends BroadcastReceiver {
UninstallReceiver()4914         public UninstallReceiver() {
4915             IntentFilter filter = new IntentFilter();
4916             filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
4917             filter.addAction(Intent.ACTION_PACKAGE_ADDED);
4918             filter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
4919             filter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4920             filter.addDataScheme(IntentFilter.SCHEME_PACKAGE);
4921             getContext().registerReceiverForAllUsers(this, filter,
4922                     /* broadcastPermission */ null, /* scheduler */ null);
4923             // Register for events related to sdcard installation.
4924             IntentFilter sdFilter = new IntentFilter();
4925             sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
4926             sdFilter.addAction(Intent.ACTION_USER_STOPPED);
4927             if (mStartUserBeforeScheduledAlarms) {
4928                 sdFilter.addAction(Intent.ACTION_LOCKED_BOOT_COMPLETED);
4929                 sdFilter.addAction(Intent.ACTION_USER_REMOVED);
4930             }
4931             sdFilter.addAction(Intent.ACTION_UID_REMOVED);
4932             getContext().registerReceiverForAllUsers(this, sdFilter,
4933                     /* broadcastPermission */ null, /* scheduler */ null);
4934         }
4935 
4936         @Override
onReceive(Context context, Intent intent)4937         public void onReceive(Context context, Intent intent) {
4938             final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
4939             synchronized (mLock) {
4940                 String pkgList[] = null;
4941                 switch (intent.getAction()) {
4942                     case Intent.ACTION_QUERY_PACKAGE_RESTART:
4943                         pkgList = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4944                         for (String packageName : pkgList) {
4945                             if (lookForPackageLocked(packageName, uid)) {
4946                                 setResultCode(Activity.RESULT_OK);
4947                                 return;
4948                             }
4949                         }
4950                         return;
4951                     case Intent.ACTION_USER_STOPPED:
4952                         final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
4953                         if (userHandle >= 0) {
4954                             removeUserLocked(userHandle);
4955                             mAppWakeupHistory.removeForUser(userHandle);
4956                             mAllowWhileIdleHistory.removeForUser(userHandle);
4957                             mAllowWhileIdleCompatHistory.removeForUser(userHandle);
4958                             mTemporaryQuotaReserve.removeForUser(userHandle);
4959                         }
4960                         return;
4961                     case Intent.ACTION_LOCKED_BOOT_COMPLETED:
4962                         final int handle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
4963                         if (handle >= 0) {
4964                             if (mStartUserBeforeScheduledAlarms) {
4965                                 mUserWakeupStore.onUserStarted(handle);
4966                             }
4967                         }
4968                         return;
4969                     case Intent.ACTION_USER_REMOVED:
4970                         final int user = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
4971                         if (user >= 0) {
4972                             if (mStartUserBeforeScheduledAlarms) {
4973                                 mUserWakeupStore.onUserRemoved(user);
4974                             }
4975                         }
4976                         return;
4977                     case Intent.ACTION_UID_REMOVED:
4978                         mLastPriorityAlarmDispatch.delete(uid);
4979                         mRemovalHistory.delete(uid);
4980                         mLastOpScheduleExactAlarm.delete(uid);
4981                         return;
4982                     case Intent.ACTION_PACKAGE_ADDED:
4983                         mHandler.sendEmptyMessage(AlarmHandler.REFRESH_EXACT_ALARM_CANDIDATES);
4984                         if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
4985                             // Some apps may lose permission to set exact alarms on update.
4986                             // We need to remove their exact alarms.
4987                             final String packageUpdated = intent.getData().getSchemeSpecificPart();
4988                             mHandler.obtainMessage(
4989                                     AlarmHandler.CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE, uid, -1,
4990                                     packageUpdated).sendToTarget();
4991                         }
4992                         return;
4993                     case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
4994                         pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
4995                         break;
4996                     case Intent.ACTION_PACKAGE_REMOVED:
4997                         if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
4998                             // This package is being updated; don't kill its alarms.
4999                             // We will refresh the exact alarm candidates on subsequent receipt of
5000                             // PACKAGE_ADDED.
5001                             return;
5002                         }
5003                         mHandler.sendEmptyMessage(AlarmHandler.REFRESH_EXACT_ALARM_CANDIDATES);
5004                         // Intentional fall-through.
5005                     case Intent.ACTION_PACKAGE_RESTARTED:
5006                         final Uri data = intent.getData();
5007                         if (data != null) {
5008                             final String pkg = data.getSchemeSpecificPart();
5009                             if (pkg != null) {
5010                                 pkgList = new String[]{pkg};
5011                             }
5012                         }
5013                         break;
5014                 }
5015                 if (pkgList != null && (pkgList.length > 0)) {
5016                     for (String pkg : pkgList) {
5017                         if (uid >= 0) {
5018                             // package-removed and package-restarted case
5019                             mAppWakeupHistory.removeForPackage(pkg, UserHandle.getUserId(uid));
5020                             mAllowWhileIdleHistory.removeForPackage(pkg, UserHandle.getUserId(uid));
5021                             mAllowWhileIdleCompatHistory.removeForPackage(pkg,
5022                                     UserHandle.getUserId(uid));
5023                             mTemporaryQuotaReserve.removeForPackage(pkg, UserHandle.getUserId(uid));
5024                             removeLocked(uid, REMOVE_REASON_UNDEFINED);
5025                         } else {
5026                             // external-applications-unavailable case
5027                             removeLocked(pkg, REMOVE_REASON_UNDEFINED);
5028                         }
5029                         for (int i = mBroadcastStats.size() - 1; i >= 0; i--) {
5030                             ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(i);
5031                             if (uidStats.remove(pkg) != null) {
5032                                 if (uidStats.size() <= 0) {
5033                                     mBroadcastStats.removeAt(i);
5034                                 }
5035                             }
5036                         }
5037                     }
5038                 }
5039             }
5040         }
5041     }
5042 
5043     /**
5044      * Tracking of app assignments to standby buckets
5045      */
5046     private final class AppStandbyTracker extends AppIdleStateChangeListener {
5047         @Override
onAppIdleStateChanged(final String packageName, final @UserIdInt int userId, boolean idle, int bucket, int reason)5048         public void onAppIdleStateChanged(final String packageName, final @UserIdInt int userId,
5049                 boolean idle, int bucket, int reason) {
5050             if (DEBUG_STANDBY) {
5051                 Slog.d(TAG, "Package " + packageName + " for user " + userId + " now in bucket " +
5052                         bucket);
5053             }
5054             mHandler.obtainMessage(AlarmHandler.APP_STANDBY_BUCKET_CHANGED, userId, -1, packageName)
5055                     .sendToTarget();
5056         }
5057 
5058         @Override
triggerTemporaryQuotaBump(String packageName, int userId)5059         public void triggerTemporaryQuotaBump(String packageName, int userId) {
5060             final int quotaBump;
5061             synchronized (mLock) {
5062                 quotaBump = mConstants.TEMPORARY_QUOTA_BUMP;
5063             }
5064             if (quotaBump <= 0) {
5065                 return;
5066             }
5067             final int uid = mPackageManagerInternal.getPackageUid(packageName, 0, userId);
5068             if (uid < 0 || UserHandle.isCore(uid)) {
5069                 return;
5070             }
5071             if (DEBUG_STANDBY) {
5072                 Slog.d(TAG, "Bumping quota temporarily for " + packageName + " for user " + userId);
5073             }
5074             synchronized (mLock) {
5075                 mTemporaryQuotaReserve.replenishQuota(packageName, userId, quotaBump,
5076                         mInjector.getElapsedRealtimeMillis());
5077             }
5078             mHandler.obtainMessage(AlarmHandler.TEMPORARY_QUOTA_CHANGED, userId, -1,
5079                     packageName).sendToTarget();
5080         }
5081     }
5082 
5083     private final Listener mForceAppStandbyListener = new Listener() {
5084 
5085         @Override
5086         public void updateAllAlarms() {
5087             // Called when:
5088             // 1. Power exemption list changes,
5089             // 2. Battery saver state is toggled,
5090             // 3. Any package is moved into or out of the EXEMPTED bucket.
5091             synchronized (mLock) {
5092                 if (mAlarmStore.updateAlarmDeliveries(
5093                         a -> adjustDeliveryTimeBasedOnBatterySaver(a))) {
5094                     rescheduleKernelAlarmsLocked();
5095                 }
5096             }
5097         }
5098 
5099         @Override
5100         public void updateAlarmsForUid(int uid) {
5101             // Called when the given uid's state switches b/w active and idle.
5102             synchronized (mLock) {
5103                 if (mAlarmStore.updateAlarmDeliveries(a -> {
5104                     if (a.creatorUid != uid) {
5105                         return false;
5106                     }
5107                     return adjustDeliveryTimeBasedOnBatterySaver(a);
5108                 })) {
5109                     rescheduleKernelAlarmsLocked();
5110                 }
5111             }
5112         }
5113 
5114         @Override
5115         public void unblockAllUnrestrictedAlarms() {
5116             // Called when the power exemption list changes.
5117             synchronized (mLock) {
5118                 sendAllUnrestrictedPendingBackgroundAlarmsLocked();
5119             }
5120         }
5121 
5122         @Override
5123         public void unblockAlarmsForUid(int uid) {
5124             synchronized (mLock) {
5125                 // Called when the given uid becomes active.
5126                 sendPendingBackgroundAlarmsLocked(uid, null);
5127             }
5128         }
5129 
5130         @Override
5131         public void unblockAlarmsForUidPackage(int uid, String packageName) {
5132             // Called when user turns off FAS for this (uid, package).
5133             synchronized (mLock) {
5134                 sendPendingBackgroundAlarmsLocked(uid, packageName);
5135             }
5136         }
5137 
5138         @Override
5139         public void removeAlarmsForUid(int uid) {
5140             synchronized (mLock) {
5141                 removeForStoppedLocked(uid);
5142             }
5143         }
5144 
5145         @Override
5146         public void handleUidCachedChanged(int uid, boolean cached) {
5147             if (mUseFrozenStateToDropListenerAlarms) {
5148                 // Use ActivityManager#UidFrozenStateChangedCallback instead.
5149                 return;
5150             }
5151             if (!CompatChanges.isChangeEnabled(EXACT_LISTENER_ALARMS_DROPPED_ON_CACHED, uid)) {
5152                 return;
5153             }
5154             // Apps can quickly get frozen after being cached, breaking the exactness guarantee on
5155             // listener alarms. So going forward, the contract of exact listener alarms explicitly
5156             // states that they will be removed as soon as the app goes out of lifecycle. We still
5157             // allow a short grace period for quick shuffling of proc-states that may happen
5158             // unexpectedly when switching between different lifecycles and is generally hard for
5159             // apps to avoid.
5160 
5161             final long delay;
5162             synchronized (mLock) {
5163                 delay = mConstants.CACHED_LISTENER_REMOVAL_DELAY;
5164             }
5165             final Integer uidObj = uid;
5166 
5167             if (cached && !mHandler.hasEqualMessages(REMOVE_EXACT_LISTENER_ALARMS_ON_CACHED,
5168                     uidObj)) {
5169                 mHandler.sendMessageDelayed(
5170                         mHandler.obtainMessage(REMOVE_EXACT_LISTENER_ALARMS_ON_CACHED, uidObj),
5171                         delay);
5172             } else {
5173                 mHandler.removeEqualMessages(REMOVE_EXACT_LISTENER_ALARMS_ON_CACHED, uidObj);
5174             }
5175         }
5176     };
5177 
getStatsLocked(PendingIntent pi)5178     private final BroadcastStats getStatsLocked(PendingIntent pi) {
5179         String pkg = pi.getCreatorPackage();
5180         int uid = pi.getCreatorUid();
5181         return getStatsLocked(uid, pkg);
5182     }
5183 
getStatsLocked(int uid, String pkgName)5184     private final BroadcastStats getStatsLocked(int uid, String pkgName) {
5185         ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.get(uid);
5186         if (uidStats == null) {
5187             uidStats = new ArrayMap<String, BroadcastStats>();
5188             mBroadcastStats.put(uid, uidStats);
5189         }
5190         BroadcastStats bs = uidStats.get(pkgName);
5191         if (bs == null) {
5192             bs = new BroadcastStats(uid, pkgName);
5193             uidStats.put(pkgName, bs);
5194         }
5195         return bs;
5196     }
5197 
5198     /**
5199      * Canonical count of (operation.send() - onSendFinished()) and
5200      * listener send/complete/timeout invocations.
5201      * Guarded by the usual lock.
5202      */
5203     @GuardedBy("mLock")
5204     private int mSendCount = 0;
5205     @GuardedBy("mLock")
5206     private int mSendFinishCount = 0;
5207     @GuardedBy("mLock")
5208     private int mListenerCount = 0;
5209     @GuardedBy("mLock")
5210     private int mListenerFinishCount = 0;
5211 
5212     class DeliveryTracker extends IAlarmCompleteListener.Stub implements PendingIntent.OnFinished {
5213 
5214         @GuardedBy("mLock")
removeLocked(PendingIntent pi, Intent intent)5215         private InFlight removeLocked(PendingIntent pi, Intent intent) {
5216             for (int i = 0; i < mInFlight.size(); i++) {
5217                 final InFlight inflight = mInFlight.get(i);
5218                 if (inflight.mPendingIntent == pi) {
5219                     if (pi.isBroadcast()) {
5220                         notifyBroadcastAlarmCompleteLocked(inflight.mUid);
5221                     }
5222                     return mInFlight.remove(i);
5223                 }
5224             }
5225             mLog.w("No in-flight alarm for " + pi + " " + intent);
5226             return null;
5227         }
5228 
5229         @GuardedBy("mLock")
removeLocked(IBinder listener)5230         private InFlight removeLocked(IBinder listener) {
5231             for (int i = 0; i < mInFlight.size(); i++) {
5232                 if (mInFlight.get(i).mListener == listener) {
5233                     return mInFlight.remove(i);
5234                 }
5235             }
5236             mLog.w("No in-flight alarm for listener " + listener);
5237             return null;
5238         }
5239 
updateStatsLocked(InFlight inflight)5240         private void updateStatsLocked(InFlight inflight) {
5241             final long nowELAPSED = mInjector.getElapsedRealtimeMillis();
5242             BroadcastStats bs = inflight.mBroadcastStats;
5243             bs.nesting--;
5244             if (bs.nesting <= 0) {
5245                 bs.nesting = 0;
5246                 bs.aggregateTime += nowELAPSED - bs.startTime;
5247             }
5248             FilterStats fs = inflight.mFilterStats;
5249             fs.nesting--;
5250             if (fs.nesting <= 0) {
5251                 fs.nesting = 0;
5252                 fs.aggregateTime += nowELAPSED - fs.startTime;
5253             }
5254             if (RECORD_ALARMS_IN_HISTORY) {
5255                 mActivityManagerInternal.noteAlarmFinish(inflight.mPendingIntent,
5256                         inflight.mWorkSource, inflight.mUid, inflight.mTag);
5257             }
5258         }
5259 
updateTrackingLocked(InFlight inflight)5260         private void updateTrackingLocked(InFlight inflight) {
5261             if (inflight != null) {
5262                 updateStatsLocked(inflight);
5263             }
5264             mBroadcastRefCount--;
5265             if (DEBUG_WAKELOCK) {
5266                 Slog.d(TAG, "mBroadcastRefCount -> " + mBroadcastRefCount);
5267             }
5268             if (mBroadcastRefCount == 0) {
5269                 mHandler.obtainMessage(AlarmHandler.REPORT_ALARMS_ACTIVE, 0, 0).sendToTarget();
5270                 mWakeLock.release();
5271                 if (mInFlight.size() > 0) {
5272                     mLog.w("Finished all dispatches with " + mInFlight.size()
5273                             + " remaining inflights");
5274                     for (int i = 0; i < mInFlight.size(); i++) {
5275                         mLog.w("  Remaining #" + i + ": " + mInFlight.get(i));
5276                     }
5277                     mInFlight.clear();
5278                 }
5279             } else {
5280                 // the next of our alarms is now in flight.  reattribute the wakelock.
5281                 if (mInFlight.size() > 0) {
5282                     InFlight inFlight = mInFlight.get(0);
5283                     setWakelockWorkSource(inFlight.mWorkSource, inFlight.mCreatorUid, inFlight.mTag,
5284                             false);
5285                 } else {
5286                     // should never happen
5287                     mLog.w("Alarm wakelock still held but sent queue empty");
5288                     mWakeLock.setWorkSource(null);
5289                 }
5290             }
5291         }
5292 
5293         /**
5294          * Callback that arrives when a direct-call alarm reports that delivery has finished
5295          */
5296         @Override
alarmComplete(IBinder who)5297         public void alarmComplete(IBinder who) {
5298             if (who == null) {
5299                 mLog.w("Invalid alarmComplete: uid=" + Binder.getCallingUid()
5300                         + " pid=" + Binder.getCallingPid());
5301                 return;
5302             }
5303 
5304             final long ident = Binder.clearCallingIdentity();
5305             try {
5306                 synchronized (mLock) {
5307                     mHandler.removeMessages(AlarmHandler.LISTENER_TIMEOUT, who);
5308                     InFlight inflight = removeLocked(who);
5309                     if (inflight != null) {
5310                         if (DEBUG_LISTENER_CALLBACK) {
5311                             Slog.i(TAG, "alarmComplete() from " + who);
5312                         }
5313                         updateTrackingLocked(inflight);
5314                         mListenerFinishCount++;
5315                     } else {
5316                         // Delivery timed out, and the timeout handling already took care of
5317                         // updating our tracking here, so we needn't do anything further.
5318                         if (DEBUG_LISTENER_CALLBACK) {
5319                             Slog.i(TAG, "Late alarmComplete() from " + who);
5320                         }
5321                     }
5322                 }
5323             } finally {
5324                 Binder.restoreCallingIdentity(ident);
5325             }
5326         }
5327 
5328         /**
5329          * Callback that arrives when a PendingIntent alarm has finished delivery
5330          */
5331         @Override
onSendFinished(PendingIntent pi, Intent intent, int resultCode, String resultData, Bundle resultExtras)5332         public void onSendFinished(PendingIntent pi, Intent intent, int resultCode,
5333                 String resultData, Bundle resultExtras) {
5334             synchronized (mLock) {
5335                 mSendFinishCount++;
5336                 updateTrackingLocked(removeLocked(pi, intent));
5337             }
5338         }
5339 
5340         /**
5341          * Timeout of a direct-call alarm delivery
5342          */
alarmTimedOut(IBinder who)5343         public void alarmTimedOut(IBinder who) {
5344             synchronized (mLock) {
5345                 InFlight inflight = removeLocked(who);
5346                 if (inflight != null) {
5347                     // TODO: implement ANR policy for the target
5348                     if (DEBUG_LISTENER_CALLBACK) {
5349                         Slog.i(TAG, "Alarm listener " + who + " timed out in delivery");
5350                     }
5351                     updateTrackingLocked(inflight);
5352                     mListenerFinishCount++;
5353                 } else {
5354                     if (DEBUG_LISTENER_CALLBACK) {
5355                         Slog.i(TAG, "Spurious timeout of listener " + who);
5356                     }
5357                     mLog.w("Spurious timeout of listener " + who);
5358                 }
5359             }
5360         }
5361 
5362         /**
5363          * Deliver an alarm and set up the post-delivery handling appropriately
5364          */
5365         @GuardedBy("mLock")
deliverLocked(Alarm alarm, long nowELAPSED)5366         public void deliverLocked(Alarm alarm, long nowELAPSED) {
5367             final long workSourceToken = ThreadLocalWorkSource.setUid(
5368                     getAlarmAttributionUid(alarm));
5369             try {
5370                 if (alarm.operation != null) {
5371                     // PendingIntent alarm
5372                     mSendCount++;
5373 
5374                     try {
5375                         final Bundle bundle = getAlarmOperationBundle(alarm);
5376                         alarm.operation.send(getContext(), 0,
5377                                 mBackgroundIntent.putExtra(Intent.EXTRA_ALARM_COUNT, alarm.count),
5378                                 mDeliveryTracker, mHandler, null, bundle);
5379                     } catch (PendingIntent.CanceledException e) {
5380                         if (alarm.repeatInterval > 0) {
5381                             // This IntentSender is no longer valid, but this
5382                             // is a repeating alarm, so toss it
5383                             removeImpl(alarm.operation, null);
5384                         }
5385                         // No actual delivery was possible, so the delivery tracker's
5386                         // 'finished' callback won't be invoked.  We also don't need
5387                         // to do any wakelock or stats tracking, so we have nothing
5388                         // left to do here but go on to the next thing.
5389                         mSendFinishCount++;
5390                         return;
5391                     }
5392                 } else {
5393                     // Direct listener callback alarm
5394                     mListenerCount++;
5395 
5396                     alarm.listener.asBinder().unlinkToDeath(mListenerDeathRecipient, 0);
5397 
5398                     if (RECORD_ALARMS_IN_HISTORY) {
5399                         if (alarm.listener == mTimeTickTrigger) {
5400                             mTickHistory[mNextTickHistory++] = nowELAPSED;
5401                             if (mNextTickHistory >= TICK_HISTORY_DEPTH) {
5402                                 mNextTickHistory = 0;
5403                             }
5404                         }
5405                     }
5406 
5407                     try {
5408                         if (DEBUG_LISTENER_CALLBACK) {
5409                             Slog.v(TAG, "Alarm to uid=" + alarm.uid
5410                                     + " listener=" + alarm.listener.asBinder());
5411                         }
5412                         alarm.listener.doAlarm(this);
5413                         mHandler.sendMessageDelayed(
5414                                 mHandler.obtainMessage(AlarmHandler.LISTENER_TIMEOUT,
5415                                         alarm.listener.asBinder()),
5416                                 mConstants.LISTENER_TIMEOUT);
5417                     } catch (Exception e) {
5418                         if (DEBUG_LISTENER_CALLBACK) {
5419                             Slog.i(TAG, "Alarm undeliverable to listener "
5420                                     + alarm.listener.asBinder(), e);
5421                         }
5422                         // As in the PendingIntent.CanceledException case, delivery of the
5423                         // alarm was not possible, so we have no wakelock or timeout or
5424                         // stats management to do.  It threw before we posted the delayed
5425                         // timeout message, so we're done here.
5426                         mListenerFinishCount++;
5427                         return;
5428                     }
5429                 }
5430             } finally {
5431                 ThreadLocalWorkSource.restore(workSourceToken);
5432             }
5433 
5434             // The alarm is now in flight; now arrange wakelock and stats tracking
5435             if (DEBUG_WAKELOCK) {
5436                 Slog.d(TAG, "mBroadcastRefCount -> " + (mBroadcastRefCount + 1));
5437             }
5438             if (mBroadcastRefCount == 0) {
5439                 setWakelockWorkSource(alarm.workSource, alarm.creatorUid, alarm.statsTag, true);
5440                 mWakeLock.acquire();
5441                 mHandler.obtainMessage(AlarmHandler.REPORT_ALARMS_ACTIVE, 1, 0).sendToTarget();
5442             }
5443             final InFlight inflight = new InFlight(AlarmManagerService.this, alarm, nowELAPSED);
5444             mInFlight.add(inflight);
5445             mBroadcastRefCount++;
5446             if (inflight.isBroadcast()) {
5447                 notifyBroadcastAlarmPendingLocked(alarm.uid);
5448             }
5449             final boolean doze = (mPendingIdleUntil != null);
5450             final boolean batterySaver = (mAppStateTracker != null
5451                     && mAppStateTracker.isForceAllAppsStandbyEnabled());
5452             if (doze || batterySaver) {
5453                 if (isAllowedWhileIdleRestricted(alarm)) {
5454                     // Record the last time this uid handled an ALLOW_WHILE_IDLE alarm while the
5455                     // device was in doze or battery saver.
5456                     final AppWakeupHistory history = ((alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0)
5457                             ? mAllowWhileIdleHistory
5458                             : mAllowWhileIdleCompatHistory;
5459                     history.recordAlarmForPackage(alarm.sourcePackage,
5460                             UserHandle.getUserId(alarm.creatorUid), nowELAPSED);
5461                     mAlarmStore.updateAlarmDeliveries(a -> {
5462                         if (a.creatorUid != alarm.creatorUid || !isAllowedWhileIdleRestricted(a)) {
5463                             return false;
5464                         }
5465                         final boolean dozeAdjusted = doze && adjustDeliveryTimeBasedOnDeviceIdle(a);
5466                         final boolean batterySaverAdjusted =
5467                                 batterySaver && adjustDeliveryTimeBasedOnBatterySaver(a);
5468                         return dozeAdjusted || batterySaverAdjusted;
5469                     });
5470                 } else if ((alarm.flags & FLAG_PRIORITIZE) != 0) {
5471                     mLastPriorityAlarmDispatch.put(alarm.creatorUid, nowELAPSED);
5472                     mAlarmStore.updateAlarmDeliveries(a -> {
5473                         if (a.creatorUid != alarm.creatorUid
5474                                 || (alarm.flags & FLAG_PRIORITIZE) == 0) {
5475                             return false;
5476                         }
5477                         final boolean dozeAdjusted = doze && adjustDeliveryTimeBasedOnDeviceIdle(a);
5478                         final boolean batterySaverAdjusted =
5479                                 batterySaver && adjustDeliveryTimeBasedOnBatterySaver(a);
5480                         return dozeAdjusted || batterySaverAdjusted;
5481                     });
5482                 }
5483                 if (RECORD_DEVICE_IDLE_ALARMS) {
5484                     IdleDispatchEntry ent = new IdleDispatchEntry();
5485                     ent.uid = alarm.uid;
5486                     ent.pkg = alarm.packageName;
5487                     ent.tag = alarm.statsTag;
5488                     ent.op = "DELIVER";
5489                     ent.elapsedRealtime = nowELAPSED;
5490                     mAllowWhileIdleDispatches.add(ent);
5491                 }
5492             }
5493             if (!isExemptFromAppStandby(alarm)) {
5494                 final int userId = UserHandle.getUserId(alarm.creatorUid);
5495                 if (alarm.mUsingReserveQuota) {
5496                     mTemporaryQuotaReserve.recordUsage(alarm.sourcePackage, userId, nowELAPSED);
5497                 } else {
5498                     mAppWakeupHistory.recordAlarmForPackage(alarm.sourcePackage, userId,
5499                             nowELAPSED);
5500                 }
5501             }
5502             final BroadcastStats bs = inflight.mBroadcastStats;
5503             bs.count++;
5504             if (bs.nesting == 0) {
5505                 bs.nesting = 1;
5506                 bs.startTime = nowELAPSED;
5507             } else {
5508                 bs.nesting++;
5509             }
5510             final FilterStats fs = inflight.mFilterStats;
5511             fs.count++;
5512             if (fs.nesting == 0) {
5513                 fs.nesting = 1;
5514                 fs.startTime = nowELAPSED;
5515             } else {
5516                 fs.nesting++;
5517             }
5518             if (alarm.type == ELAPSED_REALTIME_WAKEUP
5519                     || alarm.type == RTC_WAKEUP) {
5520                 bs.numWakeup++;
5521                 fs.numWakeup++;
5522                 mActivityManagerInternal.noteWakeupAlarm(
5523                         alarm.operation, alarm.workSource, alarm.uid, alarm.packageName,
5524                         alarm.statsTag);
5525             }
5526         }
5527     }
5528 
incrementAlarmCount(int uid)5529     private void incrementAlarmCount(int uid) {
5530         increment(mAlarmsPerUid, uid);
5531     }
5532 
5533     /**
5534      * Send {@link AlarmManager#ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED} to
5535      * the app that is just granted the permission.
5536      */
sendScheduleExactAlarmPermissionStateChangedBroadcast( String packageName, int userId)5537     private void sendScheduleExactAlarmPermissionStateChangedBroadcast(
5538             String packageName, int userId) {
5539         final Intent i = new Intent(
5540                 AlarmManager.ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED);
5541         i.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
5542                 | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
5543                 | Intent.FLAG_RECEIVER_FOREGROUND);
5544         i.setPackage(packageName);
5545 
5546         // We need to allow the app to start a foreground service.
5547         // This broadcast is very rare, so we do not cache the BroadcastOptions.
5548         final BroadcastOptions opts = BroadcastOptions.makeBasic();
5549         opts.setTemporaryAppAllowlist(
5550                 mActivityManagerInternal.getBootTimeTempAllowListDuration(),
5551                 TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
5552                 REASON_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED, "");
5553         getContext().sendBroadcastAsUser(i, UserHandle.of(userId), /*permission*/ null,
5554                 opts.toBundle());
5555     }
5556 
decrementAlarmCount(int uid, int decrement)5557     private void decrementAlarmCount(int uid, int decrement) {
5558         int oldCount = 0;
5559         final int uidIndex = mAlarmsPerUid.indexOfKey(uid);
5560         if (uidIndex >= 0) {
5561             oldCount = mAlarmsPerUid.valueAt(uidIndex);
5562             if (oldCount > decrement) {
5563                 mAlarmsPerUid.setValueAt(uidIndex, oldCount - decrement);
5564             } else {
5565                 mAlarmsPerUid.removeAt(uidIndex);
5566             }
5567         }
5568         if (oldCount < decrement) {
5569             Slog.wtf(TAG, "Attempt to decrement existing alarm count " + oldCount + " by "
5570                     + decrement + " for uid " + uid);
5571         }
5572     }
5573 
5574     private class ShellCmd extends ShellCommand {
5575 
getBinderService()5576         IAlarmManager getBinderService() {
5577             return IAlarmManager.Stub.asInterface(mService);
5578         }
5579 
5580         @Override
onCommand(String cmd)5581         public int onCommand(String cmd) {
5582             if (cmd == null) {
5583                 return handleDefaultCommands(cmd);
5584             }
5585 
5586             final PrintWriter pw = getOutPrintWriter();
5587             try {
5588                 switch (cmd) {
5589                     case "set-time":
5590                         final long millis = Long.parseLong(getNextArgRequired());
5591                         return (getBinderService().setTime(millis)) ? 0 : -1;
5592                     case "set-timezone":
5593                         final String tz = getNextArgRequired();
5594                         getBinderService().setTimeZone(tz);
5595                         return 0;
5596                     case "get-config-version":
5597                         final int version = getBinderService().getConfigVersion();
5598                         pw.println(version);
5599                         return 0;
5600                     default:
5601                         return handleDefaultCommands(cmd);
5602                 }
5603             } catch (Exception e) {
5604                 pw.println(e);
5605             }
5606             return -1;
5607         }
5608 
5609         @Override
onHelp()5610         public void onHelp() {
5611             PrintWriter pw = getOutPrintWriter();
5612             pw.println("Alarm manager service (alarm) commands:");
5613             pw.println("  help");
5614             pw.println("    Print this help text.");
5615             pw.println("  set-time TIME");
5616             pw.println("    Set the system clock time to TIME where TIME is milliseconds");
5617             pw.println("    since the Epoch.");
5618             pw.println("  set-timezone TZ");
5619             pw.println("    Set the system timezone to TZ where TZ is an Olson id.");
5620             pw.println("  get-config-version");
5621             pw.println("    Returns an integer denoting the version of device_config keys the"
5622                     + " service is sync'ed to. As long as this returns the same version, the values"
5623                     + " of the config are guaranteed to remain the same.");
5624         }
5625     }
5626 }
5627