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