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