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