blob: c93f405012ca5b4e169ffa3b8b6477f0c7fa7491 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
17package com.android.server;
18
Jeff Sharkey9911a282018-02-14 22:29:11 -070019import static android.app.AlarmManager.ELAPSED_REALTIME;
20import static android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP;
21import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE;
22import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
23import static android.app.AlarmManager.RTC;
24import static android.app.AlarmManager.RTC_WAKEUP;
25
Suprabh Shukla75edab12018-01-29 14:09:06 -080026import android.annotation.UserIdInt;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080027import android.app.Activity;
Adrian Roosc42a1e12014-07-07 23:35:53 +020028import android.app.ActivityManager;
Christopher Tate57ceaaa2013-07-19 16:30:43 -070029import android.app.AlarmManager;
Christopher Tate14a7bb02015-10-01 10:24:31 -070030import android.app.AppOpsManager;
Dianne Hackborna750a632015-06-16 17:18:23 -070031import android.app.BroadcastOptions;
Christopher Tate14a7bb02015-10-01 10:24:31 -070032import android.app.IAlarmCompleteListener;
33import android.app.IAlarmListener;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.app.IAlarmManager;
Dianne Hackbornbef28fe2015-10-29 17:57:11 -070035import android.app.IUidObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036import android.app.PendingIntent;
Suprabh Shukla75edab12018-01-29 14:09:06 -080037import android.app.usage.UsageStatsManager;
38import android.app.usage.UsageStatsManagerInternal;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.content.BroadcastReceiver;
Dianne Hackborna750a632015-06-16 17:18:23 -070040import android.content.ContentResolver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.content.Context;
42import android.content.Intent;
43import android.content.IntentFilter;
Christopher Tatebb9cce52017-04-18 14:19:43 -070044import android.content.pm.ApplicationInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045import android.content.pm.PackageManager;
Christopher Tatebb9cce52017-04-18 14:19:43 -070046import android.content.pm.PackageManager.NameNotFoundException;
47import android.content.pm.PermissionInfo;
Dianne Hackborna750a632015-06-16 17:18:23 -070048import android.database.ContentObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049import android.net.Uri;
50import android.os.Binder;
51import android.os.Bundle;
Christopher Tate247571462017-04-10 11:45:05 -070052import android.os.Environment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053import android.os.Handler;
Adam Lesinski182f73f2013-12-05 16:48:06 -080054import android.os.IBinder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055import android.os.Message;
Jeff Sharkey9911a282018-02-14 22:29:11 -070056import android.os.ParcelableException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import android.os.PowerManager;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -070058import android.os.Process;
Dianne Hackbornbef28fe2015-10-29 17:57:11 -070059import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060import android.os.SystemClock;
61import android.os.SystemProperties;
Tim Murray175c0f92017-11-28 15:01:04 -080062import android.os.Trace;
Dianne Hackborn80a4af22012-08-27 19:18:31 -070063import android.os.UserHandle;
Christopher Tatec4a07d12012-04-06 14:19:13 -070064import android.os.WorkSource;
Adrian Roosc42a1e12014-07-07 23:35:53 +020065import android.provider.Settings;
Christopher Tate8b98ade2018-02-09 11:13:19 -080066import android.system.Os;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067import android.text.TextUtils;
Adrian Roosc42a1e12014-07-07 23:35:53 +020068import android.text.format.DateFormat;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -080069import android.util.ArrayMap;
Suprabh Shukla92994ab2018-01-31 17:39:30 -080070import android.util.ArraySet;
Dianne Hackborna750a632015-06-16 17:18:23 -070071import android.util.KeyValueListParser;
Adrian Roosc42a1e12014-07-07 23:35:53 +020072import android.util.Log;
Jeff Sharkey9911a282018-02-14 22:29:11 -070073import android.util.NtpTrustedTime;
Suprabh Shukla75edab12018-01-29 14:09:06 -080074import android.util.Pair;
Joe Onorato8a9b2202010-02-26 18:56:32 -080075import android.util.Slog;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -080076import android.util.SparseArray;
Adrian Roosc42a1e12014-07-07 23:35:53 +020077import android.util.SparseBooleanArray;
Dianne Hackborn3d1933c42015-06-10 16:25:57 -070078import android.util.SparseLongArray;
Dianne Hackborn043fcd92010-10-06 14:27:34 -070079import android.util.TimeUtils;
Kweku Adams61e03292017-10-19 14:27:12 -070080import android.util.proto.ProtoOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081
Jeff Sharkey9911a282018-02-14 22:29:11 -070082import com.android.internal.annotations.GuardedBy;
83import com.android.internal.annotations.VisibleForTesting;
84import com.android.internal.util.ArrayUtils;
85import com.android.internal.util.DumpUtils;
86import com.android.internal.util.LocalLog;
87import com.android.server.AppStateTracker.Listener;
88
Christopher Tate4cb338d2013-07-26 13:11:31 -070089import java.io.ByteArrayOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090import java.io.FileDescriptor;
91import java.io.PrintWriter;
Dianne Hackborn043fcd92010-10-06 14:27:34 -070092import java.text.SimpleDateFormat;
Jeff Sharkey9911a282018-02-14 22:29:11 -070093import java.time.DateTimeException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094import java.util.ArrayList;
Dianne Hackborn81038902012-11-26 17:04:09 -080095import java.util.Arrays;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096import java.util.Calendar;
97import java.util.Collections;
98import java.util.Comparator;
Mike Lockwood1f7b4132009-11-20 15:12:51 -050099import java.util.Date;
Christopher Tate1590f1e2014-10-02 17:27:57 -0700100import java.util.HashMap;
Christopher Tate18a75f12013-07-01 18:18:59 -0700101import java.util.LinkedList;
Adrian Roosc42a1e12014-07-07 23:35:53 +0200102import java.util.Locale;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700103import java.util.Random;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104import java.util.TimeZone;
John Spurlock604a5ee2015-06-01 12:27:22 -0400105import java.util.TreeSet;
Makoto Onuki2206af32017-11-21 16:25:35 -0800106import java.util.function.Predicate;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107
Makoto Onuki2206af32017-11-21 16:25:35 -0800108/**
109 * Alarm manager implementaion.
110 *
111 * Unit test:
112 atest $ANDROID_BUILD_TOP/frameworks/base/services/tests/servicestests/src/com/android/server/AlarmManagerServiceTest.java
113 */
Adam Lesinski182f73f2013-12-05 16:48:06 -0800114class AlarmManagerService extends SystemService {
Christopher Tatee0a22b32013-07-11 14:43:13 -0700115 private static final int RTC_WAKEUP_MASK = 1 << RTC_WAKEUP;
116 private static final int RTC_MASK = 1 << RTC;
Adam Lesinski182f73f2013-12-05 16:48:06 -0800117 private static final int ELAPSED_REALTIME_WAKEUP_MASK = 1 << ELAPSED_REALTIME_WAKEUP;
Christopher Tatee0a22b32013-07-11 14:43:13 -0700118 private static final int ELAPSED_REALTIME_MASK = 1 << ELAPSED_REALTIME;
Adam Lesinski182f73f2013-12-05 16:48:06 -0800119 static final int TIME_CHANGED_MASK = 1 << 16;
120 static final int IS_WAKEUP_MASK = RTC_WAKEUP_MASK|ELAPSED_REALTIME_WAKEUP_MASK;
Christopher Tateb8849c12011-02-08 13:39:01 -0800121
Christopher Tatee0a22b32013-07-11 14:43:13 -0700122 // Mask for testing whether a given alarm type is wakeup vs non-wakeup
Adam Lesinski182f73f2013-12-05 16:48:06 -0800123 static final int TYPE_NONWAKEUP_MASK = 0x1; // low bit => non-wakeup
Christopher Tateb8849c12011-02-08 13:39:01 -0800124
Adam Lesinski182f73f2013-12-05 16:48:06 -0800125 static final String TAG = "AlarmManager";
Adam Lesinski182f73f2013-12-05 16:48:06 -0800126 static final boolean localLOGV = false;
127 static final boolean DEBUG_BATCH = localLOGV || false;
128 static final boolean DEBUG_VALIDATE = localLOGV || false;
Adrian Roosc42a1e12014-07-07 23:35:53 +0200129 static final boolean DEBUG_ALARM_CLOCK = localLOGV || false;
Christopher Tate14a7bb02015-10-01 10:24:31 -0700130 static final boolean DEBUG_LISTENER_CALLBACK = localLOGV || false;
Makoto Onuki3e7d8452017-03-02 15:33:17 -0800131 static final boolean DEBUG_WAKELOCK = localLOGV || false;
Suprabh Shukladb6bf662017-08-30 15:41:53 -0700132 static final boolean DEBUG_BG_LIMIT = localLOGV || false;
Suprabh Shukla75edab12018-01-29 14:09:06 -0800133 static final boolean DEBUG_STANDBY = localLOGV || false;
Dianne Hackborn1e383822015-04-10 14:02:33 -0700134 static final boolean RECORD_ALARMS_IN_HISTORY = true;
Dianne Hackbornae78bf82015-10-26 13:33:20 -0700135 static final boolean RECORD_DEVICE_IDLE_ALARMS = false;
Adam Lesinski182f73f2013-12-05 16:48:06 -0800136 static final int ALARM_EVENT = 1;
137 static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
Adrian Roosc42a1e12014-07-07 23:35:53 +0200138
Christopher Tate14a7bb02015-10-01 10:24:31 -0700139 private final Intent mBackgroundIntent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800140 = new Intent().addFlags(Intent.FLAG_FROM_BACKGROUND);
Adam Lesinski182f73f2013-12-05 16:48:06 -0800141 static final IncreasingTimeOrder sIncreasingTimeOrder = new IncreasingTimeOrder();
Suprabh Shukladb6bf662017-08-30 15:41:53 -0700142
Adam Lesinski182f73f2013-12-05 16:48:06 -0800143 static final boolean WAKEUP_STATS = false;
Christopher Tate18a75f12013-07-01 18:18:59 -0700144
Christopher Tate24cd46f2016-02-02 14:28:01 -0800145 private static final Intent NEXT_ALARM_CLOCK_CHANGED_INTENT =
146 new Intent(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED)
Christopher Tate50191db2017-05-09 16:02:25 -0700147 .addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
148 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
Adrian Roosc42a1e12014-07-07 23:35:53 +0200149
Adam Lesinski182f73f2013-12-05 16:48:06 -0800150 final LocalLog mLog = new LocalLog(TAG);
Dianne Hackborn81038902012-11-26 17:04:09 -0800151
Christopher Tate14a7bb02015-10-01 10:24:31 -0700152 AppOpsManager mAppOps;
Dianne Hackborn627dfa12015-11-11 18:10:30 -0800153 DeviceIdleController.LocalService mLocalDeviceIdleController;
Suprabh Shukla75edab12018-01-29 14:09:06 -0800154 private UsageStatsManagerInternal mUsageStatsManagerInternal;
Christopher Tate14a7bb02015-10-01 10:24:31 -0700155
Adam Lesinski182f73f2013-12-05 16:48:06 -0800156 final Object mLock = new Object();
Dianne Hackborn81038902012-11-26 17:04:09 -0800157
Suprabh Shukladb6bf662017-08-30 15:41:53 -0700158 // List of alarms per uid deferred due to user applied background restrictions on the source app
159 SparseArray<ArrayList<Alarm>> mPendingBackgroundAlarms = new SparseArray<>();
Greg Hackmannf1bdbdd2013-12-17 11:56:22 -0800160 long mNativeData;
Christopher Tate0dab4dc2014-12-16 12:14:06 -0800161 private long mNextWakeup;
Christopher Tatee0a22b32013-07-11 14:43:13 -0700162 private long mNextNonWakeup;
Dianne Hackbornaa9a59d2016-05-23 15:59:18 -0700163 private long mLastWakeupSet;
164 private long mLastWakeup;
Christopher Tate8b98ade2018-02-09 11:13:19 -0800165 private long mLastTrigger;
Christopher Tate12cf0b62018-01-05 18:40:14 -0800166 private long mLastTickSet;
167 private long mLastTickIssued; // elapsed
168 private long mLastTickReceived;
Makoto Onuki5d93b832018-01-10 16:12:39 -0800169 private long mLastTickAdded;
170 private long mLastTickRemoved;
Adam Lesinski182f73f2013-12-05 16:48:06 -0800171 int mBroadcastRefCount = 0;
172 PowerManager.WakeLock mWakeLock;
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700173 boolean mLastWakeLockUnimportantForLogging;
Dianne Hackborn3d1933c42015-06-10 16:25:57 -0700174 ArrayList<Alarm> mPendingNonWakeupAlarms = new ArrayList<>();
175 ArrayList<InFlight> mInFlight = new ArrayList<>();
Adam Lesinski182f73f2013-12-05 16:48:06 -0800176 final AlarmHandler mHandler = new AlarmHandler();
177 ClockReceiver mClockReceiver;
Dianne Hackbornd4e6d462014-05-16 16:32:37 -0700178 InteractiveStateReceiver mInteractiveStateReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800179 private UninstallReceiver mUninstallReceiver;
Christopher Tate14a7bb02015-10-01 10:24:31 -0700180 final DeliveryTracker mDeliveryTracker = new DeliveryTracker();
Adam Lesinski182f73f2013-12-05 16:48:06 -0800181 PendingIntent mTimeTickSender;
182 PendingIntent mDateChangeSender;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700183 Random mRandom;
Dianne Hackbornd4e6d462014-05-16 16:32:37 -0700184 boolean mInteractive = true;
185 long mNonInteractiveStartTime;
186 long mNonInteractiveTime;
187 long mLastAlarmDeliveryTime;
188 long mStartCurrentDelayTime;
189 long mNextNonWakeupDeliveryTime;
Dianne Hackbornc3527222015-05-13 14:03:20 -0700190 long mLastTimeChangeClockTime;
191 long mLastTimeChangeRealtime;
Dianne Hackborn998e6082014-09-11 19:13:23 -0700192 int mNumTimeChanged;
Dianne Hackborn81038902012-11-26 17:04:09 -0800193
Christopher Tatebb9cce52017-04-18 14:19:43 -0700194 // Bookkeeping about the identity of the "System UI" package, determined at runtime.
195
196 /**
197 * This permission must be defined by the canonical System UI package,
198 * with protection level "signature".
199 */
200 private static final String SYSTEM_UI_SELF_PERMISSION =
201 "android.permission.systemui.IDENTITY";
202
203 /**
204 * At boot we use SYSTEM_UI_SELF_PERMISSION to look up the definer's uid.
205 */
206 int mSystemUiUid;
207
Dianne Hackborn3d1933c42015-06-10 16:25:57 -0700208 /**
209 * For each uid, this is the last time we dispatched an "allow while idle" alarm,
Kweku Adams61e03292017-10-19 14:27:12 -0700210 * used to determine the earliest we can dispatch the next such alarm. Times are in the
211 * 'elapsed' timebase.
Dianne Hackborn3d1933c42015-06-10 16:25:57 -0700212 */
213 final SparseLongArray mLastAllowWhileIdleDispatch = new SparseLongArray();
214
Suprabh Shuklac25447d2018-01-19 16:43:35 -0800215 /**
216 * For each uid, we store whether the last allow-while-idle alarm was dispatched while
217 * the uid was in foreground or not. We will use the allow_while_idle_short_time in such cases.
218 */
219 final SparseBooleanArray mUseAllowWhileIdleShortTime = new SparseBooleanArray();
220
Dianne Hackbornae78bf82015-10-26 13:33:20 -0700221 final static class IdleDispatchEntry {
222 int uid;
223 String pkg;
224 String tag;
225 String op;
226 long elapsedRealtime;
227 long argRealtime;
228 }
229 final ArrayList<IdleDispatchEntry> mAllowWhileIdleDispatches = new ArrayList();
230
Suprabh Shukla75edab12018-01-29 14:09:06 -0800231 interface Stats {
232 int REBATCH_ALL_ALARMS = 0;
Suprabh Shukla92994ab2018-01-31 17:39:30 -0800233 int REORDER_ALARMS_FOR_STANDBY = 1;
Suprabh Shukla75edab12018-01-29 14:09:06 -0800234 }
235
236 private final StatLogger mStatLogger = new StatLogger(new String[] {
237 "REBATCH_ALL_ALARMS",
Suprabh Shukla92994ab2018-01-31 17:39:30 -0800238 "REORDER_ALARMS_FOR_STANDBY",
Suprabh Shukla75edab12018-01-29 14:09:06 -0800239 });
240
Dianne Hackborna750a632015-06-16 17:18:23 -0700241 /**
242 * Broadcast options to use for FLAG_ALLOW_WHILE_IDLE.
243 */
244 Bundle mIdleOptions;
245
Jose Lima235510e2014-08-13 12:50:01 -0700246 private final SparseArray<AlarmManager.AlarmClockInfo> mNextAlarmClockForUser =
247 new SparseArray<>();
248 private final SparseArray<AlarmManager.AlarmClockInfo> mTmpSparseAlarmClockArray =
249 new SparseArray<>();
Adrian Roosc42a1e12014-07-07 23:35:53 +0200250 private final SparseBooleanArray mPendingSendNextAlarmClockChangedForUser =
251 new SparseBooleanArray();
252 private boolean mNextAlarmClockMayChange;
253
254 // May only use on mHandler's thread, locking not required.
Jose Lima235510e2014-08-13 12:50:01 -0700255 private final SparseArray<AlarmManager.AlarmClockInfo> mHandlerSparseAlarmClockArray =
256 new SparseArray<>();
Adrian Roosc42a1e12014-07-07 23:35:53 +0200257
Makoto Onukie4918212018-02-06 11:30:15 -0800258 private AppStateTracker mAppStateTracker;
Suprabh Shukla75edab12018-01-29 14:09:06 -0800259 private boolean mAppStandbyParole;
260 private ArrayMap<Pair<String, Integer>, Long> mLastAlarmDeliveredForPackage = new ArrayMap<>();
Makoto Onuki2206af32017-11-21 16:25:35 -0800261
Dianne Hackborna750a632015-06-16 17:18:23 -0700262 /**
263 * All times are in milliseconds. These constants are kept synchronized with the system
264 * global Settings. Any access to this class or its fields should be done while
265 * holding the AlarmManagerService.mLock lock.
266 */
267 private final class Constants extends ContentObserver {
268 // Key names stored in the settings value.
269 private static final String KEY_MIN_FUTURITY = "min_futurity";
270 private static final String KEY_MIN_INTERVAL = "min_interval";
271 private static final String KEY_ALLOW_WHILE_IDLE_SHORT_TIME = "allow_while_idle_short_time";
272 private static final String KEY_ALLOW_WHILE_IDLE_LONG_TIME = "allow_while_idle_long_time";
273 private static final String KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION
274 = "allow_while_idle_whitelist_duration";
Christopher Tate14a7bb02015-10-01 10:24:31 -0700275 private static final String KEY_LISTENER_TIMEOUT = "listener_timeout";
Dianne Hackborna750a632015-06-16 17:18:23 -0700276
Suprabh Shukla75edab12018-01-29 14:09:06 -0800277 // Keys for specifying throttling delay based on app standby bucketing
278 private final String[] KEYS_APP_STANDBY_DELAY = {
279 "standby_active_delay",
280 "standby_working_delay",
281 "standby_frequent_delay",
282 "standby_rare_delay",
283 "standby_never_delay",
284 };
285
Dianne Hackborna750a632015-06-16 17:18:23 -0700286 private static final long DEFAULT_MIN_FUTURITY = 5 * 1000;
287 private static final long DEFAULT_MIN_INTERVAL = 60 * 1000;
Christopher Tateaa244da2015-08-27 15:57:57 -0700288 private static final long DEFAULT_ALLOW_WHILE_IDLE_SHORT_TIME = DEFAULT_MIN_FUTURITY;
Dianne Hackborn7682b262015-10-26 17:51:57 -0700289 private static final long DEFAULT_ALLOW_WHILE_IDLE_LONG_TIME = 9*60*1000;
Dianne Hackborna750a632015-06-16 17:18:23 -0700290 private static final long DEFAULT_ALLOW_WHILE_IDLE_WHITELIST_DURATION = 10*1000;
Christopher Tate14a7bb02015-10-01 10:24:31 -0700291 private static final long DEFAULT_LISTENER_TIMEOUT = 5 * 1000;
Suprabh Shukla75edab12018-01-29 14:09:06 -0800292 private final long[] DEFAULT_APP_STANDBY_DELAYS = {
293 0, // Active
294 6 * 60_000, // Working
295 30 * 60_000, // Frequent
296 2 * 60 * 60_000, // Rare
297 10 * 24 * 60 * 60_000 // Never
298 };
Christopher Tate14a7bb02015-10-01 10:24:31 -0700299
Dianne Hackborna750a632015-06-16 17:18:23 -0700300 // Minimum futurity of a new alarm
301 public long MIN_FUTURITY = DEFAULT_MIN_FUTURITY;
302
303 // Minimum alarm recurrence interval
304 public long MIN_INTERVAL = DEFAULT_MIN_INTERVAL;
305
306 // Minimum time between ALLOW_WHILE_IDLE alarms when system is not idle.
307 public long ALLOW_WHILE_IDLE_SHORT_TIME = DEFAULT_ALLOW_WHILE_IDLE_SHORT_TIME;
308
309 // Minimum time between ALLOW_WHILE_IDLE alarms when system is idling.
310 public long ALLOW_WHILE_IDLE_LONG_TIME = DEFAULT_ALLOW_WHILE_IDLE_LONG_TIME;
311
312 // BroadcastOptions.setTemporaryAppWhitelistDuration() to use for FLAG_ALLOW_WHILE_IDLE.
313 public long ALLOW_WHILE_IDLE_WHITELIST_DURATION
314 = DEFAULT_ALLOW_WHILE_IDLE_WHITELIST_DURATION;
315
Christopher Tate14a7bb02015-10-01 10:24:31 -0700316 // Direct alarm listener callback timeout
317 public long LISTENER_TIMEOUT = DEFAULT_LISTENER_TIMEOUT;
318
Suprabh Shukla75edab12018-01-29 14:09:06 -0800319 public long[] APP_STANDBY_MIN_DELAYS = new long[DEFAULT_APP_STANDBY_DELAYS.length];
320
Dianne Hackborna750a632015-06-16 17:18:23 -0700321 private ContentResolver mResolver;
322 private final KeyValueListParser mParser = new KeyValueListParser(',');
323 private long mLastAllowWhileIdleWhitelistDuration = -1;
324
325 public Constants(Handler handler) {
326 super(handler);
Dianne Hackborna750a632015-06-16 17:18:23 -0700327 updateAllowWhileIdleWhitelistDurationLocked();
328 }
329
330 public void start(ContentResolver resolver) {
331 mResolver = resolver;
332 mResolver.registerContentObserver(Settings.Global.getUriFor(
333 Settings.Global.ALARM_MANAGER_CONSTANTS), false, this);
334 updateConstants();
335 }
336
Dianne Hackborna750a632015-06-16 17:18:23 -0700337 public void updateAllowWhileIdleWhitelistDurationLocked() {
338 if (mLastAllowWhileIdleWhitelistDuration != ALLOW_WHILE_IDLE_WHITELIST_DURATION) {
339 mLastAllowWhileIdleWhitelistDuration = ALLOW_WHILE_IDLE_WHITELIST_DURATION;
340 BroadcastOptions opts = BroadcastOptions.makeBasic();
341 opts.setTemporaryAppWhitelistDuration(ALLOW_WHILE_IDLE_WHITELIST_DURATION);
342 mIdleOptions = opts.toBundle();
343 }
344 }
345
346 @Override
347 public void onChange(boolean selfChange, Uri uri) {
348 updateConstants();
349 }
350
351 private void updateConstants() {
352 synchronized (mLock) {
353 try {
354 mParser.setString(Settings.Global.getString(mResolver,
355 Settings.Global.ALARM_MANAGER_CONSTANTS));
356 } catch (IllegalArgumentException e) {
357 // Failed to parse the settings string, log this and move on
358 // with defaults.
Dianne Hackborn0ef403e2017-01-24 18:22:15 -0800359 Slog.e(TAG, "Bad alarm manager settings", e);
Dianne Hackborna750a632015-06-16 17:18:23 -0700360 }
361
362 MIN_FUTURITY = mParser.getLong(KEY_MIN_FUTURITY, DEFAULT_MIN_FUTURITY);
363 MIN_INTERVAL = mParser.getLong(KEY_MIN_INTERVAL, DEFAULT_MIN_INTERVAL);
364 ALLOW_WHILE_IDLE_SHORT_TIME = mParser.getLong(KEY_ALLOW_WHILE_IDLE_SHORT_TIME,
365 DEFAULT_ALLOW_WHILE_IDLE_SHORT_TIME);
366 ALLOW_WHILE_IDLE_LONG_TIME = mParser.getLong(KEY_ALLOW_WHILE_IDLE_LONG_TIME,
367 DEFAULT_ALLOW_WHILE_IDLE_LONG_TIME);
368 ALLOW_WHILE_IDLE_WHITELIST_DURATION = mParser.getLong(
369 KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION,
370 DEFAULT_ALLOW_WHILE_IDLE_WHITELIST_DURATION);
Christopher Tate14a7bb02015-10-01 10:24:31 -0700371 LISTENER_TIMEOUT = mParser.getLong(KEY_LISTENER_TIMEOUT,
372 DEFAULT_LISTENER_TIMEOUT);
Suprabh Shukla75edab12018-01-29 14:09:06 -0800373 APP_STANDBY_MIN_DELAYS[0] = mParser.getDurationMillis(KEYS_APP_STANDBY_DELAY[0],
374 DEFAULT_APP_STANDBY_DELAYS[0]);
375 for (int i = 1; i < KEYS_APP_STANDBY_DELAY.length; i++) {
376 APP_STANDBY_MIN_DELAYS[i] = mParser.getDurationMillis(KEYS_APP_STANDBY_DELAY[i],
377 Math.max(APP_STANDBY_MIN_DELAYS[i-1], DEFAULT_APP_STANDBY_DELAYS[i]));
378 }
Dianne Hackborna750a632015-06-16 17:18:23 -0700379 updateAllowWhileIdleWhitelistDurationLocked();
380 }
381 }
382
383 void dump(PrintWriter pw) {
384 pw.println(" Settings:");
385
386 pw.print(" "); pw.print(KEY_MIN_FUTURITY); pw.print("=");
387 TimeUtils.formatDuration(MIN_FUTURITY, pw);
388 pw.println();
389
390 pw.print(" "); pw.print(KEY_MIN_INTERVAL); pw.print("=");
391 TimeUtils.formatDuration(MIN_INTERVAL, pw);
392 pw.println();
393
Christopher Tate14a7bb02015-10-01 10:24:31 -0700394 pw.print(" "); pw.print(KEY_LISTENER_TIMEOUT); pw.print("=");
395 TimeUtils.formatDuration(LISTENER_TIMEOUT, pw);
396 pw.println();
397
Dianne Hackborna750a632015-06-16 17:18:23 -0700398 pw.print(" "); pw.print(KEY_ALLOW_WHILE_IDLE_SHORT_TIME); pw.print("=");
399 TimeUtils.formatDuration(ALLOW_WHILE_IDLE_SHORT_TIME, pw);
400 pw.println();
401
402 pw.print(" "); pw.print(KEY_ALLOW_WHILE_IDLE_LONG_TIME); pw.print("=");
403 TimeUtils.formatDuration(ALLOW_WHILE_IDLE_LONG_TIME, pw);
404 pw.println();
405
406 pw.print(" "); pw.print(KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION); pw.print("=");
407 TimeUtils.formatDuration(ALLOW_WHILE_IDLE_WHITELIST_DURATION, pw);
408 pw.println();
Suprabh Shukla75edab12018-01-29 14:09:06 -0800409
410 for (int i = 0; i < KEYS_APP_STANDBY_DELAY.length; i++) {
411 pw.print(" "); pw.print(KEYS_APP_STANDBY_DELAY[i]); pw.print("=");
412 TimeUtils.formatDuration(APP_STANDBY_MIN_DELAYS[i], pw);
413 pw.println();
414 }
Dianne Hackborna750a632015-06-16 17:18:23 -0700415 }
Kweku Adams61e03292017-10-19 14:27:12 -0700416
417 void dumpProto(ProtoOutputStream proto, long fieldId) {
418 final long token = proto.start(fieldId);
419
420 proto.write(ConstantsProto.MIN_FUTURITY_DURATION_MS, MIN_FUTURITY);
421 proto.write(ConstantsProto.MIN_INTERVAL_DURATION_MS, MIN_INTERVAL);
422 proto.write(ConstantsProto.LISTENER_TIMEOUT_DURATION_MS, LISTENER_TIMEOUT);
423 proto.write(ConstantsProto.ALLOW_WHILE_IDLE_SHORT_DURATION_MS,
424 ALLOW_WHILE_IDLE_SHORT_TIME);
425 proto.write(ConstantsProto.ALLOW_WHILE_IDLE_LONG_DURATION_MS,
426 ALLOW_WHILE_IDLE_LONG_TIME);
427 proto.write(ConstantsProto.ALLOW_WHILE_IDLE_WHITELIST_DURATION_MS,
428 ALLOW_WHILE_IDLE_WHITELIST_DURATION);
429
430 proto.end(token);
431 }
Dianne Hackborna750a632015-06-16 17:18:23 -0700432 }
433
434 final Constants mConstants;
435
Christopher Tate1590f1e2014-10-02 17:27:57 -0700436 // Alarm delivery ordering bookkeeping
437 static final int PRIO_TICK = 0;
438 static final int PRIO_WAKEUP = 1;
439 static final int PRIO_NORMAL = 2;
440
Dianne Hackborna750a632015-06-16 17:18:23 -0700441 final class PriorityClass {
Christopher Tate1590f1e2014-10-02 17:27:57 -0700442 int seq;
443 int priority;
444
445 PriorityClass() {
446 seq = mCurrentSeq - 1;
447 priority = PRIO_NORMAL;
448 }
449 }
450
Dianne Hackborna750a632015-06-16 17:18:23 -0700451 final HashMap<String, PriorityClass> mPriorities = new HashMap<>();
Christopher Tate1590f1e2014-10-02 17:27:57 -0700452 int mCurrentSeq = 0;
453
Dianne Hackborna750a632015-06-16 17:18:23 -0700454 static final class WakeupEvent {
Christopher Tate18a75f12013-07-01 18:18:59 -0700455 public long when;
456 public int uid;
457 public String action;
458
459 public WakeupEvent(long theTime, int theUid, String theAction) {
460 when = theTime;
461 uid = theUid;
462 action = theAction;
463 }
464 }
465
Adam Lesinski182f73f2013-12-05 16:48:06 -0800466 final LinkedList<WakeupEvent> mRecentWakeups = new LinkedList<WakeupEvent>();
467 final long RECENT_WAKEUP_PERIOD = 1000L * 60 * 60 * 24; // one day
Christopher Tate18a75f12013-07-01 18:18:59 -0700468
Adrian Roosc42a1e12014-07-07 23:35:53 +0200469 final class Batch {
Christopher Tatee0a22b32013-07-11 14:43:13 -0700470 long start; // These endpoints are always in ELAPSED
471 long end;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700472 int flags; // Flags for alarms, such as FLAG_STANDALONE.
Christopher Tatee0a22b32013-07-11 14:43:13 -0700473
474 final ArrayList<Alarm> alarms = new ArrayList<Alarm>();
475
476 Batch() {
477 start = 0;
478 end = Long.MAX_VALUE;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700479 flags = 0;
Christopher Tatee0a22b32013-07-11 14:43:13 -0700480 }
481
482 Batch(Alarm seed) {
483 start = seed.whenElapsed;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700484 end = seed.maxWhenElapsed;
485 flags = seed.flags;
Christopher Tatee0a22b32013-07-11 14:43:13 -0700486 alarms.add(seed);
Makoto Onuki5d93b832018-01-10 16:12:39 -0800487 if (seed.operation == mTimeTickSender) {
488 mLastTickAdded = System.currentTimeMillis();
489 }
Christopher Tatee0a22b32013-07-11 14:43:13 -0700490 }
491
492 int size() {
493 return alarms.size();
494 }
495
496 Alarm get(int index) {
497 return alarms.get(index);
498 }
499
500 boolean canHold(long whenElapsed, long maxWhen) {
501 return (end >= whenElapsed) && (start <= maxWhen);
502 }
503
504 boolean add(Alarm alarm) {
505 boolean newStart = false;
506 // narrows the batch if necessary; presumes that canHold(alarm) is true
507 int index = Collections.binarySearch(alarms, alarm, sIncreasingTimeOrder);
508 if (index < 0) {
509 index = 0 - index - 1;
510 }
511 alarms.add(index, alarm);
Makoto Onuki5d93b832018-01-10 16:12:39 -0800512 if (alarm.operation == mTimeTickSender) {
513 mLastTickAdded = System.currentTimeMillis();
514 }
Christopher Tatee0a22b32013-07-11 14:43:13 -0700515 if (DEBUG_BATCH) {
516 Slog.v(TAG, "Adding " + alarm + " to " + this);
517 }
518 if (alarm.whenElapsed > start) {
519 start = alarm.whenElapsed;
520 newStart = true;
521 }
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700522 if (alarm.maxWhenElapsed < end) {
523 end = alarm.maxWhenElapsed;
Christopher Tatee0a22b32013-07-11 14:43:13 -0700524 }
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700525 flags |= alarm.flags;
Christopher Tatee0a22b32013-07-11 14:43:13 -0700526
527 if (DEBUG_BATCH) {
528 Slog.v(TAG, " => now " + this);
529 }
530 return newStart;
531 }
532
Suprabh Shukla92994ab2018-01-31 17:39:30 -0800533 boolean remove(Alarm alarm) {
534 return remove(a -> (a == alarm));
535 }
536
Christopher Tate1d99c392017-12-07 16:54:04 -0800537 boolean remove(Predicate<Alarm> predicate) {
Christopher Tatee0a22b32013-07-11 14:43:13 -0700538 boolean didRemove = false;
539 long newStart = 0; // recalculate endpoints as we go
540 long newEnd = Long.MAX_VALUE;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700541 int newFlags = 0;
Christopher Tateae269d52013-09-26 13:11:55 -0700542 for (int i = 0; i < alarms.size(); ) {
Christopher Tatee0a22b32013-07-11 14:43:13 -0700543 Alarm alarm = alarms.get(i);
Christopher Tate1d99c392017-12-07 16:54:04 -0800544 if (predicate.test(alarm)) {
Christopher Tatee0a22b32013-07-11 14:43:13 -0700545 alarms.remove(i);
546 didRemove = true;
Adrian Roosc42a1e12014-07-07 23:35:53 +0200547 if (alarm.alarmClock != null) {
548 mNextAlarmClockMayChange = true;
549 }
Makoto Onuki5d93b832018-01-10 16:12:39 -0800550 if (alarm.operation == mTimeTickSender) {
551 mLastTickRemoved = System.currentTimeMillis();
552 }
Christopher Tatee0a22b32013-07-11 14:43:13 -0700553 } else {
554 if (alarm.whenElapsed > newStart) {
555 newStart = alarm.whenElapsed;
556 }
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700557 if (alarm.maxWhenElapsed < newEnd) {
558 newEnd = alarm.maxWhenElapsed;
Christopher Tatee0a22b32013-07-11 14:43:13 -0700559 }
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700560 newFlags |= alarm.flags;
Christopher Tatee0a22b32013-07-11 14:43:13 -0700561 i++;
562 }
563 }
564 if (didRemove) {
565 // commit the new batch bounds
566 start = newStart;
567 end = newEnd;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700568 flags = newFlags;
Christopher Tatee0a22b32013-07-11 14:43:13 -0700569 }
570 return didRemove;
571 }
572
Christopher Tatee0a22b32013-07-11 14:43:13 -0700573 boolean hasPackage(final String packageName) {
574 final int N = alarms.size();
575 for (int i = 0; i < N; i++) {
576 Alarm a = alarms.get(i);
Christopher Tate14a7bb02015-10-01 10:24:31 -0700577 if (a.matches(packageName)) {
Christopher Tatee0a22b32013-07-11 14:43:13 -0700578 return true;
579 }
580 }
581 return false;
582 }
583
584 boolean hasWakeups() {
585 final int N = alarms.size();
586 for (int i = 0; i < N; i++) {
587 Alarm a = alarms.get(i);
588 // non-wakeup alarms are types 1 and 3, i.e. have the low bit set
589 if ((a.type & TYPE_NONWAKEUP_MASK) == 0) {
590 return true;
591 }
592 }
593 return false;
594 }
595
596 @Override
597 public String toString() {
598 StringBuilder b = new StringBuilder(40);
599 b.append("Batch{"); b.append(Integer.toHexString(this.hashCode()));
600 b.append(" num="); b.append(size());
601 b.append(" start="); b.append(start);
602 b.append(" end="); b.append(end);
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700603 if (flags != 0) {
604 b.append(" flgs=0x");
605 b.append(Integer.toHexString(flags));
Christopher Tatee0a22b32013-07-11 14:43:13 -0700606 }
607 b.append('}');
608 return b.toString();
609 }
Kweku Adams61e03292017-10-19 14:27:12 -0700610
611 public void writeToProto(ProtoOutputStream proto, long fieldId, long nowElapsed,
612 long nowRTC) {
613 final long token = proto.start(fieldId);
614
615 proto.write(BatchProto.START_REALTIME, start);
616 proto.write(BatchProto.END_REALTIME, end);
617 proto.write(BatchProto.FLAGS, flags);
618 for (Alarm a : alarms) {
619 a.writeToProto(proto, BatchProto.ALARMS, nowElapsed, nowRTC);
620 }
621
622 proto.end(token);
623 }
Christopher Tatee0a22b32013-07-11 14:43:13 -0700624 }
625
626 static class BatchTimeOrder implements Comparator<Batch> {
627 public int compare(Batch b1, Batch b2) {
Christopher Tate0dab4dc2014-12-16 12:14:06 -0800628 long when1 = b1.start;
629 long when2 = b2.start;
Charles Tsaicdaaeee2015-05-20 18:16:48 +0800630 if (when1 > when2) {
Christopher Tatee0a22b32013-07-11 14:43:13 -0700631 return 1;
632 }
Charles Tsaicdaaeee2015-05-20 18:16:48 +0800633 if (when1 < when2) {
Christopher Tatee0a22b32013-07-11 14:43:13 -0700634 return -1;
635 }
636 return 0;
637 }
638 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800639
640 final Comparator<Alarm> mAlarmDispatchComparator = new Comparator<Alarm>() {
641 @Override
642 public int compare(Alarm lhs, Alarm rhs) {
Christopher Tate1590f1e2014-10-02 17:27:57 -0700643 // priority class trumps everything. TICK < WAKEUP < NORMAL
644 if (lhs.priorityClass.priority < rhs.priorityClass.priority) {
645 return -1;
646 } else if (lhs.priorityClass.priority > rhs.priorityClass.priority) {
647 return 1;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800648 }
Christopher Tate1590f1e2014-10-02 17:27:57 -0700649
650 // within each class, sort by nominal delivery time
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800651 if (lhs.whenElapsed < rhs.whenElapsed) {
652 return -1;
653 } else if (lhs.whenElapsed > rhs.whenElapsed) {
654 return 1;
655 }
Christopher Tate1590f1e2014-10-02 17:27:57 -0700656
657 // same priority class + same target delivery time
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800658 return 0;
659 }
660 };
661
Christopher Tate1590f1e2014-10-02 17:27:57 -0700662 void calculateDeliveryPriorities(ArrayList<Alarm> alarms) {
663 final int N = alarms.size();
664 for (int i = 0; i < N; i++) {
665 Alarm a = alarms.get(i);
666
667 final int alarmPrio;
Christopher Tate14a7bb02015-10-01 10:24:31 -0700668 if (a.operation != null
669 && Intent.ACTION_TIME_TICK.equals(a.operation.getIntent().getAction())) {
Christopher Tate1590f1e2014-10-02 17:27:57 -0700670 alarmPrio = PRIO_TICK;
671 } else if (a.wakeup) {
672 alarmPrio = PRIO_WAKEUP;
673 } else {
674 alarmPrio = PRIO_NORMAL;
675 }
676
677 PriorityClass packagePrio = a.priorityClass;
Suprabh Shukla75edab12018-01-29 14:09:06 -0800678 String alarmPackage = a.sourcePackage;
Christopher Tate14a7bb02015-10-01 10:24:31 -0700679 if (packagePrio == null) packagePrio = mPriorities.get(alarmPackage);
Christopher Tate1590f1e2014-10-02 17:27:57 -0700680 if (packagePrio == null) {
681 packagePrio = a.priorityClass = new PriorityClass(); // lowest prio & stale sequence
Christopher Tate14a7bb02015-10-01 10:24:31 -0700682 mPriorities.put(alarmPackage, packagePrio);
Christopher Tate1590f1e2014-10-02 17:27:57 -0700683 }
684 a.priorityClass = packagePrio;
685
686 if (packagePrio.seq != mCurrentSeq) {
687 // first alarm we've seen in the current delivery generation from this package
688 packagePrio.priority = alarmPrio;
689 packagePrio.seq = mCurrentSeq;
690 } else {
691 // Multiple alarms from this package being delivered in this generation;
692 // bump the package's delivery class if it's warranted.
693 // TICK < WAKEUP < NORMAL
694 if (alarmPrio < packagePrio.priority) {
695 packagePrio.priority = alarmPrio;
696 }
697 }
698 }
699 }
700
Christopher Tatee0a22b32013-07-11 14:43:13 -0700701 // minimum recurrence period or alarm futurity for us to be able to fuzz it
Adam Lesinski182f73f2013-12-05 16:48:06 -0800702 static final long MIN_FUZZABLE_INTERVAL = 10000;
703 static final BatchTimeOrder sBatchOrder = new BatchTimeOrder();
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700704 final ArrayList<Batch> mAlarmBatches = new ArrayList<>();
705
Suprabh Shukladb6bf662017-08-30 15:41:53 -0700706 // set to non-null if in idle mode; while in this mode, any alarms we don't want
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700707 // to run during this time are placed in mPendingWhileIdleAlarms
708 Alarm mPendingIdleUntil = null;
Dianne Hackbornf70faed2015-04-21 14:11:38 -0700709 Alarm mNextWakeFromIdle = null;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700710 ArrayList<Alarm> mPendingWhileIdleAlarms = new ArrayList<>();
Christopher Tatee0a22b32013-07-11 14:43:13 -0700711
Jeff Brownb880d882014-02-10 19:47:07 -0800712 public AlarmManagerService(Context context) {
713 super(context);
Dianne Hackborna750a632015-06-16 17:18:23 -0700714 mConstants = new Constants(mHandler);
Makoto Onuki2206af32017-11-21 16:25:35 -0800715
Christopher Tate1d99c392017-12-07 16:54:04 -0800716 publishLocalService(AlarmManagerInternal.class, new LocalService());
Jeff Brownb880d882014-02-10 19:47:07 -0800717 }
718
Christopher Tatee0a22b32013-07-11 14:43:13 -0700719 static long convertToElapsed(long when, int type) {
720 final boolean isRtc = (type == RTC || type == RTC_WAKEUP);
721 if (isRtc) {
722 when -= System.currentTimeMillis() - SystemClock.elapsedRealtime();
723 }
724 return when;
725 }
726
727 // Apply a heuristic to { recurrence interval, futurity of the trigger time } to
728 // calculate the end of our nominal delivery window for the alarm.
729 static long maxTriggerTime(long now, long triggerAtTime, long interval) {
730 // Current heuristic: batchable window is 75% of either the recurrence interval
731 // [for a periodic alarm] or of the time from now to the desired delivery time,
732 // with a minimum delay/interval of 10 seconds, under which we will simply not
733 // defer the alarm.
734 long futurity = (interval == 0)
735 ? (triggerAtTime - now)
736 : interval;
Christopher Tate57ceaaa2013-07-19 16:30:43 -0700737 if (futurity < MIN_FUZZABLE_INTERVAL) {
Christopher Tatee0a22b32013-07-11 14:43:13 -0700738 futurity = 0;
739 }
740 return triggerAtTime + (long)(.75 * futurity);
741 }
742
743 // returns true if the batch was added at the head
744 static boolean addBatchLocked(ArrayList<Batch> list, Batch newBatch) {
745 int index = Collections.binarySearch(list, newBatch, sBatchOrder);
746 if (index < 0) {
747 index = 0 - index - 1;
748 }
749 list.add(index, newBatch);
750 return (index == 0);
751 }
752
Suprabh Shukla92994ab2018-01-31 17:39:30 -0800753 private void insertAndBatchAlarmLocked(Alarm alarm) {
754 final int whichBatch = ((alarm.flags & AlarmManager.FLAG_STANDALONE) != 0) ? -1
755 : attemptCoalesceLocked(alarm.whenElapsed, alarm.maxWhenElapsed);
756
757 if (whichBatch < 0) {
758 addBatchLocked(mAlarmBatches, new Batch(alarm));
759 } else {
760 final Batch batch = mAlarmBatches.get(whichBatch);
761 if (batch.add(alarm)) {
762 // The start time of this batch advanced, so batch ordering may
763 // have just been broken. Move it to where it now belongs.
764 mAlarmBatches.remove(whichBatch);
765 addBatchLocked(mAlarmBatches, batch);
766 }
767 }
768 }
769
Christopher Tate385e4982013-07-23 18:22:29 -0700770 // Return the index of the matching batch, or -1 if none found.
771 int attemptCoalesceLocked(long whenElapsed, long maxWhen) {
Christopher Tatee0a22b32013-07-11 14:43:13 -0700772 final int N = mAlarmBatches.size();
773 for (int i = 0; i < N; i++) {
774 Batch b = mAlarmBatches.get(i);
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700775 if ((b.flags&AlarmManager.FLAG_STANDALONE) == 0 && b.canHold(whenElapsed, maxWhen)) {
Christopher Tate385e4982013-07-23 18:22:29 -0700776 return i;
Christopher Tatee0a22b32013-07-11 14:43:13 -0700777 }
778 }
Christopher Tate385e4982013-07-23 18:22:29 -0700779 return -1;
Christopher Tatee0a22b32013-07-11 14:43:13 -0700780 }
Makoto Onuki5d93b832018-01-10 16:12:39 -0800781 /** @return total count of the alarms in a set of alarm batches. */
782 static int getAlarmCount(ArrayList<Batch> batches) {
783 int ret = 0;
784
785 final int size = batches.size();
786 for (int i = 0; i < size; i++) {
787 ret += batches.get(i).size();
788 }
789 return ret;
790 }
791
792 boolean haveAlarmsTimeTickAlarm(ArrayList<Alarm> alarms) {
793 if (alarms.size() == 0) {
794 return false;
795 }
796 final int batchSize = alarms.size();
797 for (int j = 0; j < batchSize; j++) {
798 if (alarms.get(j).operation == mTimeTickSender) {
799 return true;
800 }
801 }
802 return false;
803 }
804
805 boolean haveBatchesTimeTickAlarm(ArrayList<Batch> batches) {
806 final int numBatches = batches.size();
807 for (int i = 0; i < numBatches; i++) {
808 if (haveAlarmsTimeTickAlarm(batches.get(i).alarms)) {
809 return true;
810 }
811 }
812 return false;
813 }
Christopher Tatee0a22b32013-07-11 14:43:13 -0700814
815 // The RTC clock has moved arbitrarily, so we need to recalculate all the batching
816 void rebatchAllAlarms() {
Christopher Tatee0a22b32013-07-11 14:43:13 -0700817 synchronized (mLock) {
Christopher Tate4cb338d2013-07-26 13:11:31 -0700818 rebatchAllAlarmsLocked(true);
819 }
820 }
821
822 void rebatchAllAlarmsLocked(boolean doValidate) {
Suprabh Shukla92994ab2018-01-31 17:39:30 -0800823 final long start = mStatLogger.getTime();
Makoto Onuki5d93b832018-01-10 16:12:39 -0800824 final int oldCount =
825 getAlarmCount(mAlarmBatches) + ArrayUtils.size(mPendingWhileIdleAlarms);
826 final boolean oldHasTick = haveBatchesTimeTickAlarm(mAlarmBatches)
827 || haveAlarmsTimeTickAlarm(mPendingWhileIdleAlarms);
828
Christopher Tate4cb338d2013-07-26 13:11:31 -0700829 ArrayList<Batch> oldSet = (ArrayList<Batch>) mAlarmBatches.clone();
830 mAlarmBatches.clear();
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700831 Alarm oldPendingIdleUntil = mPendingIdleUntil;
Christopher Tate4cb338d2013-07-26 13:11:31 -0700832 final long nowElapsed = SystemClock.elapsedRealtime();
833 final int oldBatches = oldSet.size();
834 for (int batchNum = 0; batchNum < oldBatches; batchNum++) {
835 Batch batch = oldSet.get(batchNum);
836 final int N = batch.size();
837 for (int i = 0; i < N; i++) {
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700838 reAddAlarmLocked(batch.get(i), nowElapsed, doValidate);
Christopher Tatee0a22b32013-07-11 14:43:13 -0700839 }
840 }
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700841 if (oldPendingIdleUntil != null && oldPendingIdleUntil != mPendingIdleUntil) {
842 Slog.wtf(TAG, "Rebatching: idle until changed from " + oldPendingIdleUntil
843 + " to " + mPendingIdleUntil);
844 if (mPendingIdleUntil == null) {
845 // Somehow we lost this... we need to restore all of the pending alarms.
846 restorePendingWhileIdleAlarmsLocked();
847 }
848 }
Makoto Onuki5d93b832018-01-10 16:12:39 -0800849 final int newCount =
850 getAlarmCount(mAlarmBatches) + ArrayUtils.size(mPendingWhileIdleAlarms);
851 final boolean newHasTick = haveBatchesTimeTickAlarm(mAlarmBatches)
852 || haveAlarmsTimeTickAlarm(mPendingWhileIdleAlarms);
853
854 if (oldCount != newCount) {
855 Slog.wtf(TAG, "Rebatching: total count changed from " + oldCount + " to " + newCount);
856 }
857 if (oldHasTick != newHasTick) {
858 Slog.wtf(TAG, "Rebatching: hasTick changed from " + oldHasTick + " to " + newHasTick);
859 }
860
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700861 rescheduleKernelAlarmsLocked();
862 updateNextAlarmClockLocked();
Suprabh Shukla75edab12018-01-29 14:09:06 -0800863 mStatLogger.logDurationStat(Stats.REBATCH_ALL_ALARMS, start);
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700864 }
865
Suprabh Shukla92994ab2018-01-31 17:39:30 -0800866 /**
867 * Re-orders the alarm batches based on newly evaluated send times based on the current
868 * app-standby buckets
869 * @param targetPackages [Package, User] pairs for which alarms need to be re-evaluated,
870 * null indicates all
871 * @return True if there was any reordering done to the current list.
872 */
873 boolean reorderAlarmsBasedOnStandbyBuckets(ArraySet<Pair<String, Integer>> targetPackages) {
874 final long start = mStatLogger.getTime();
875 final ArrayList<Alarm> rescheduledAlarms = new ArrayList<>();
876
877 for (int batchIndex = mAlarmBatches.size() - 1; batchIndex >= 0; batchIndex--) {
878 final Batch batch = mAlarmBatches.get(batchIndex);
879 for (int alarmIndex = batch.size() - 1; alarmIndex >= 0; alarmIndex--) {
880 final Alarm alarm = batch.get(alarmIndex);
881 final Pair<String, Integer> packageUser =
882 Pair.create(alarm.sourcePackage, UserHandle.getUserId(alarm.creatorUid));
883 if (targetPackages != null && !targetPackages.contains(packageUser)) {
884 continue;
885 }
886 if (adjustDeliveryTimeBasedOnStandbyBucketLocked(alarm)) {
887 batch.remove(alarm);
888 rescheduledAlarms.add(alarm);
889 }
890 }
891 if (batch.size() == 0) {
892 mAlarmBatches.remove(batchIndex);
893 }
894 }
895 for (int i = 0; i < rescheduledAlarms.size(); i++) {
896 final Alarm a = rescheduledAlarms.get(i);
897 insertAndBatchAlarmLocked(a);
898 }
899
900 mStatLogger.logDurationStat(Stats.REORDER_ALARMS_FOR_STANDBY, start);
901 return rescheduledAlarms.size() > 0;
902 }
903
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700904 void reAddAlarmLocked(Alarm a, long nowElapsed, boolean doValidate) {
905 a.when = a.origWhen;
906 long whenElapsed = convertToElapsed(a.when, a.type);
907 final long maxElapsed;
Dianne Hackborn3d1933c42015-06-10 16:25:57 -0700908 if (a.windowLength == AlarmManager.WINDOW_EXACT) {
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700909 // Exact
910 maxElapsed = whenElapsed;
911 } else {
912 // Not exact. Preserve any explicit window, otherwise recalculate
913 // the window based on the alarm's new futurity. Note that this
914 // reflects a policy of preferring timely to deferred delivery.
915 maxElapsed = (a.windowLength > 0)
916 ? (whenElapsed + a.windowLength)
917 : maxTriggerTime(nowElapsed, whenElapsed, a.repeatInterval);
918 }
919 a.whenElapsed = whenElapsed;
920 a.maxWhenElapsed = maxElapsed;
921 setImplLocked(a, true, doValidate);
922 }
923
Suprabh Shukladb6bf662017-08-30 15:41:53 -0700924 /**
925 * Sends alarms that were blocked due to user applied background restrictions - either because
926 * the user lifted those or the uid came to foreground.
927 *
928 * @param uid uid to filter on
929 * @param packageName package to filter on, or null for all packages in uid
930 */
931 void sendPendingBackgroundAlarmsLocked(int uid, String packageName) {
932 final ArrayList<Alarm> alarmsForUid = mPendingBackgroundAlarms.get(uid);
933 if (alarmsForUid == null || alarmsForUid.size() == 0) {
934 return;
935 }
936 final ArrayList<Alarm> alarmsToDeliver;
937 if (packageName != null) {
938 if (DEBUG_BG_LIMIT) {
939 Slog.d(TAG, "Sending blocked alarms for uid " + uid + ", package " + packageName);
940 }
941 alarmsToDeliver = new ArrayList<>();
942 for (int i = alarmsForUid.size() - 1; i >= 0; i--) {
943 final Alarm a = alarmsForUid.get(i);
944 if (a.matches(packageName)) {
945 alarmsToDeliver.add(alarmsForUid.remove(i));
946 }
947 }
948 if (alarmsForUid.size() == 0) {
949 mPendingBackgroundAlarms.remove(uid);
950 }
951 } else {
952 if (DEBUG_BG_LIMIT) {
953 Slog.d(TAG, "Sending blocked alarms for uid " + uid);
954 }
955 alarmsToDeliver = alarmsForUid;
956 mPendingBackgroundAlarms.remove(uid);
957 }
958 deliverPendingBackgroundAlarmsLocked(alarmsToDeliver, SystemClock.elapsedRealtime());
959 }
960
Makoto Onuki2206af32017-11-21 16:25:35 -0800961 /**
962 * Check all alarms in {@link #mPendingBackgroundAlarms} and send the ones that are not
963 * restricted.
964 *
965 * This is only called when the global "force all apps-standby" flag changes or when the
966 * power save whitelist changes, so it's okay to be slow.
967 */
968 void sendAllUnrestrictedPendingBackgroundAlarmsLocked() {
Suprabh Shukladb6bf662017-08-30 15:41:53 -0700969 final ArrayList<Alarm> alarmsToDeliver = new ArrayList<>();
Makoto Onuki2206af32017-11-21 16:25:35 -0800970
971 findAllUnrestrictedPendingBackgroundAlarmsLockedInner(
972 mPendingBackgroundAlarms, alarmsToDeliver, this::isBackgroundRestricted);
973
974 if (alarmsToDeliver.size() > 0) {
975 deliverPendingBackgroundAlarmsLocked(alarmsToDeliver, SystemClock.elapsedRealtime());
976 }
977 }
978
979 @VisibleForTesting
980 static void findAllUnrestrictedPendingBackgroundAlarmsLockedInner(
981 SparseArray<ArrayList<Alarm>> pendingAlarms, ArrayList<Alarm> unrestrictedAlarms,
982 Predicate<Alarm> isBackgroundRestricted) {
983
984 for (int uidIndex = pendingAlarms.size() - 1; uidIndex >= 0; uidIndex--) {
985 final int uid = pendingAlarms.keyAt(uidIndex);
986 final ArrayList<Alarm> alarmsForUid = pendingAlarms.valueAt(uidIndex);
987
988 for (int alarmIndex = alarmsForUid.size() - 1; alarmIndex >= 0; alarmIndex--) {
989 final Alarm alarm = alarmsForUid.get(alarmIndex);
990
991 if (isBackgroundRestricted.test(alarm)) {
992 continue;
993 }
994
995 unrestrictedAlarms.add(alarm);
996 alarmsForUid.remove(alarmIndex);
997 }
998
999 if (alarmsForUid.size() == 0) {
1000 pendingAlarms.removeAt(uidIndex);
Suprabh Shukladb6bf662017-08-30 15:41:53 -07001001 }
1002 }
Suprabh Shukladb6bf662017-08-30 15:41:53 -07001003 }
1004
1005 private void deliverPendingBackgroundAlarmsLocked(ArrayList<Alarm> alarms, long nowELAPSED) {
1006 final int N = alarms.size();
1007 boolean hasWakeup = false;
1008 for (int i = 0; i < N; i++) {
1009 final Alarm alarm = alarms.get(i);
1010 if (alarm.wakeup) {
1011 hasWakeup = true;
1012 }
1013 alarm.count = 1;
1014 // Recurring alarms may have passed several alarm intervals while the
1015 // alarm was kept pending. Send the appropriate trigger count.
1016 if (alarm.repeatInterval > 0) {
Suprabh Shuklad65e58a2018-02-05 20:36:08 -08001017 alarm.count += (nowELAPSED - alarm.expectedWhenElapsed) / alarm.repeatInterval;
Suprabh Shukladb6bf662017-08-30 15:41:53 -07001018 // Also schedule its next recurrence
1019 final long delta = alarm.count * alarm.repeatInterval;
1020 final long nextElapsed = alarm.whenElapsed + delta;
1021 setImplLocked(alarm.type, alarm.when + delta, nextElapsed, alarm.windowLength,
1022 maxTriggerTime(nowELAPSED, nextElapsed, alarm.repeatInterval),
1023 alarm.repeatInterval, alarm.operation, null, null, alarm.flags, true,
1024 alarm.workSource, alarm.alarmClock, alarm.uid, alarm.packageName);
1025 // Kernel alarms will be rescheduled as needed in setImplLocked
1026 }
1027 }
1028 if (!hasWakeup && checkAllowNonWakeupDelayLocked(nowELAPSED)) {
1029 // No need to wakeup for non wakeup alarms
1030 if (mPendingNonWakeupAlarms.size() == 0) {
1031 mStartCurrentDelayTime = nowELAPSED;
1032 mNextNonWakeupDeliveryTime = nowELAPSED
1033 + ((currentNonWakeupFuzzLocked(nowELAPSED)*3)/2);
1034 }
1035 mPendingNonWakeupAlarms.addAll(alarms);
1036 mNumDelayedAlarms += alarms.size();
1037 } else {
1038 if (DEBUG_BG_LIMIT) {
1039 Slog.d(TAG, "Waking up to deliver pending blocked alarms");
1040 }
1041 // Since we are waking up, also deliver any pending non wakeup alarms we have.
1042 if (mPendingNonWakeupAlarms.size() > 0) {
1043 alarms.addAll(mPendingNonWakeupAlarms);
1044 final long thisDelayTime = nowELAPSED - mStartCurrentDelayTime;
1045 mTotalDelayTime += thisDelayTime;
1046 if (mMaxDelayTime < thisDelayTime) {
1047 mMaxDelayTime = thisDelayTime;
1048 }
1049 mPendingNonWakeupAlarms.clear();
1050 }
1051 calculateDeliveryPriorities(alarms);
1052 Collections.sort(alarms, mAlarmDispatchComparator);
1053 deliverAlarmsLocked(alarms, nowELAPSED);
1054 }
1055 }
1056
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07001057 void restorePendingWhileIdleAlarmsLocked() {
Dianne Hackbornae78bf82015-10-26 13:33:20 -07001058 if (RECORD_DEVICE_IDLE_ALARMS) {
1059 IdleDispatchEntry ent = new IdleDispatchEntry();
1060 ent.uid = 0;
1061 ent.pkg = "FINISH IDLE";
1062 ent.elapsedRealtime = SystemClock.elapsedRealtime();
1063 mAllowWhileIdleDispatches.add(ent);
1064 }
1065
Dianne Hackborn35d54032015-04-23 10:30:43 -07001066 // Bring pending alarms back into the main list.
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001067 if (mPendingWhileIdleAlarms.size() > 0) {
1068 ArrayList<Alarm> alarms = mPendingWhileIdleAlarms;
1069 mPendingWhileIdleAlarms = new ArrayList<>();
1070 final long nowElapsed = SystemClock.elapsedRealtime();
1071 for (int i=alarms.size() - 1; i >= 0; i--) {
1072 Alarm a = alarms.get(i);
1073 reAddAlarmLocked(a, nowElapsed, false);
1074 }
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07001075 }
Dianne Hackborn35d54032015-04-23 10:30:43 -07001076
1077 // Reschedule everything.
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07001078 rescheduleKernelAlarmsLocked();
1079 updateNextAlarmClockLocked();
Dianne Hackborn35d54032015-04-23 10:30:43 -07001080
1081 // And send a TIME_TICK right now, since it is important to get the UI updated.
1082 try {
1083 mTimeTickSender.send();
1084 } catch (PendingIntent.CanceledException e) {
1085 }
Christopher Tatee0a22b32013-07-11 14:43:13 -07001086 }
1087
Christopher Tate14a7bb02015-10-01 10:24:31 -07001088 static final class InFlight {
Dianne Hackborn81038902012-11-26 17:04:09 -08001089 final PendingIntent mPendingIntent;
Christopher Tateeabba732017-08-17 17:12:52 -07001090 final long mWhenElapsed;
Christopher Tate14a7bb02015-10-01 10:24:31 -07001091 final IBinder mListener;
David Christieebe51fc2013-07-26 13:23:29 -07001092 final WorkSource mWorkSource;
Christopher Tate14a7bb02015-10-01 10:24:31 -07001093 final int mUid;
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07001094 final String mTag;
Dianne Hackborn81038902012-11-26 17:04:09 -08001095 final BroadcastStats mBroadcastStats;
1096 final FilterStats mFilterStats;
Dianne Hackborne5167ca2014-03-08 14:39:10 -08001097 final int mAlarmType;
Dianne Hackborn81038902012-11-26 17:04:09 -08001098
Christopher Tate14a7bb02015-10-01 10:24:31 -07001099 InFlight(AlarmManagerService service, PendingIntent pendingIntent, IAlarmListener listener,
1100 WorkSource workSource, int uid, String alarmPkg, int alarmType, String tag,
1101 long nowELAPSED) {
Dianne Hackborn81038902012-11-26 17:04:09 -08001102 mPendingIntent = pendingIntent;
Christopher Tateeabba732017-08-17 17:12:52 -07001103 mWhenElapsed = nowELAPSED;
Christopher Tate14a7bb02015-10-01 10:24:31 -07001104 mListener = listener != null ? listener.asBinder() : null;
David Christieebe51fc2013-07-26 13:23:29 -07001105 mWorkSource = workSource;
Christopher Tate14a7bb02015-10-01 10:24:31 -07001106 mUid = uid;
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07001107 mTag = tag;
Christopher Tate14a7bb02015-10-01 10:24:31 -07001108 mBroadcastStats = (pendingIntent != null)
1109 ? service.getStatsLocked(pendingIntent)
1110 : service.getStatsLocked(uid, alarmPkg);
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07001111 FilterStats fs = mBroadcastStats.filterStats.get(mTag);
Dianne Hackborn81038902012-11-26 17:04:09 -08001112 if (fs == null) {
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07001113 fs = new FilterStats(mBroadcastStats, mTag);
1114 mBroadcastStats.filterStats.put(mTag, fs);
Dianne Hackborn81038902012-11-26 17:04:09 -08001115 }
Dianne Hackbornf70faed2015-04-21 14:11:38 -07001116 fs.lastTime = nowELAPSED;
Dianne Hackborn81038902012-11-26 17:04:09 -08001117 mFilterStats = fs;
Dianne Hackborne5167ca2014-03-08 14:39:10 -08001118 mAlarmType = alarmType;
Dianne Hackborn81038902012-11-26 17:04:09 -08001119 }
Makoto Onuki33955e12017-03-01 18:11:00 -08001120
1121 @Override
1122 public String toString() {
1123 return "InFlight{"
1124 + "pendingIntent=" + mPendingIntent
Christopher Tateeabba732017-08-17 17:12:52 -07001125 + ", when=" + mWhenElapsed
Makoto Onuki33955e12017-03-01 18:11:00 -08001126 + ", workSource=" + mWorkSource
1127 + ", uid=" + mUid
1128 + ", tag=" + mTag
1129 + ", broadcastStats=" + mBroadcastStats
1130 + ", filterStats=" + mFilterStats
1131 + ", alarmType=" + mAlarmType
1132 + "}";
1133 }
Kweku Adams61e03292017-10-19 14:27:12 -07001134
1135 public void writeToProto(ProtoOutputStream proto, long fieldId) {
1136 final long token = proto.start(fieldId);
1137
1138 proto.write(InFlightProto.UID, mUid);
1139 proto.write(InFlightProto.TAG, mTag);
1140 proto.write(InFlightProto.WHEN_ELAPSED_MS, mWhenElapsed);
1141 proto.write(InFlightProto.ALARM_TYPE, mAlarmType);
1142 if (mPendingIntent != null) {
1143 mPendingIntent.writeToProto(proto, InFlightProto.PENDING_INTENT);
1144 }
1145 if (mBroadcastStats != null) {
1146 mBroadcastStats.writeToProto(proto, InFlightProto.BROADCAST_STATS);
1147 }
1148 if (mFilterStats != null) {
1149 mFilterStats.writeToProto(proto, InFlightProto.FILTER_STATS);
1150 }
1151 if (mWorkSource != null) {
1152 mWorkSource.writeToProto(proto, InFlightProto.WORK_SOURCE);
1153 }
1154
1155 proto.end(token);
1156 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001157 }
Dianne Hackborn81038902012-11-26 17:04:09 -08001158
Adam Lesinski182f73f2013-12-05 16:48:06 -08001159 static final class FilterStats {
Dianne Hackborn81038902012-11-26 17:04:09 -08001160 final BroadcastStats mBroadcastStats;
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07001161 final String mTag;
Dianne Hackborn81038902012-11-26 17:04:09 -08001162
Dianne Hackbornf70faed2015-04-21 14:11:38 -07001163 long lastTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001164 long aggregateTime;
Dianne Hackborn81038902012-11-26 17:04:09 -08001165 int count;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001166 int numWakeup;
1167 long startTime;
1168 int nesting;
Dianne Hackborn81038902012-11-26 17:04:09 -08001169
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07001170 FilterStats(BroadcastStats broadcastStats, String tag) {
Dianne Hackborn81038902012-11-26 17:04:09 -08001171 mBroadcastStats = broadcastStats;
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07001172 mTag = tag;
Dianne Hackborn81038902012-11-26 17:04:09 -08001173 }
Makoto Onuki33955e12017-03-01 18:11:00 -08001174
1175 @Override
1176 public String toString() {
1177 return "FilterStats{"
1178 + "tag=" + mTag
1179 + ", lastTime=" + lastTime
1180 + ", aggregateTime=" + aggregateTime
1181 + ", count=" + count
1182 + ", numWakeup=" + numWakeup
1183 + ", startTime=" + startTime
1184 + ", nesting=" + nesting
1185 + "}";
1186 }
Kweku Adams61e03292017-10-19 14:27:12 -07001187
1188 public void writeToProto(ProtoOutputStream proto, long fieldId) {
1189 final long token = proto.start(fieldId);
1190
1191 proto.write(FilterStatsProto.TAG, mTag);
1192 proto.write(FilterStatsProto.LAST_FLIGHT_TIME_REALTIME, lastTime);
1193 proto.write(FilterStatsProto.TOTAL_FLIGHT_DURATION_MS, aggregateTime);
1194 proto.write(FilterStatsProto.COUNT, count);
1195 proto.write(FilterStatsProto.WAKEUP_COUNT, numWakeup);
1196 proto.write(FilterStatsProto.START_TIME_REALTIME, startTime);
1197 proto.write(FilterStatsProto.NESTING, nesting);
1198
1199 proto.end(token);
1200 }
Dianne Hackborn81038902012-11-26 17:04:09 -08001201 }
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07001202
Adam Lesinski182f73f2013-12-05 16:48:06 -08001203 static final class BroadcastStats {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001204 final int mUid;
Dianne Hackborn81038902012-11-26 17:04:09 -08001205 final String mPackageName;
1206
1207 long aggregateTime;
1208 int count;
1209 int numWakeup;
1210 long startTime;
1211 int nesting;
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07001212 final ArrayMap<String, FilterStats> filterStats = new ArrayMap<String, FilterStats>();
Dianne Hackborn81038902012-11-26 17:04:09 -08001213
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001214 BroadcastStats(int uid, String packageName) {
1215 mUid = uid;
Dianne Hackborn81038902012-11-26 17:04:09 -08001216 mPackageName = packageName;
1217 }
Makoto Onuki33955e12017-03-01 18:11:00 -08001218
1219 @Override
1220 public String toString() {
1221 return "BroadcastStats{"
1222 + "uid=" + mUid
1223 + ", packageName=" + mPackageName
1224 + ", aggregateTime=" + aggregateTime
1225 + ", count=" + count
1226 + ", numWakeup=" + numWakeup
1227 + ", startTime=" + startTime
1228 + ", nesting=" + nesting
1229 + "}";
1230 }
Kweku Adams61e03292017-10-19 14:27:12 -07001231
1232 public void writeToProto(ProtoOutputStream proto, long fieldId) {
1233 final long token = proto.start(fieldId);
1234
1235 proto.write(BroadcastStatsProto.UID, mUid);
1236 proto.write(BroadcastStatsProto.PACKAGE_NAME, mPackageName);
1237 proto.write(BroadcastStatsProto.TOTAL_FLIGHT_DURATION_MS, aggregateTime);
1238 proto.write(BroadcastStatsProto.COUNT, count);
1239 proto.write(BroadcastStatsProto.WAKEUP_COUNT, numWakeup);
1240 proto.write(BroadcastStatsProto.START_TIME_REALTIME, startTime);
1241 proto.write(BroadcastStatsProto.NESTING, nesting);
1242
1243 proto.end(token);
1244 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001245 }
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07001246
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001247 final SparseArray<ArrayMap<String, BroadcastStats>> mBroadcastStats
1248 = new SparseArray<ArrayMap<String, BroadcastStats>>();
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07001249
1250 int mNumDelayedAlarms = 0;
1251 long mTotalDelayTime = 0;
1252 long mMaxDelayTime = 0;
1253
Adam Lesinski182f73f2013-12-05 16:48:06 -08001254 @Override
1255 public void onStart() {
Greg Hackmanna1d6f922013-12-09 16:56:53 -08001256 mNativeData = init();
Christopher Tate0dab4dc2014-12-16 12:14:06 -08001257 mNextWakeup = mNextNonWakeup = 0;
Robert CH Chou64ba8e42009-11-04 21:38:49 +08001258
1259 // We have to set current TimeZone info to kernel
1260 // because kernel doesn't keep this after reboot
Adam Lesinski182f73f2013-12-05 16:48:06 -08001261 setTimeZoneImpl(SystemProperties.get(TIMEZONE_PROPERTY));
Robert CH Chou64ba8e42009-11-04 21:38:49 +08001262
Christopher Tate247571462017-04-10 11:45:05 -07001263 // Also sure that we're booting with a halfway sensible current time
1264 if (mNativeData != 0) {
1265 final long systemBuildTime = Environment.getRootDirectory().lastModified();
1266 if (System.currentTimeMillis() < systemBuildTime) {
1267 Slog.i(TAG, "Current time only " + System.currentTimeMillis()
1268 + ", advancing to build time " + systemBuildTime);
1269 setKernelTime(mNativeData, systemBuildTime);
1270 }
1271 }
1272
Christopher Tatebb9cce52017-04-18 14:19:43 -07001273 // Determine SysUI's uid
1274 final PackageManager packMan = getContext().getPackageManager();
1275 try {
1276 PermissionInfo sysUiPerm = packMan.getPermissionInfo(SYSTEM_UI_SELF_PERMISSION, 0);
1277 ApplicationInfo sysUi = packMan.getApplicationInfo(sysUiPerm.packageName, 0);
1278 if ((sysUi.privateFlags&ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
1279 mSystemUiUid = sysUi.uid;
1280 } else {
1281 Slog.e(TAG, "SysUI permission " + SYSTEM_UI_SELF_PERMISSION
1282 + " defined by non-privileged app " + sysUi.packageName
1283 + " - ignoring");
1284 }
1285 } catch (NameNotFoundException e) {
1286 }
1287
1288 if (mSystemUiUid <= 0) {
1289 Slog.wtf(TAG, "SysUI package not found!");
1290 }
1291
Adam Lesinski182f73f2013-12-05 16:48:06 -08001292 PowerManager pm = (PowerManager) getContext().getSystemService(Context.POWER_SERVICE);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001293 mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*alarm*");
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -08001294
Adam Lesinski182f73f2013-12-05 16:48:06 -08001295 mTimeTickSender = PendingIntent.getBroadcastAsUser(getContext(), 0,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001296 new Intent(Intent.ACTION_TIME_TICK).addFlags(
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001297 Intent.FLAG_RECEIVER_REGISTERED_ONLY
Chad Brubaker291df4f2017-03-14 10:23:02 -07001298 | Intent.FLAG_RECEIVER_FOREGROUND
1299 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS), 0,
Dianne Hackborndb5aca92012-10-26 13:39:41 -07001300 UserHandle.ALL);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -08001301 Intent intent = new Intent(Intent.ACTION_DATE_CHANGED);
Chad Brubaker291df4f2017-03-14 10:23:02 -07001302 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
1303 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
Adam Lesinski182f73f2013-12-05 16:48:06 -08001304 mDateChangeSender = PendingIntent.getBroadcastAsUser(getContext(), 0, intent,
Dianne Hackborndb5aca92012-10-26 13:39:41 -07001305 Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT, UserHandle.ALL);
Kweku Adams61e03292017-10-19 14:27:12 -07001306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001307 // now that we have initied the driver schedule the alarm
Adam Lesinski182f73f2013-12-05 16:48:06 -08001308 mClockReceiver = new ClockReceiver();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001309 mClockReceiver.scheduleTimeTickEvent();
1310 mClockReceiver.scheduleDateChangedEvent();
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07001311 mInteractiveStateReceiver = new InteractiveStateReceiver();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001312 mUninstallReceiver = new UninstallReceiver();
Kweku Adams61e03292017-10-19 14:27:12 -07001313
Greg Hackmanna1d6f922013-12-09 16:56:53 -08001314 if (mNativeData != 0) {
Adam Lesinski182f73f2013-12-05 16:48:06 -08001315 AlarmThread waitThread = new AlarmThread();
1316 waitThread.start();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001317 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001318 Slog.w(TAG, "Failed to open alarm driver. Falling back to a handler.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001319 }
Adam Lesinski182f73f2013-12-05 16:48:06 -08001320
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001321 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001322 ActivityManager.getService().registerUidObserver(new UidObserver(),
Suprabh Shukladb6bf662017-08-30 15:41:53 -07001323 ActivityManager.UID_OBSERVER_GONE | ActivityManager.UID_OBSERVER_IDLE
1324 | ActivityManager.UID_OBSERVER_ACTIVE,
1325 ActivityManager.PROCESS_STATE_UNKNOWN, null);
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001326 } catch (RemoteException e) {
1327 // ignored; both services live in system_server
1328 }
Adam Lesinski182f73f2013-12-05 16:48:06 -08001329 publishBinderService(Context.ALARM_SERVICE, mService);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001330 }
Adam Lesinski182f73f2013-12-05 16:48:06 -08001331
1332 @Override
Dianne Hackborna750a632015-06-16 17:18:23 -07001333 public void onBootPhase(int phase) {
1334 if (phase == PHASE_SYSTEM_SERVICES_READY) {
1335 mConstants.start(getContext().getContentResolver());
Christopher Tate14a7bb02015-10-01 10:24:31 -07001336 mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE);
Dianne Hackborn627dfa12015-11-11 18:10:30 -08001337 mLocalDeviceIdleController
1338 = LocalServices.getService(DeviceIdleController.LocalService.class);
Suprabh Shukla75edab12018-01-29 14:09:06 -08001339 mUsageStatsManagerInternal = LocalServices.getService(UsageStatsManagerInternal.class);
1340 mUsageStatsManagerInternal.addAppIdleStateChangeListener(new AppStandbyTracker());
Makoto Onukie4918212018-02-06 11:30:15 -08001341
1342 mAppStateTracker = LocalServices.getService(AppStateTracker.class);
1343 mAppStateTracker.addListener(mForceAppStandbyListener);
Dianne Hackborna750a632015-06-16 17:18:23 -07001344 }
1345 }
1346
1347 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001348 protected void finalize() throws Throwable {
1349 try {
Greg Hackmanna1d6f922013-12-09 16:56:53 -08001350 close(mNativeData);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001351 } finally {
1352 super.finalize();
1353 }
1354 }
Christopher Tatee0a22b32013-07-11 14:43:13 -07001355
Adam Lesinski182f73f2013-12-05 16:48:06 -08001356 void setTimeZoneImpl(String tz) {
1357 if (TextUtils.isEmpty(tz)) {
1358 return;
David Christieebe51fc2013-07-26 13:23:29 -07001359 }
1360
Adam Lesinski182f73f2013-12-05 16:48:06 -08001361 TimeZone zone = TimeZone.getTimeZone(tz);
1362 // Prevent reentrant calls from stepping on each other when writing
1363 // the time zone property
1364 boolean timeZoneWasChanged = false;
1365 synchronized (this) {
1366 String current = SystemProperties.get(TIMEZONE_PROPERTY);
1367 if (current == null || !current.equals(zone.getID())) {
1368 if (localLOGV) {
1369 Slog.v(TAG, "timezone changed: " + current + ", new=" + zone.getID());
1370 }
1371 timeZoneWasChanged = true;
1372 SystemProperties.set(TIMEZONE_PROPERTY, zone.getID());
1373 }
1374
1375 // Update the kernel timezone information
1376 // Kernel tracks time offsets as 'minutes west of GMT'
1377 int gmtOffset = zone.getOffset(System.currentTimeMillis());
Greg Hackmannf1bdbdd2013-12-17 11:56:22 -08001378 setKernelTimezone(mNativeData, -(gmtOffset / 60000));
Adam Lesinski182f73f2013-12-05 16:48:06 -08001379 }
1380
1381 TimeZone.setDefault(null);
1382
1383 if (timeZoneWasChanged) {
1384 Intent intent = new Intent(Intent.ACTION_TIMEZONE_CHANGED);
Chad Brubaker291df4f2017-03-14 10:23:02 -07001385 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
Christopher Tate5cdf9f82017-05-03 18:10:39 -07001386 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
Chad Brubaker291df4f2017-03-14 10:23:02 -07001387 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
Adam Lesinski182f73f2013-12-05 16:48:06 -08001388 intent.putExtra("time-zone", zone.getID());
1389 getContext().sendBroadcastAsUser(intent, UserHandle.ALL);
1390 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001391 }
Christopher Tatee0a22b32013-07-11 14:43:13 -07001392
Adam Lesinski182f73f2013-12-05 16:48:06 -08001393 void removeImpl(PendingIntent operation) {
1394 if (operation == null) {
1395 return;
1396 }
1397 synchronized (mLock) {
Christopher Tate14a7bb02015-10-01 10:24:31 -07001398 removeLocked(operation, null);
Adam Lesinski182f73f2013-12-05 16:48:06 -08001399 }
1400 }
1401
1402 void setImpl(int type, long triggerAtTime, long windowLength, long interval,
Christopher Tate14a7bb02015-10-01 10:24:31 -07001403 PendingIntent operation, IAlarmListener directReceiver, String listenerTag,
1404 int flags, WorkSource workSource, AlarmManager.AlarmClockInfo alarmClock,
1405 int callingUid, String callingPackage) {
1406 // must be *either* PendingIntent or AlarmReceiver, but not both
1407 if ((operation == null && directReceiver == null)
1408 || (operation != null && directReceiver != null)) {
1409 Slog.w(TAG, "Alarms must either supply a PendingIntent or an AlarmReceiver");
1410 // NB: previous releases failed silently here, so we are continuing to do the same
1411 // rather than throw an IllegalArgumentException.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001412 return;
1413 }
Christopher Tatee0a22b32013-07-11 14:43:13 -07001414
Christopher Tate57ceaaa2013-07-19 16:30:43 -07001415 // Sanity check the window length. This will catch people mistakenly
1416 // trying to pass an end-of-window timestamp rather than a duration.
1417 if (windowLength > AlarmManager.INTERVAL_HALF_DAY) {
1418 Slog.w(TAG, "Window length " + windowLength
1419 + "ms suspiciously long; limiting to 1 hour");
1420 windowLength = AlarmManager.INTERVAL_HOUR;
1421 }
1422
Christopher Tate498c6cb2014-11-17 16:09:27 -08001423 // Sanity check the recurrence interval. This will catch people who supply
1424 // seconds when the API expects milliseconds.
Dianne Hackborna750a632015-06-16 17:18:23 -07001425 final long minInterval = mConstants.MIN_INTERVAL;
1426 if (interval > 0 && interval < minInterval) {
Christopher Tate498c6cb2014-11-17 16:09:27 -08001427 Slog.w(TAG, "Suspiciously short interval " + interval
Dianne Hackborna750a632015-06-16 17:18:23 -07001428 + " millis; expanding to " + (minInterval/1000)
Christopher Tate498c6cb2014-11-17 16:09:27 -08001429 + " seconds");
Dianne Hackborna750a632015-06-16 17:18:23 -07001430 interval = minInterval;
Christopher Tate498c6cb2014-11-17 16:09:27 -08001431 }
1432
Christopher Tatee0a22b32013-07-11 14:43:13 -07001433 if (type < RTC_WAKEUP || type > ELAPSED_REALTIME) {
1434 throw new IllegalArgumentException("Invalid alarm type " + type);
1435 }
1436
Christopher Tate5f221e82013-07-30 17:13:15 -07001437 if (triggerAtTime < 0) {
Christopher Tate5f221e82013-07-30 17:13:15 -07001438 final long what = Binder.getCallingPid();
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07001439 Slog.w(TAG, "Invalid alarm trigger time! " + triggerAtTime + " from uid=" + callingUid
Christopher Tate5f221e82013-07-30 17:13:15 -07001440 + " pid=" + what);
1441 triggerAtTime = 0;
1442 }
1443
Christopher Tate57ceaaa2013-07-19 16:30:43 -07001444 final long nowElapsed = SystemClock.elapsedRealtime();
Christopher Tate498c6cb2014-11-17 16:09:27 -08001445 final long nominalTrigger = convertToElapsed(triggerAtTime, type);
1446 // Try to prevent spamming by making sure we aren't firing alarms in the immediate future
Dianne Hackborna750a632015-06-16 17:18:23 -07001447 final long minTrigger = nowElapsed + mConstants.MIN_FUTURITY;
Christopher Tate498c6cb2014-11-17 16:09:27 -08001448 final long triggerElapsed = (nominalTrigger > minTrigger) ? nominalTrigger : minTrigger;
1449
Christopher Tate57ceaaa2013-07-19 16:30:43 -07001450 final long maxElapsed;
1451 if (windowLength == AlarmManager.WINDOW_EXACT) {
1452 maxElapsed = triggerElapsed;
1453 } else if (windowLength < 0) {
1454 maxElapsed = maxTriggerTime(nowElapsed, triggerElapsed, interval);
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07001455 // Fix this window in place, so that as time approaches we don't collapse it.
1456 windowLength = maxElapsed - triggerElapsed;
Christopher Tate57ceaaa2013-07-19 16:30:43 -07001457 } else {
1458 maxElapsed = triggerElapsed + windowLength;
1459 }
Christopher Tatee0a22b32013-07-11 14:43:13 -07001460
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001461 synchronized (mLock) {
Christopher Tatee0a22b32013-07-11 14:43:13 -07001462 if (DEBUG_BATCH) {
1463 Slog.v(TAG, "set(" + operation + ") : type=" + type
Christopher Tate57ceaaa2013-07-19 16:30:43 -07001464 + " triggerAtTime=" + triggerAtTime + " win=" + windowLength
Christopher Tatee0a22b32013-07-11 14:43:13 -07001465 + " tElapsed=" + triggerElapsed + " maxElapsed=" + maxElapsed
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07001466 + " interval=" + interval + " flags=0x" + Integer.toHexString(flags));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001467 }
Christopher Tate3e04b472013-10-21 17:51:31 -07001468 setImplLocked(type, triggerAtTime, triggerElapsed, windowLength, maxElapsed,
Christopher Tate14a7bb02015-10-01 10:24:31 -07001469 interval, operation, directReceiver, listenerTag, flags, true, workSource,
1470 alarmClock, callingUid, callingPackage);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001471 }
1472 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001473
Christopher Tate3e04b472013-10-21 17:51:31 -07001474 private void setImplLocked(int type, long when, long whenElapsed, long windowLength,
Christopher Tate14a7bb02015-10-01 10:24:31 -07001475 long maxWhen, long interval, PendingIntent operation, IAlarmListener directReceiver,
1476 String listenerTag, int flags, boolean doValidate, WorkSource workSource,
1477 AlarmManager.AlarmClockInfo alarmClock, int callingUid, String callingPackage) {
Christopher Tate3e04b472013-10-21 17:51:31 -07001478 Alarm a = new Alarm(type, when, whenElapsed, windowLength, maxWhen, interval,
Christopher Tate14a7bb02015-10-01 10:24:31 -07001479 operation, directReceiver, listenerTag, workSource, flags, alarmClock,
1480 callingUid, callingPackage);
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001481 try {
Dianne Hackbornc3af19a2017-01-20 17:00:44 -08001482 if (ActivityManager.getService().isAppStartModeDisabled(callingUid, callingPackage)) {
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001483 Slog.w(TAG, "Not setting alarm from " + callingUid + ":" + a
1484 + " -- package not allowed to start");
1485 return;
1486 }
1487 } catch (RemoteException e) {
1488 }
Christopher Tate14a7bb02015-10-01 10:24:31 -07001489 removeLocked(operation, directReceiver);
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07001490 setImplLocked(a, false, doValidate);
1491 }
Christopher Tateb8849c12011-02-08 13:39:01 -08001492
Suprabh Shukla75edab12018-01-29 14:09:06 -08001493 private long getMinDelayForBucketLocked(int bucket) {
1494 // Return the minimum time that should elapse before an app in the specified bucket
1495 // can receive alarms again
1496 if (bucket == UsageStatsManager.STANDBY_BUCKET_NEVER) {
1497 return mConstants.APP_STANDBY_MIN_DELAYS[4];
1498 }
1499 else if (bucket >= UsageStatsManager.STANDBY_BUCKET_RARE) {
1500 return mConstants.APP_STANDBY_MIN_DELAYS[3];
1501 }
1502 else if (bucket >= UsageStatsManager.STANDBY_BUCKET_FREQUENT) {
1503 return mConstants.APP_STANDBY_MIN_DELAYS[2];
1504 }
1505 else if (bucket >= UsageStatsManager.STANDBY_BUCKET_WORKING_SET) {
1506 return mConstants.APP_STANDBY_MIN_DELAYS[1];
1507 }
1508 else return mConstants.APP_STANDBY_MIN_DELAYS[0];
1509 }
1510
Suprabh Shukla92994ab2018-01-31 17:39:30 -08001511 /**
1512 * Adjusts the alarm delivery time based on the current app standby bucket.
1513 * @param alarm The alarm to adjust
1514 * @return true if the alarm delivery time was updated.
Suprabh Shukla92994ab2018-01-31 17:39:30 -08001515 */
1516 private boolean adjustDeliveryTimeBasedOnStandbyBucketLocked(Alarm alarm) {
Suprabh Shuklad65e58a2018-02-05 20:36:08 -08001517 if (isExemptFromAppStandby(alarm)) {
Suprabh Shukla92994ab2018-01-31 17:39:30 -08001518 return false;
Suprabh Shukla75edab12018-01-29 14:09:06 -08001519 }
1520 if (mAppStandbyParole) {
Suprabh Shuklad65e58a2018-02-05 20:36:08 -08001521 if (alarm.whenElapsed > alarm.expectedWhenElapsed) {
Suprabh Shukla92994ab2018-01-31 17:39:30 -08001522 // We did defer this alarm earlier, restore original requirements
Suprabh Shuklad65e58a2018-02-05 20:36:08 -08001523 alarm.whenElapsed = alarm.expectedWhenElapsed;
1524 alarm.maxWhenElapsed = alarm.expectedMaxWhenElapsed;
1525 return true;
Suprabh Shukla75edab12018-01-29 14:09:06 -08001526 }
Suprabh Shuklad65e58a2018-02-05 20:36:08 -08001527 return false;
Suprabh Shukla75edab12018-01-29 14:09:06 -08001528 }
Suprabh Shukla92994ab2018-01-31 17:39:30 -08001529 final long oldWhenElapsed = alarm.whenElapsed;
1530 final long oldMaxWhenElapsed = alarm.maxWhenElapsed;
1531
Suprabh Shukla75edab12018-01-29 14:09:06 -08001532 final String sourcePackage = alarm.sourcePackage;
1533 final int sourceUserId = UserHandle.getUserId(alarm.creatorUid);
1534 final int standbyBucket = mUsageStatsManagerInternal.getAppStandbyBucket(
1535 sourcePackage, sourceUserId, SystemClock.elapsedRealtime());
1536
1537 final Pair<String, Integer> packageUser = Pair.create(sourcePackage, sourceUserId);
1538 final long lastElapsed = mLastAlarmDeliveredForPackage.getOrDefault(packageUser, 0L);
1539 if (lastElapsed > 0) {
1540 final long minElapsed = lastElapsed + getMinDelayForBucketLocked(standbyBucket);
Suprabh Shuklad65e58a2018-02-05 20:36:08 -08001541 if (alarm.expectedWhenElapsed < minElapsed) {
Suprabh Shukla75edab12018-01-29 14:09:06 -08001542 alarm.whenElapsed = alarm.maxWhenElapsed = minElapsed;
Suprabh Shukla92994ab2018-01-31 17:39:30 -08001543 } else {
1544 // app is now eligible to run alarms at the originally requested window.
1545 // Restore original requirements in case they were changed earlier.
Suprabh Shuklad65e58a2018-02-05 20:36:08 -08001546 alarm.whenElapsed = alarm.expectedWhenElapsed;
1547 alarm.maxWhenElapsed = alarm.expectedMaxWhenElapsed;
Suprabh Shukla75edab12018-01-29 14:09:06 -08001548 }
1549 }
Suprabh Shukla92994ab2018-01-31 17:39:30 -08001550 return (oldWhenElapsed != alarm.whenElapsed || oldMaxWhenElapsed != alarm.maxWhenElapsed);
Suprabh Shukla75edab12018-01-29 14:09:06 -08001551 }
1552
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07001553 private void setImplLocked(Alarm a, boolean rebatching, boolean doValidate) {
1554 if ((a.flags&AlarmManager.FLAG_IDLE_UNTIL) != 0) {
Dianne Hackbornf70faed2015-04-21 14:11:38 -07001555 // This is a special alarm that will put the system into idle until it goes off.
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07001556 // The caller has given the time they want this to happen at, however we need
1557 // to pull that earlier if there are existing alarms that have requested to
Dianne Hackbornf3831292015-10-15 14:51:06 -07001558 // bring us out of idle at an earlier time.
1559 if (mNextWakeFromIdle != null && a.whenElapsed > mNextWakeFromIdle.whenElapsed) {
Dianne Hackbornf70faed2015-04-21 14:11:38 -07001560 a.when = a.whenElapsed = a.maxWhenElapsed = mNextWakeFromIdle.whenElapsed;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07001561 }
1562 // Add fuzz to make the alarm go off some time before the actual desired time.
1563 final long nowElapsed = SystemClock.elapsedRealtime();
Dianne Hackbornf70faed2015-04-21 14:11:38 -07001564 final int fuzz = fuzzForDuration(a.whenElapsed-nowElapsed);
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07001565 if (fuzz > 0) {
1566 if (mRandom == null) {
1567 mRandom = new Random();
1568 }
Dianne Hackbornf70faed2015-04-21 14:11:38 -07001569 final int delta = mRandom.nextInt(fuzz);
1570 a.whenElapsed -= delta;
1571 if (false) {
1572 Slog.d(TAG, "Alarm when: " + a.whenElapsed);
1573 Slog.d(TAG, "Delta until alarm: " + (a.whenElapsed-nowElapsed));
1574 Slog.d(TAG, "Applied fuzz: " + fuzz);
1575 Slog.d(TAG, "Final delta: " + delta);
1576 Slog.d(TAG, "Final when: " + a.whenElapsed);
1577 }
1578 a.when = a.maxWhenElapsed = a.whenElapsed;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07001579 }
1580
1581 } else if (mPendingIdleUntil != null) {
1582 // We currently have an idle until alarm scheduled; if the new alarm has
1583 // not explicitly stated it wants to run while idle, then put it on hold.
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07001584 if ((a.flags&(AlarmManager.FLAG_ALLOW_WHILE_IDLE
1585 | AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED
1586 | AlarmManager.FLAG_WAKE_FROM_IDLE))
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07001587 == 0) {
1588 mPendingWhileIdleAlarms.add(a);
1589 return;
1590 }
1591 }
Dianne Hackbornae78bf82015-10-26 13:33:20 -07001592 if (RECORD_DEVICE_IDLE_ALARMS) {
1593 if ((a.flags & AlarmManager.FLAG_ALLOW_WHILE_IDLE) != 0) {
1594 IdleDispatchEntry ent = new IdleDispatchEntry();
1595 ent.uid = a.uid;
1596 ent.pkg = a.operation.getCreatorPackage();
1597 ent.tag = a.operation.getTag("");
1598 ent.op = "SET";
1599 ent.elapsedRealtime = SystemClock.elapsedRealtime();
1600 ent.argRealtime = a.whenElapsed;
1601 mAllowWhileIdleDispatches.add(ent);
1602 }
1603 }
Suprabh Shukla75edab12018-01-29 14:09:06 -08001604 adjustDeliveryTimeBasedOnStandbyBucketLocked(a);
Suprabh Shukla92994ab2018-01-31 17:39:30 -08001605 insertAndBatchAlarmLocked(a);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001606
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07001607 if (a.alarmClock != null) {
Adrian Roosc42a1e12014-07-07 23:35:53 +02001608 mNextAlarmClockMayChange = true;
Adrian Roosc42a1e12014-07-07 23:35:53 +02001609 }
1610
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07001611 boolean needRebatch = false;
1612
1613 if ((a.flags&AlarmManager.FLAG_IDLE_UNTIL) != 0) {
Dianne Hackbornae78bf82015-10-26 13:33:20 -07001614 if (RECORD_DEVICE_IDLE_ALARMS) {
1615 if (mPendingIdleUntil == null) {
1616 IdleDispatchEntry ent = new IdleDispatchEntry();
1617 ent.uid = 0;
1618 ent.pkg = "START IDLE";
1619 ent.elapsedRealtime = SystemClock.elapsedRealtime();
1620 mAllowWhileIdleDispatches.add(ent);
1621 }
1622 }
Makoto Onuki4274a6d2017-04-21 12:21:25 -07001623 if ((mPendingIdleUntil != a) && (mPendingIdleUntil != null)) {
1624 Slog.wtfStack(TAG, "setImplLocked: idle until changed from " + mPendingIdleUntil
1625 + " to " + a);
1626 }
1627
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07001628 mPendingIdleUntil = a;
1629 needRebatch = true;
Dianne Hackbornf70faed2015-04-21 14:11:38 -07001630 } else if ((a.flags&AlarmManager.FLAG_WAKE_FROM_IDLE) != 0) {
1631 if (mNextWakeFromIdle == null || mNextWakeFromIdle.whenElapsed > a.whenElapsed) {
1632 mNextWakeFromIdle = a;
1633 // If this wake from idle is earlier than whatever was previously scheduled,
1634 // and we are currently idling, then we need to rebatch alarms in case the idle
1635 // until time needs to be updated.
1636 if (mPendingIdleUntil != null) {
1637 needRebatch = true;
1638 }
1639 }
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07001640 }
1641
1642 if (!rebatching) {
1643 if (DEBUG_VALIDATE) {
1644 if (doValidate && !validateConsistencyLocked()) {
1645 Slog.v(TAG, "Tipping-point operation: type=" + a.type + " when=" + a.when
1646 + " when(hex)=" + Long.toHexString(a.when)
1647 + " whenElapsed=" + a.whenElapsed
1648 + " maxWhenElapsed=" + a.maxWhenElapsed
1649 + " interval=" + a.repeatInterval + " op=" + a.operation
1650 + " flags=0x" + Integer.toHexString(a.flags));
1651 rebatchAllAlarmsLocked(false);
1652 needRebatch = false;
1653 }
1654 }
1655
1656 if (needRebatch) {
Christopher Tate4cb338d2013-07-26 13:11:31 -07001657 rebatchAllAlarmsLocked(false);
Christopher Tate4cb338d2013-07-26 13:11:31 -07001658 }
Christopher Tate4cb338d2013-07-26 13:11:31 -07001659
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07001660 rescheduleKernelAlarmsLocked();
1661 updateNextAlarmClockLocked();
1662 }
Christopher Tatee0a22b32013-07-11 14:43:13 -07001663 }
1664
Christopher Tate1d99c392017-12-07 16:54:04 -08001665 /**
1666 * System-process internal API
1667 */
1668 private final class LocalService implements AlarmManagerInternal {
1669 @Override
1670 public void removeAlarmsForUid(int uid) {
1671 synchronized (mLock) {
1672 removeLocked(uid);
1673 }
1674 }
1675 }
1676
1677 /**
1678 * Public-facing binder interface
1679 */
Adam Lesinski182f73f2013-12-05 16:48:06 -08001680 private final IBinder mService = new IAlarmManager.Stub() {
1681 @Override
Christopher Tate14a7bb02015-10-01 10:24:31 -07001682 public void set(String callingPackage,
1683 int type, long triggerAtTime, long windowLength, long interval, int flags,
1684 PendingIntent operation, IAlarmListener directReceiver, String listenerTag,
1685 WorkSource workSource, AlarmManager.AlarmClockInfo alarmClock) {
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07001686 final int callingUid = Binder.getCallingUid();
Christopher Tate14a7bb02015-10-01 10:24:31 -07001687
1688 // make sure the caller is not lying about which package should be blamed for
1689 // wakelock time spent in alarm delivery
1690 mAppOps.checkPackage(callingUid, callingPackage);
1691
1692 // Repeating alarms must use PendingIntent, not direct listener
1693 if (interval != 0) {
1694 if (directReceiver != null) {
1695 throw new IllegalArgumentException("Repeating alarms cannot use AlarmReceivers");
1696 }
1697 }
1698
Adam Lesinski182f73f2013-12-05 16:48:06 -08001699 if (workSource != null) {
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07001700 getContext().enforcePermission(
Adam Lesinski182f73f2013-12-05 16:48:06 -08001701 android.Manifest.permission.UPDATE_DEVICE_STATS,
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07001702 Binder.getCallingPid(), callingUid, "AlarmManager.set");
Christopher Tate89779822012-08-31 14:40:03 -07001703 }
1704
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07001705 // No incoming callers can request either WAKE_FROM_IDLE or
1706 // ALLOW_WHILE_IDLE_UNRESTRICTED -- we will apply those later as appropriate.
1707 flags &= ~(AlarmManager.FLAG_WAKE_FROM_IDLE
1708 | AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED);
1709
1710 // Only the system can use FLAG_IDLE_UNTIL -- this is used to tell the alarm
1711 // manager when to come out of idle mode, which is only for DeviceIdleController.
1712 if (callingUid != Process.SYSTEM_UID) {
1713 flags &= ~AlarmManager.FLAG_IDLE_UNTIL;
1714 }
1715
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07001716 // If this is an exact time alarm, then it can't be batched with other alarms.
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07001717 if (windowLength == AlarmManager.WINDOW_EXACT) {
1718 flags |= AlarmManager.FLAG_STANDALONE;
1719 }
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07001720
1721 // If this alarm is for an alarm clock, then it must be standalone and we will
1722 // use it to wake early from idle if needed.
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07001723 if (alarmClock != null) {
1724 flags |= AlarmManager.FLAG_WAKE_FROM_IDLE | AlarmManager.FLAG_STANDALONE;
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08001725
1726 // If the caller is a core system component or on the user's whitelist, and not calling
1727 // to do work on behalf of someone else, then always set ALLOW_WHILE_IDLE_UNRESTRICTED.
1728 // This means we will allow these alarms to go off as normal even while idle, with no
1729 // timing restrictions.
1730 } else if (workSource == null && (callingUid < Process.FIRST_APPLICATION_UID
Suprabh Shuklad65e58a2018-02-05 20:36:08 -08001731 || UserHandle.isSameApp(callingUid, mSystemUiUid)
Makoto Onukie4918212018-02-06 11:30:15 -08001732 || ((mAppStateTracker != null)
1733 && mAppStateTracker.isUidPowerSaveWhitelisted(callingUid)))) {
Dianne Hackborn262ae5c2016-02-10 16:28:29 -08001734 flags |= AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
1735 flags &= ~AlarmManager.FLAG_ALLOW_WHILE_IDLE;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07001736 }
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07001737
Christopher Tate14a7bb02015-10-01 10:24:31 -07001738 setImpl(type, triggerAtTime, windowLength, interval, operation, directReceiver,
1739 listenerTag, flags, workSource, alarmClock, callingUid, callingPackage);
Adam Lesinski182f73f2013-12-05 16:48:06 -08001740 }
Christopher Tate89779822012-08-31 14:40:03 -07001741
Adam Lesinski182f73f2013-12-05 16:48:06 -08001742 @Override
Greg Hackmann0cab8962014-02-21 16:35:52 -08001743 public boolean setTime(long millis) {
Adam Lesinski182f73f2013-12-05 16:48:06 -08001744 getContext().enforceCallingOrSelfPermission(
1745 "android.permission.SET_TIME",
1746 "setTime");
1747
Greg Hackmann0cab8962014-02-21 16:35:52 -08001748 if (mNativeData == 0) {
1749 Slog.w(TAG, "Not setting time since no alarm driver is available.");
1750 return false;
Christopher Tate89779822012-08-31 14:40:03 -07001751 }
Greg Hackmann0cab8962014-02-21 16:35:52 -08001752
1753 synchronized (mLock) {
1754 return setKernelTime(mNativeData, millis) == 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001755 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001756 }
Adam Lesinski182f73f2013-12-05 16:48:06 -08001757
1758 @Override
1759 public void setTimeZone(String tz) {
1760 getContext().enforceCallingOrSelfPermission(
1761 "android.permission.SET_TIME_ZONE",
1762 "setTimeZone");
1763
1764 final long oldId = Binder.clearCallingIdentity();
1765 try {
1766 setTimeZoneImpl(tz);
1767 } finally {
1768 Binder.restoreCallingIdentity(oldId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001769 }
1770 }
Christopher Tate4cb338d2013-07-26 13:11:31 -07001771
Adam Lesinski182f73f2013-12-05 16:48:06 -08001772 @Override
Christopher Tate14a7bb02015-10-01 10:24:31 -07001773 public void remove(PendingIntent operation, IAlarmListener listener) {
1774 if (operation == null && listener == null) {
1775 Slog.w(TAG, "remove() with no intent or listener");
1776 return;
1777 }
Dianne Hackborn80a4af22012-08-27 19:18:31 -07001778
Christopher Tate14a7bb02015-10-01 10:24:31 -07001779 synchronized (mLock) {
1780 removeLocked(operation, listener);
1781 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001782 }
Christopher Tate4cb338d2013-07-26 13:11:31 -07001783
Adam Lesinski182f73f2013-12-05 16:48:06 -08001784 @Override
Dianne Hackbornf70faed2015-04-21 14:11:38 -07001785 public long getNextWakeFromIdleTime() {
1786 return getNextWakeFromIdleTimeImpl();
1787 }
1788
1789 @Override
Jose Lima235510e2014-08-13 12:50:01 -07001790 public AlarmManager.AlarmClockInfo getNextAlarmClock(int userId) {
Adrian Roosc42a1e12014-07-07 23:35:53 +02001791 userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
1792 Binder.getCallingUid(), userId, false /* allowAll */, false /* requireFull */,
1793 "getNextAlarmClock", null);
1794
1795 return getNextAlarmClockImpl(userId);
1796 }
1797
1798 @Override
Jeff Sharkey9911a282018-02-14 22:29:11 -07001799 public long currentNetworkTimeMillis() {
1800 final NtpTrustedTime time = NtpTrustedTime.getInstance(getContext());
1801 if (time.hasCache()) {
1802 return time.currentTimeMillis();
1803 } else {
1804 throw new ParcelableException(new DateTimeException("Missing NTP fix"));
1805 }
1806 }
1807
1808 @Override
Adam Lesinski182f73f2013-12-05 16:48:06 -08001809 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Jeff Sharkey6df866a2017-03-31 14:08:23 -06001810 if (!DumpUtils.checkDumpAndUsageStatsPermission(getContext(), TAG, pw)) return;
Kweku Adams61e03292017-10-19 14:27:12 -07001811
1812 if (args.length > 0 && "--proto".equals(args[0])) {
1813 dumpProto(fd);
1814 } else {
1815 dumpImpl(pw);
1816 }
Dianne Hackborn80a4af22012-08-27 19:18:31 -07001817 }
Adam Lesinski182f73f2013-12-05 16:48:06 -08001818 };
Christopher Tate4cb338d2013-07-26 13:11:31 -07001819
Adam Lesinski182f73f2013-12-05 16:48:06 -08001820 void dumpImpl(PrintWriter pw) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001821 synchronized (mLock) {
1822 pw.println("Current Alarm Manager state:");
Dianne Hackborna750a632015-06-16 17:18:23 -07001823 mConstants.dump(pw);
1824 pw.println();
1825
Makoto Onukie4918212018-02-06 11:30:15 -08001826 if (mAppStateTracker != null) {
1827 mAppStateTracker.dump(pw, " ");
1828 pw.println();
1829 }
Makoto Onuki2206af32017-11-21 16:25:35 -08001830
Suprabh Shukla75edab12018-01-29 14:09:06 -08001831 pw.println(" App Standby Parole: " + mAppStandbyParole);
1832 pw.println();
1833
Christopher Tatee0a22b32013-07-11 14:43:13 -07001834 final long nowRTC = System.currentTimeMillis();
1835 final long nowELAPSED = SystemClock.elapsedRealtime();
Makoto Onuki5d93b832018-01-10 16:12:39 -08001836 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
Christopher Tatee0a22b32013-07-11 14:43:13 -07001837
Dianne Hackborna750a632015-06-16 17:18:23 -07001838 pw.print(" nowRTC="); pw.print(nowRTC);
Christopher Tatee0a22b32013-07-11 14:43:13 -07001839 pw.print("="); pw.print(sdf.format(new Date(nowRTC)));
Christopher Tate7f2a0352015-12-08 10:24:33 -08001840 pw.print(" nowELAPSED="); pw.print(nowELAPSED);
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07001841 pw.println();
Dianne Hackborna750a632015-06-16 17:18:23 -07001842 pw.print(" mLastTimeChangeClockTime="); pw.print(mLastTimeChangeClockTime);
Dianne Hackbornc3527222015-05-13 14:03:20 -07001843 pw.print("="); pw.println(sdf.format(new Date(mLastTimeChangeClockTime)));
Christopher Tate12cf0b62018-01-05 18:40:14 -08001844 pw.print(" mLastTimeChangeRealtime="); pw.println(mLastTimeChangeRealtime);
1845 pw.print(" mLastTickIssued=");
Makoto Onuki5d93b832018-01-10 16:12:39 -08001846 pw.println(sdf.format(new Date(nowRTC - (nowELAPSED - mLastTickIssued))));
Christopher Tate12cf0b62018-01-05 18:40:14 -08001847 pw.print(" mLastTickReceived="); pw.println(sdf.format(new Date(mLastTickReceived)));
1848 pw.print(" mLastTickSet="); pw.println(sdf.format(new Date(mLastTickSet)));
Makoto Onuki5d93b832018-01-10 16:12:39 -08001849 pw.print(" mLastTickAdded="); pw.println(sdf.format(new Date(mLastTickAdded)));
1850 pw.print(" mLastTickRemoved="); pw.println(sdf.format(new Date(mLastTickRemoved)));
Dianne Hackbornc3527222015-05-13 14:03:20 -07001851 pw.println();
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07001852 if (!mInteractive) {
Dianne Hackborna750a632015-06-16 17:18:23 -07001853 pw.print(" Time since non-interactive: ");
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07001854 TimeUtils.formatDuration(nowELAPSED - mNonInteractiveStartTime, pw);
1855 pw.println();
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07001856 }
Makoto Onuki0b05aa62018-02-09 16:14:26 -08001857 pw.print(" Max wakeup delay: ");
1858 TimeUtils.formatDuration(currentNonWakeupFuzzLocked(nowELAPSED), pw);
1859 pw.println();
1860 pw.print(" Time since last dispatch: ");
1861 TimeUtils.formatDuration(nowELAPSED - mLastAlarmDeliveryTime, pw);
1862 pw.println();
1863 pw.print(" Next non-wakeup delivery time: ");
1864 TimeUtils.formatDuration(nowELAPSED - mNextNonWakeupDeliveryTime, pw);
1865 pw.println();
Christopher Tatee0a22b32013-07-11 14:43:13 -07001866
1867 long nextWakeupRTC = mNextWakeup + (nowRTC - nowELAPSED);
1868 long nextNonWakeupRTC = mNextNonWakeup + (nowRTC - nowELAPSED);
Dianne Hackborna750a632015-06-16 17:18:23 -07001869 pw.print(" Next non-wakeup alarm: ");
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07001870 TimeUtils.formatDuration(mNextNonWakeup, nowELAPSED, pw);
Christopher Tate8b98ade2018-02-09 11:13:19 -08001871 pw.print(" = "); pw.print(mNextNonWakeup);
Christopher Tatee0a22b32013-07-11 14:43:13 -07001872 pw.print(" = "); pw.println(sdf.format(new Date(nextNonWakeupRTC)));
Christopher Tate8b98ade2018-02-09 11:13:19 -08001873 pw.print(" Next wakeup alarm: "); TimeUtils.formatDuration(mNextWakeup, nowELAPSED, pw);
1874 pw.print(" = "); pw.print(mNextWakeup);
Christopher Tatee0a22b32013-07-11 14:43:13 -07001875 pw.print(" = "); pw.println(sdf.format(new Date(nextWakeupRTC)));
Christopher Tate8b98ade2018-02-09 11:13:19 -08001876 pw.print(" set at "); TimeUtils.formatDuration(mLastWakeupSet, nowELAPSED, pw);
1877 pw.println();
Dianne Hackbornaa9a59d2016-05-23 15:59:18 -07001878 pw.print(" Last wakeup: "); TimeUtils.formatDuration(mLastWakeup, nowELAPSED, pw);
Christopher Tate8b98ade2018-02-09 11:13:19 -08001879 pw.print(" = "); pw.println(mLastWakeup);
1880 pw.print(" Last trigger: "); TimeUtils.formatDuration(mLastTrigger, nowELAPSED, pw);
1881 pw.print(" = "); pw.println(mLastTrigger);
Dianne Hackborna750a632015-06-16 17:18:23 -07001882 pw.print(" Num time change events: "); pw.println(mNumTimeChanged);
Christopher Tatee0a22b32013-07-11 14:43:13 -07001883
John Spurlock604a5ee2015-06-01 12:27:22 -04001884 pw.println();
Dianne Hackborna750a632015-06-16 17:18:23 -07001885 pw.println(" Next alarm clock information: ");
John Spurlock604a5ee2015-06-01 12:27:22 -04001886 final TreeSet<Integer> users = new TreeSet<>();
1887 for (int i = 0; i < mNextAlarmClockForUser.size(); i++) {
1888 users.add(mNextAlarmClockForUser.keyAt(i));
1889 }
1890 for (int i = 0; i < mPendingSendNextAlarmClockChangedForUser.size(); i++) {
1891 users.add(mPendingSendNextAlarmClockChangedForUser.keyAt(i));
1892 }
1893 for (int user : users) {
1894 final AlarmManager.AlarmClockInfo next = mNextAlarmClockForUser.get(user);
1895 final long time = next != null ? next.getTriggerTime() : 0;
1896 final boolean pendingSend = mPendingSendNextAlarmClockChangedForUser.get(user);
Dianne Hackborna750a632015-06-16 17:18:23 -07001897 pw.print(" user:"); pw.print(user);
John Spurlock604a5ee2015-06-01 12:27:22 -04001898 pw.print(" pendingSend:"); pw.print(pendingSend);
1899 pw.print(" time:"); pw.print(time);
1900 if (time > 0) {
1901 pw.print(" = "); pw.print(sdf.format(new Date(time)));
1902 pw.print(" = "); TimeUtils.formatDuration(time, nowRTC, pw);
1903 }
1904 pw.println();
1905 }
Christopher Tatee0a22b32013-07-11 14:43:13 -07001906 if (mAlarmBatches.size() > 0) {
1907 pw.println();
Dianne Hackborna750a632015-06-16 17:18:23 -07001908 pw.print(" Pending alarm batches: ");
Christopher Tatee0a22b32013-07-11 14:43:13 -07001909 pw.println(mAlarmBatches.size());
1910 for (Batch b : mAlarmBatches) {
1911 pw.print(b); pw.println(':');
Dianne Hackborna750a632015-06-16 17:18:23 -07001912 dumpAlarmList(pw, b.alarms, " ", nowELAPSED, nowRTC, sdf);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001913 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001914 }
Suprabh Shukladb6bf662017-08-30 15:41:53 -07001915 pw.println();
1916 pw.println(" Pending user blocked background alarms: ");
1917 boolean blocked = false;
1918 for (int i = 0; i < mPendingBackgroundAlarms.size(); i++) {
1919 final ArrayList<Alarm> blockedAlarms = mPendingBackgroundAlarms.valueAt(i);
1920 if (blockedAlarms != null && blockedAlarms.size() > 0) {
1921 blocked = true;
1922 dumpAlarmList(pw, blockedAlarms, " ", nowELAPSED, nowRTC, sdf);
1923 }
1924 }
1925 if (!blocked) {
1926 pw.println(" none");
1927 }
Suprabh Shuklac25447d2018-01-19 16:43:35 -08001928
Suprabh Shukla75edab12018-01-29 14:09:06 -08001929 pw.println(" mLastAlarmDeliveredForPackage:");
1930 for (int i = 0; i < mLastAlarmDeliveredForPackage.size(); i++) {
1931 Pair<String, Integer> packageUser = mLastAlarmDeliveredForPackage.keyAt(i);
1932 pw.print(" Package " + packageUser.first + ", User " + packageUser.second + ":");
1933 TimeUtils.formatDuration(mLastAlarmDeliveredForPackage.valueAt(i), nowELAPSED, pw);
1934 pw.println();
1935 }
1936 pw.println();
1937
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001938 if (mPendingIdleUntil != null || mPendingWhileIdleAlarms.size() > 0) {
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07001939 pw.println();
Dianne Hackborna750a632015-06-16 17:18:23 -07001940 pw.println(" Idle mode state:");
1941 pw.print(" Idling until: ");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001942 if (mPendingIdleUntil != null) {
1943 pw.println(mPendingIdleUntil);
Kweku Adams61e03292017-10-19 14:27:12 -07001944 mPendingIdleUntil.dump(pw, " ", nowELAPSED, nowRTC, sdf);
Dianne Hackborn0b4daca2015-04-27 09:47:32 -07001945 } else {
1946 pw.println("null");
1947 }
Dianne Hackborna750a632015-06-16 17:18:23 -07001948 pw.println(" Pending alarms:");
1949 dumpAlarmList(pw, mPendingWhileIdleAlarms, " ", nowELAPSED, nowRTC, sdf);
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07001950 }
Dianne Hackbornf70faed2015-04-21 14:11:38 -07001951 if (mNextWakeFromIdle != null) {
1952 pw.println();
1953 pw.print(" Next wake from idle: "); pw.println(mNextWakeFromIdle);
Kweku Adams61e03292017-10-19 14:27:12 -07001954 mNextWakeFromIdle.dump(pw, " ", nowELAPSED, nowRTC, sdf);
Dianne Hackbornf70faed2015-04-21 14:11:38 -07001955 }
Dianne Hackborn81038902012-11-26 17:04:09 -08001956
1957 pw.println();
Dianne Hackborna750a632015-06-16 17:18:23 -07001958 pw.print(" Past-due non-wakeup alarms: ");
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07001959 if (mPendingNonWakeupAlarms.size() > 0) {
1960 pw.println(mPendingNonWakeupAlarms.size());
Dianne Hackborna750a632015-06-16 17:18:23 -07001961 dumpAlarmList(pw, mPendingNonWakeupAlarms, " ", nowELAPSED, nowRTC, sdf);
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07001962 } else {
1963 pw.println("(none)");
1964 }
Dianne Hackborna750a632015-06-16 17:18:23 -07001965 pw.print(" Number of delayed alarms: "); pw.print(mNumDelayedAlarms);
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07001966 pw.print(", total delay time: "); TimeUtils.formatDuration(mTotalDelayTime, pw);
1967 pw.println();
Dianne Hackborna750a632015-06-16 17:18:23 -07001968 pw.print(" Max delay time: "); TimeUtils.formatDuration(mMaxDelayTime, pw);
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07001969 pw.print(", max non-interactive time: ");
1970 TimeUtils.formatDuration(mNonInteractiveTime, pw);
1971 pw.println();
1972
1973 pw.println();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07001974 pw.print(" Broadcast ref count: "); pw.println(mBroadcastRefCount);
Christopher Tateeabba732017-08-17 17:12:52 -07001975 pw.print(" PendingIntent send count: "); pw.println(mSendCount);
1976 pw.print(" PendingIntent finish count: "); pw.println(mSendFinishCount);
1977 pw.print(" Listener send count: "); pw.println(mListenerCount);
1978 pw.print(" Listener finish count: "); pw.println(mListenerFinishCount);
Dianne Hackborn81038902012-11-26 17:04:09 -08001979 pw.println();
1980
Christopher Tate7f2a0352015-12-08 10:24:33 -08001981 if (mInFlight.size() > 0) {
1982 pw.println("Outstanding deliveries:");
1983 for (int i = 0; i < mInFlight.size(); i++) {
1984 pw.print(" #"); pw.print(i); pw.print(": ");
1985 pw.println(mInFlight.get(i));
1986 }
1987 pw.println();
1988 }
1989
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07001990 if (mLastAllowWhileIdleDispatch.size() > 0) {
Dianne Hackborna750a632015-06-16 17:18:23 -07001991 pw.println(" Last allow while idle dispatch times:");
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07001992 for (int i=0; i<mLastAllowWhileIdleDispatch.size(); i++) {
Makoto Onukiadb50d82018-01-29 16:20:30 -08001993 pw.print(" UID ");
1994 final int uid = mLastAllowWhileIdleDispatch.keyAt(i);
1995 UserHandle.formatUid(pw, uid);
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07001996 pw.print(": ");
Makoto Onukiadb50d82018-01-29 16:20:30 -08001997 final long lastTime = mLastAllowWhileIdleDispatch.valueAt(i);
1998 TimeUtils.formatDuration(lastTime, nowELAPSED, pw);
1999
2000 final long minInterval = getWhileIdleMinIntervalLocked(uid);
2001 pw.print(" Next allowed:");
2002 TimeUtils.formatDuration(lastTime + minInterval, nowELAPSED, pw);
2003 pw.print(" (");
2004 TimeUtils.formatDuration(minInterval, 0, pw);
2005 pw.print(")");
2006
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07002007 pw.println();
2008 }
2009 }
Makoto Onukiadb50d82018-01-29 16:20:30 -08002010
2011 pw.print(" mUseAllowWhileIdleShortTime: [");
2012 for (int i = 0; i < mUseAllowWhileIdleShortTime.size(); i++) {
2013 if (mUseAllowWhileIdleShortTime.valueAt(i)) {
2014 UserHandle.formatUid(pw, mUseAllowWhileIdleShortTime.keyAt(i));
2015 pw.print(" ");
2016 }
2017 }
2018 pw.println("]");
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07002019 pw.println();
2020
Dianne Hackborn81038902012-11-26 17:04:09 -08002021 if (mLog.dump(pw, " Recent problems", " ")) {
2022 pw.println();
2023 }
2024
2025 final FilterStats[] topFilters = new FilterStats[10];
2026 final Comparator<FilterStats> comparator = new Comparator<FilterStats>() {
2027 @Override
2028 public int compare(FilterStats lhs, FilterStats rhs) {
2029 if (lhs.aggregateTime < rhs.aggregateTime) {
2030 return 1;
2031 } else if (lhs.aggregateTime > rhs.aggregateTime) {
2032 return -1;
2033 }
2034 return 0;
2035 }
2036 };
2037 int len = 0;
Kweku Adams61e03292017-10-19 14:27:12 -07002038 // Get the top 10 FilterStats, ordered by aggregateTime.
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002039 for (int iu=0; iu<mBroadcastStats.size(); iu++) {
2040 ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(iu);
2041 for (int ip=0; ip<uidStats.size(); ip++) {
2042 BroadcastStats bs = uidStats.valueAt(ip);
2043 for (int is=0; is<bs.filterStats.size(); is++) {
2044 FilterStats fs = bs.filterStats.valueAt(is);
2045 int pos = len > 0
2046 ? Arrays.binarySearch(topFilters, 0, len, fs, comparator) : 0;
2047 if (pos < 0) {
2048 pos = -pos - 1;
Dianne Hackborn81038902012-11-26 17:04:09 -08002049 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002050 if (pos < topFilters.length) {
2051 int copylen = topFilters.length - pos - 1;
2052 if (copylen > 0) {
2053 System.arraycopy(topFilters, pos, topFilters, pos+1, copylen);
2054 }
2055 topFilters[pos] = fs;
2056 if (len < topFilters.length) {
2057 len++;
2058 }
Dianne Hackborn81038902012-11-26 17:04:09 -08002059 }
2060 }
2061 }
2062 }
2063 if (len > 0) {
2064 pw.println(" Top Alarms:");
2065 for (int i=0; i<len; i++) {
2066 FilterStats fs = topFilters[i];
2067 pw.print(" ");
2068 if (fs.nesting > 0) pw.print("*ACTIVE* ");
2069 TimeUtils.formatDuration(fs.aggregateTime, pw);
2070 pw.print(" running, "); pw.print(fs.numWakeup);
2071 pw.print(" wakeups, "); pw.print(fs.count);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002072 pw.print(" alarms: "); UserHandle.formatUid(pw, fs.mBroadcastStats.mUid);
2073 pw.print(":"); pw.print(fs.mBroadcastStats.mPackageName);
Dianne Hackborn81038902012-11-26 17:04:09 -08002074 pw.println();
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07002075 pw.print(" "); pw.print(fs.mTag);
Dianne Hackborn81038902012-11-26 17:04:09 -08002076 pw.println();
2077 }
2078 }
2079
2080 pw.println(" ");
2081 pw.println(" Alarm Stats:");
2082 final ArrayList<FilterStats> tmpFilters = new ArrayList<FilterStats>();
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002083 for (int iu=0; iu<mBroadcastStats.size(); iu++) {
2084 ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(iu);
2085 for (int ip=0; ip<uidStats.size(); ip++) {
2086 BroadcastStats bs = uidStats.valueAt(ip);
2087 pw.print(" ");
2088 if (bs.nesting > 0) pw.print("*ACTIVE* ");
2089 UserHandle.formatUid(pw, bs.mUid);
2090 pw.print(":");
2091 pw.print(bs.mPackageName);
2092 pw.print(" "); TimeUtils.formatDuration(bs.aggregateTime, pw);
2093 pw.print(" running, "); pw.print(bs.numWakeup);
2094 pw.println(" wakeups:");
2095 tmpFilters.clear();
2096 for (int is=0; is<bs.filterStats.size(); is++) {
2097 tmpFilters.add(bs.filterStats.valueAt(is));
2098 }
2099 Collections.sort(tmpFilters, comparator);
2100 for (int i=0; i<tmpFilters.size(); i++) {
2101 FilterStats fs = tmpFilters.get(i);
2102 pw.print(" ");
2103 if (fs.nesting > 0) pw.print("*ACTIVE* ");
2104 TimeUtils.formatDuration(fs.aggregateTime, pw);
2105 pw.print(" "); pw.print(fs.numWakeup);
2106 pw.print(" wakes " ); pw.print(fs.count);
Dianne Hackbornf70faed2015-04-21 14:11:38 -07002107 pw.print(" alarms, last ");
2108 TimeUtils.formatDuration(fs.lastTime, nowELAPSED, pw);
2109 pw.println(":");
2110 pw.print(" ");
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07002111 pw.print(fs.mTag);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002112 pw.println();
2113 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002114 }
2115 }
Suprabh Shukla75edab12018-01-29 14:09:06 -08002116 pw.println();
2117 mStatLogger.dump(pw, " ");
Christopher Tate18a75f12013-07-01 18:18:59 -07002118
Dianne Hackbornae78bf82015-10-26 13:33:20 -07002119 if (RECORD_DEVICE_IDLE_ALARMS) {
2120 pw.println();
2121 pw.println(" Allow while idle dispatches:");
2122 for (int i = 0; i < mAllowWhileIdleDispatches.size(); i++) {
2123 IdleDispatchEntry ent = mAllowWhileIdleDispatches.get(i);
2124 pw.print(" ");
2125 TimeUtils.formatDuration(ent.elapsedRealtime, nowELAPSED, pw);
2126 pw.print(": ");
2127 UserHandle.formatUid(pw, ent.uid);
2128 pw.print(":");
2129 pw.println(ent.pkg);
2130 if (ent.op != null) {
2131 pw.print(" ");
2132 pw.print(ent.op);
2133 pw.print(" / ");
2134 pw.print(ent.tag);
2135 if (ent.argRealtime != 0) {
2136 pw.print(" (");
2137 TimeUtils.formatDuration(ent.argRealtime, nowELAPSED, pw);
2138 pw.print(")");
2139 }
2140 pw.println();
2141 }
2142 }
2143 }
2144
Christopher Tate18a75f12013-07-01 18:18:59 -07002145 if (WAKEUP_STATS) {
2146 pw.println();
2147 pw.println(" Recent Wakeup History:");
Christopher Tate18a75f12013-07-01 18:18:59 -07002148 long last = -1;
2149 for (WakeupEvent event : mRecentWakeups) {
2150 pw.print(" "); pw.print(sdf.format(new Date(event.when)));
2151 pw.print('|');
2152 if (last < 0) {
2153 pw.print('0');
2154 } else {
2155 pw.print(event.when - last);
2156 }
2157 last = event.when;
2158 pw.print('|'); pw.print(event.uid);
2159 pw.print('|'); pw.print(event.action);
2160 pw.println();
2161 }
2162 pw.println();
2163 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002164 }
2165 }
2166
Kweku Adams61e03292017-10-19 14:27:12 -07002167 void dumpProto(FileDescriptor fd) {
2168 final ProtoOutputStream proto = new ProtoOutputStream(fd);
2169
2170 synchronized (mLock) {
2171 final long nowRTC = System.currentTimeMillis();
2172 final long nowElapsed = SystemClock.elapsedRealtime();
2173 proto.write(AlarmManagerServiceProto.CURRENT_TIME, nowRTC);
2174 proto.write(AlarmManagerServiceProto.ELAPSED_REALTIME, nowElapsed);
2175 proto.write(AlarmManagerServiceProto.LAST_TIME_CHANGE_CLOCK_TIME,
2176 mLastTimeChangeClockTime);
2177 proto.write(AlarmManagerServiceProto.LAST_TIME_CHANGE_REALTIME,
2178 mLastTimeChangeRealtime);
2179
2180 mConstants.dumpProto(proto, AlarmManagerServiceProto.SETTINGS);
2181
Makoto Onukie4918212018-02-06 11:30:15 -08002182 if (mAppStateTracker != null) {
2183 mAppStateTracker.dumpProto(proto,
2184 AlarmManagerServiceProto.FORCE_APP_STANDBY_TRACKER);
2185 }
Kweku Adams61e03292017-10-19 14:27:12 -07002186
2187 proto.write(AlarmManagerServiceProto.IS_INTERACTIVE, mInteractive);
2188 if (!mInteractive) {
2189 // Durations
2190 proto.write(AlarmManagerServiceProto.TIME_SINCE_NON_INTERACTIVE_MS,
2191 nowElapsed - mNonInteractiveStartTime);
2192 proto.write(AlarmManagerServiceProto.MAX_WAKEUP_DELAY_MS,
2193 currentNonWakeupFuzzLocked(nowElapsed));
2194 proto.write(AlarmManagerServiceProto.TIME_SINCE_LAST_DISPATCH_MS,
2195 nowElapsed - mLastAlarmDeliveryTime);
2196 proto.write(AlarmManagerServiceProto.TIME_UNTIL_NEXT_NON_WAKEUP_DELIVERY_MS,
2197 nowElapsed - mNextNonWakeupDeliveryTime);
2198 }
2199
2200 proto.write(AlarmManagerServiceProto.TIME_UNTIL_NEXT_NON_WAKEUP_ALARM_MS,
2201 mNextNonWakeup - nowElapsed);
2202 proto.write(AlarmManagerServiceProto.TIME_UNTIL_NEXT_WAKEUP_MS,
2203 mNextWakeup - nowElapsed);
2204 proto.write(AlarmManagerServiceProto.TIME_SINCE_LAST_WAKEUP_MS,
2205 nowElapsed - mLastWakeup);
2206 proto.write(AlarmManagerServiceProto.TIME_SINCE_LAST_WAKEUP_SET_MS,
2207 nowElapsed - mLastWakeupSet);
2208 proto.write(AlarmManagerServiceProto.TIME_CHANGE_EVENT_COUNT, mNumTimeChanged);
Kweku Adams61e03292017-10-19 14:27:12 -07002209
2210 final TreeSet<Integer> users = new TreeSet<>();
2211 final int nextAlarmClockForUserSize = mNextAlarmClockForUser.size();
2212 for (int i = 0; i < nextAlarmClockForUserSize; i++) {
2213 users.add(mNextAlarmClockForUser.keyAt(i));
2214 }
2215 final int pendingSendNextAlarmClockChangedForUserSize =
2216 mPendingSendNextAlarmClockChangedForUser.size();
2217 for (int i = 0; i < pendingSendNextAlarmClockChangedForUserSize; i++) {
2218 users.add(mPendingSendNextAlarmClockChangedForUser.keyAt(i));
2219 }
2220 for (int user : users) {
2221 final AlarmManager.AlarmClockInfo next = mNextAlarmClockForUser.get(user);
2222 final long time = next != null ? next.getTriggerTime() : 0;
2223 final boolean pendingSend = mPendingSendNextAlarmClockChangedForUser.get(user);
2224 final long aToken = proto.start(AlarmManagerServiceProto.NEXT_ALARM_CLOCK_METADATA);
2225 proto.write(AlarmClockMetadataProto.USER, user);
2226 proto.write(AlarmClockMetadataProto.IS_PENDING_SEND, pendingSend);
2227 proto.write(AlarmClockMetadataProto.TRIGGER_TIME_MS, time);
2228 proto.end(aToken);
2229 }
2230 for (Batch b : mAlarmBatches) {
2231 b.writeToProto(proto, AlarmManagerServiceProto.PENDING_ALARM_BATCHES,
2232 nowElapsed, nowRTC);
2233 }
2234 for (int i = 0; i < mPendingBackgroundAlarms.size(); i++) {
2235 final ArrayList<Alarm> blockedAlarms = mPendingBackgroundAlarms.valueAt(i);
2236 if (blockedAlarms != null) {
2237 for (Alarm a : blockedAlarms) {
2238 a.writeToProto(proto,
2239 AlarmManagerServiceProto.PENDING_USER_BLOCKED_BACKGROUND_ALARMS,
2240 nowElapsed, nowRTC);
2241 }
2242 }
2243 }
2244 if (mPendingIdleUntil != null) {
2245 mPendingIdleUntil.writeToProto(
2246 proto, AlarmManagerServiceProto.PENDING_IDLE_UNTIL, nowElapsed, nowRTC);
2247 }
2248 for (Alarm a : mPendingWhileIdleAlarms) {
2249 a.writeToProto(proto, AlarmManagerServiceProto.PENDING_WHILE_IDLE_ALARMS,
2250 nowElapsed, nowRTC);
2251 }
2252 if (mNextWakeFromIdle != null) {
2253 mNextWakeFromIdle.writeToProto(proto, AlarmManagerServiceProto.NEXT_WAKE_FROM_IDLE,
2254 nowElapsed, nowRTC);
2255 }
2256
2257 for (Alarm a : mPendingNonWakeupAlarms) {
2258 a.writeToProto(proto, AlarmManagerServiceProto.PAST_DUE_NON_WAKEUP_ALARMS,
2259 nowElapsed, nowRTC);
2260 }
2261
2262 proto.write(AlarmManagerServiceProto.DELAYED_ALARM_COUNT, mNumDelayedAlarms);
2263 proto.write(AlarmManagerServiceProto.TOTAL_DELAY_TIME_MS, mTotalDelayTime);
2264 proto.write(AlarmManagerServiceProto.MAX_DELAY_DURATION_MS, mMaxDelayTime);
2265 proto.write(AlarmManagerServiceProto.MAX_NON_INTERACTIVE_DURATION_MS,
2266 mNonInteractiveTime);
2267
2268 proto.write(AlarmManagerServiceProto.BROADCAST_REF_COUNT, mBroadcastRefCount);
2269 proto.write(AlarmManagerServiceProto.PENDING_INTENT_SEND_COUNT, mSendCount);
2270 proto.write(AlarmManagerServiceProto.PENDING_INTENT_FINISH_COUNT, mSendFinishCount);
2271 proto.write(AlarmManagerServiceProto.LISTENER_SEND_COUNT, mListenerCount);
2272 proto.write(AlarmManagerServiceProto.LISTENER_FINISH_COUNT, mListenerFinishCount);
2273
2274 for (InFlight f : mInFlight) {
2275 f.writeToProto(proto, AlarmManagerServiceProto.OUTSTANDING_DELIVERIES);
2276 }
2277
Kweku Adams61e03292017-10-19 14:27:12 -07002278 for (int i = 0; i < mLastAllowWhileIdleDispatch.size(); ++i) {
2279 final long token = proto.start(
2280 AlarmManagerServiceProto.LAST_ALLOW_WHILE_IDLE_DISPATCH_TIMES);
Makoto Onukiadb50d82018-01-29 16:20:30 -08002281 final int uid = mLastAllowWhileIdleDispatch.keyAt(i);
2282 final long lastTime = mLastAllowWhileIdleDispatch.valueAt(i);
2283
2284 proto.write(AlarmManagerServiceProto.LastAllowWhileIdleDispatch.UID, uid);
2285 proto.write(AlarmManagerServiceProto.LastAllowWhileIdleDispatch.TIME_MS, lastTime);
2286 proto.write(AlarmManagerServiceProto.LastAllowWhileIdleDispatch.NEXT_ALLOWED_MS,
2287 lastTime + getWhileIdleMinIntervalLocked(uid));
Kweku Adams61e03292017-10-19 14:27:12 -07002288 proto.end(token);
2289 }
2290
Makoto Onukiadb50d82018-01-29 16:20:30 -08002291 for (int i = 0; i < mUseAllowWhileIdleShortTime.size(); i++) {
2292 if (mUseAllowWhileIdleShortTime.valueAt(i)) {
2293 proto.write(AlarmManagerServiceProto.USE_ALLOW_WHILE_IDLE_SHORT_TIME,
2294 mUseAllowWhileIdleShortTime.keyAt(i));
2295 }
2296 }
2297
Kweku Adams61e03292017-10-19 14:27:12 -07002298 mLog.writeToProto(proto, AlarmManagerServiceProto.RECENT_PROBLEMS);
2299
2300 final FilterStats[] topFilters = new FilterStats[10];
2301 final Comparator<FilterStats> comparator = new Comparator<FilterStats>() {
2302 @Override
2303 public int compare(FilterStats lhs, FilterStats rhs) {
2304 if (lhs.aggregateTime < rhs.aggregateTime) {
2305 return 1;
2306 } else if (lhs.aggregateTime > rhs.aggregateTime) {
2307 return -1;
2308 }
2309 return 0;
2310 }
2311 };
2312 int len = 0;
2313 // Get the top 10 FilterStats, ordered by aggregateTime.
2314 for (int iu = 0; iu < mBroadcastStats.size(); ++iu) {
2315 ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(iu);
2316 for (int ip = 0; ip < uidStats.size(); ++ip) {
2317 BroadcastStats bs = uidStats.valueAt(ip);
2318 for (int is = 0; is < bs.filterStats.size(); ++is) {
2319 FilterStats fs = bs.filterStats.valueAt(is);
2320 int pos = len > 0
2321 ? Arrays.binarySearch(topFilters, 0, len, fs, comparator) : 0;
2322 if (pos < 0) {
2323 pos = -pos - 1;
2324 }
2325 if (pos < topFilters.length) {
2326 int copylen = topFilters.length - pos - 1;
2327 if (copylen > 0) {
2328 System.arraycopy(topFilters, pos, topFilters, pos+1, copylen);
2329 }
2330 topFilters[pos] = fs;
2331 if (len < topFilters.length) {
2332 len++;
2333 }
2334 }
2335 }
2336 }
2337 }
2338 for (int i = 0; i < len; ++i) {
2339 final long token = proto.start(AlarmManagerServiceProto.TOP_ALARMS);
2340 FilterStats fs = topFilters[i];
2341
2342 proto.write(AlarmManagerServiceProto.TopAlarm.UID, fs.mBroadcastStats.mUid);
2343 proto.write(AlarmManagerServiceProto.TopAlarm.PACKAGE_NAME,
2344 fs.mBroadcastStats.mPackageName);
2345 fs.writeToProto(proto, AlarmManagerServiceProto.TopAlarm.FILTER);
2346
2347 proto.end(token);
2348 }
2349
2350 final ArrayList<FilterStats> tmpFilters = new ArrayList<FilterStats>();
2351 for (int iu = 0; iu < mBroadcastStats.size(); ++iu) {
2352 ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(iu);
2353 for (int ip = 0; ip < uidStats.size(); ++ip) {
2354 final long token = proto.start(AlarmManagerServiceProto.ALARM_STATS);
2355
2356 BroadcastStats bs = uidStats.valueAt(ip);
2357 bs.writeToProto(proto, AlarmManagerServiceProto.AlarmStat.BROADCAST);
2358
2359 // uidStats is an ArrayMap, which we can't sort.
2360 tmpFilters.clear();
2361 for (int is = 0; is < bs.filterStats.size(); ++is) {
2362 tmpFilters.add(bs.filterStats.valueAt(is));
2363 }
2364 Collections.sort(tmpFilters, comparator);
2365 for (FilterStats fs : tmpFilters) {
2366 fs.writeToProto(proto, AlarmManagerServiceProto.AlarmStat.FILTERS);
2367 }
2368
2369 proto.end(token);
2370 }
2371 }
2372
2373 if (RECORD_DEVICE_IDLE_ALARMS) {
2374 for (int i = 0; i < mAllowWhileIdleDispatches.size(); i++) {
2375 IdleDispatchEntry ent = mAllowWhileIdleDispatches.get(i);
2376 final long token = proto.start(
2377 AlarmManagerServiceProto.ALLOW_WHILE_IDLE_DISPATCHES);
2378
2379 proto.write(IdleDispatchEntryProto.UID, ent.uid);
2380 proto.write(IdleDispatchEntryProto.PKG, ent.pkg);
2381 proto.write(IdleDispatchEntryProto.TAG, ent.tag);
2382 proto.write(IdleDispatchEntryProto.OP, ent.op);
2383 proto.write(IdleDispatchEntryProto.ENTRY_CREATION_REALTIME,
2384 ent.elapsedRealtime);
2385 proto.write(IdleDispatchEntryProto.ARG_REALTIME, ent.argRealtime);
2386
2387 proto.end(token);
2388 }
2389 }
2390
2391 if (WAKEUP_STATS) {
2392 for (WakeupEvent event : mRecentWakeups) {
2393 final long token = proto.start(AlarmManagerServiceProto.RECENT_WAKEUP_HISTORY);
2394 proto.write(WakeupEventProto.UID, event.uid);
2395 proto.write(WakeupEventProto.ACTION, event.action);
2396 proto.write(WakeupEventProto.WHEN, event.when);
2397 proto.end(token);
2398 }
2399 }
2400 }
2401
2402 proto.flush();
2403 }
2404
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07002405 private void logBatchesLocked(SimpleDateFormat sdf) {
Adam Lesinski182f73f2013-12-05 16:48:06 -08002406 ByteArrayOutputStream bs = new ByteArrayOutputStream(2048);
2407 PrintWriter pw = new PrintWriter(bs);
2408 final long nowRTC = System.currentTimeMillis();
2409 final long nowELAPSED = SystemClock.elapsedRealtime();
2410 final int NZ = mAlarmBatches.size();
2411 for (int iz = 0; iz < NZ; iz++) {
2412 Batch bz = mAlarmBatches.get(iz);
2413 pw.append("Batch "); pw.print(iz); pw.append(": "); pw.println(bz);
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07002414 dumpAlarmList(pw, bz.alarms, " ", nowELAPSED, nowRTC, sdf);
Adam Lesinski182f73f2013-12-05 16:48:06 -08002415 pw.flush();
2416 Slog.v(TAG, bs.toString());
2417 bs.reset();
2418 }
2419 }
2420
2421 private boolean validateConsistencyLocked() {
2422 if (DEBUG_VALIDATE) {
2423 long lastTime = Long.MIN_VALUE;
2424 final int N = mAlarmBatches.size();
2425 for (int i = 0; i < N; i++) {
2426 Batch b = mAlarmBatches.get(i);
2427 if (b.start >= lastTime) {
2428 // duplicate start times are okay because of standalone batches
2429 lastTime = b.start;
2430 } else {
2431 Slog.e(TAG, "CONSISTENCY FAILURE: Batch " + i + " is out of order");
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07002432 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
2433 logBatchesLocked(sdf);
Adam Lesinski182f73f2013-12-05 16:48:06 -08002434 return false;
2435 }
2436 }
2437 }
2438 return true;
2439 }
2440
Christopher Tate0dab4dc2014-12-16 12:14:06 -08002441 private Batch findFirstWakeupBatchLocked() {
2442 final int N = mAlarmBatches.size();
2443 for (int i = 0; i < N; i++) {
2444 Batch b = mAlarmBatches.get(i);
2445 if (b.hasWakeups()) {
2446 return b;
2447 }
2448 }
2449 return null;
2450 }
2451
Dianne Hackbornf70faed2015-04-21 14:11:38 -07002452 long getNextWakeFromIdleTimeImpl() {
2453 synchronized (mLock) {
2454 return mNextWakeFromIdle != null ? mNextWakeFromIdle.whenElapsed : Long.MAX_VALUE;
2455 }
2456 }
2457
2458 AlarmManager.AlarmClockInfo getNextAlarmClockImpl(int userId) {
Adrian Roosc42a1e12014-07-07 23:35:53 +02002459 synchronized (mLock) {
2460 return mNextAlarmClockForUser.get(userId);
2461 }
2462 }
2463
2464 /**
2465 * Recomputes the next alarm clock for all users.
2466 */
2467 private void updateNextAlarmClockLocked() {
2468 if (!mNextAlarmClockMayChange) {
2469 return;
2470 }
2471 mNextAlarmClockMayChange = false;
2472
Jose Lima235510e2014-08-13 12:50:01 -07002473 SparseArray<AlarmManager.AlarmClockInfo> nextForUser = mTmpSparseAlarmClockArray;
Adrian Roosc42a1e12014-07-07 23:35:53 +02002474 nextForUser.clear();
2475
2476 final int N = mAlarmBatches.size();
2477 for (int i = 0; i < N; i++) {
2478 ArrayList<Alarm> alarms = mAlarmBatches.get(i).alarms;
2479 final int M = alarms.size();
2480
2481 for (int j = 0; j < M; j++) {
2482 Alarm a = alarms.get(j);
2483 if (a.alarmClock != null) {
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07002484 final int userId = UserHandle.getUserId(a.uid);
Christopher Tate76389c02016-08-03 14:57:47 -07002485 AlarmManager.AlarmClockInfo current = mNextAlarmClockForUser.get(userId);
Adrian Roosc42a1e12014-07-07 23:35:53 +02002486
2487 if (DEBUG_ALARM_CLOCK) {
Christopher Tate76389c02016-08-03 14:57:47 -07002488 Log.v(TAG, "Found AlarmClockInfo " + a.alarmClock + " at " +
Selim Cinek9c4a7072014-11-21 17:44:34 +01002489 formatNextAlarm(getContext(), a.alarmClock, userId) +
Adrian Roosc42a1e12014-07-07 23:35:53 +02002490 " for user " + userId);
2491 }
2492
2493 // Alarms and batches are sorted by time, no need to compare times here.
2494 if (nextForUser.get(userId) == null) {
2495 nextForUser.put(userId, a.alarmClock);
Christopher Tate76389c02016-08-03 14:57:47 -07002496 } else if (a.alarmClock.equals(current)
2497 && current.getTriggerTime() <= nextForUser.get(userId).getTriggerTime()) {
2498 // same/earlier time and it's the one we cited before, so stick with it
2499 nextForUser.put(userId, current);
Adrian Roosc42a1e12014-07-07 23:35:53 +02002500 }
2501 }
2502 }
2503 }
2504
2505 // Update mNextAlarmForUser with new values.
2506 final int NN = nextForUser.size();
2507 for (int i = 0; i < NN; i++) {
Jose Lima235510e2014-08-13 12:50:01 -07002508 AlarmManager.AlarmClockInfo newAlarm = nextForUser.valueAt(i);
Adrian Roosc42a1e12014-07-07 23:35:53 +02002509 int userId = nextForUser.keyAt(i);
Jose Lima235510e2014-08-13 12:50:01 -07002510 AlarmManager.AlarmClockInfo currentAlarm = mNextAlarmClockForUser.get(userId);
Adrian Roosc42a1e12014-07-07 23:35:53 +02002511 if (!newAlarm.equals(currentAlarm)) {
2512 updateNextAlarmInfoForUserLocked(userId, newAlarm);
2513 }
2514 }
2515
2516 // Remove users without any alarm clocks scheduled.
2517 final int NNN = mNextAlarmClockForUser.size();
2518 for (int i = NNN - 1; i >= 0; i--) {
2519 int userId = mNextAlarmClockForUser.keyAt(i);
2520 if (nextForUser.get(userId) == null) {
2521 updateNextAlarmInfoForUserLocked(userId, null);
2522 }
2523 }
2524 }
2525
Jose Lima235510e2014-08-13 12:50:01 -07002526 private void updateNextAlarmInfoForUserLocked(int userId,
2527 AlarmManager.AlarmClockInfo alarmClock) {
Adrian Roosc42a1e12014-07-07 23:35:53 +02002528 if (alarmClock != null) {
2529 if (DEBUG_ALARM_CLOCK) {
2530 Log.v(TAG, "Next AlarmClockInfoForUser(" + userId + "): " +
Selim Cinek9c4a7072014-11-21 17:44:34 +01002531 formatNextAlarm(getContext(), alarmClock, userId));
Adrian Roosc42a1e12014-07-07 23:35:53 +02002532 }
2533 mNextAlarmClockForUser.put(userId, alarmClock);
2534 } else {
2535 if (DEBUG_ALARM_CLOCK) {
2536 Log.v(TAG, "Next AlarmClockInfoForUser(" + userId + "): None");
2537 }
2538 mNextAlarmClockForUser.remove(userId);
2539 }
2540
2541 mPendingSendNextAlarmClockChangedForUser.put(userId, true);
2542 mHandler.removeMessages(AlarmHandler.SEND_NEXT_ALARM_CLOCK_CHANGED);
2543 mHandler.sendEmptyMessage(AlarmHandler.SEND_NEXT_ALARM_CLOCK_CHANGED);
2544 }
2545
2546 /**
2547 * Updates NEXT_ALARM_FORMATTED and sends NEXT_ALARM_CLOCK_CHANGED_INTENT for all users
2548 * for which alarm clocks have changed since the last call to this.
2549 *
2550 * Do not call with a lock held. Only call from mHandler's thread.
2551 *
2552 * @see AlarmHandler#SEND_NEXT_ALARM_CLOCK_CHANGED
2553 */
2554 private void sendNextAlarmClockChanged() {
Jose Lima235510e2014-08-13 12:50:01 -07002555 SparseArray<AlarmManager.AlarmClockInfo> pendingUsers = mHandlerSparseAlarmClockArray;
Adrian Roosc42a1e12014-07-07 23:35:53 +02002556 pendingUsers.clear();
2557
2558 synchronized (mLock) {
2559 final int N = mPendingSendNextAlarmClockChangedForUser.size();
2560 for (int i = 0; i < N; i++) {
2561 int userId = mPendingSendNextAlarmClockChangedForUser.keyAt(i);
2562 pendingUsers.append(userId, mNextAlarmClockForUser.get(userId));
2563 }
2564 mPendingSendNextAlarmClockChangedForUser.clear();
2565 }
2566
2567 final int N = pendingUsers.size();
2568 for (int i = 0; i < N; i++) {
2569 int userId = pendingUsers.keyAt(i);
Jose Lima235510e2014-08-13 12:50:01 -07002570 AlarmManager.AlarmClockInfo alarmClock = pendingUsers.valueAt(i);
Adrian Roosc42a1e12014-07-07 23:35:53 +02002571 Settings.System.putStringForUser(getContext().getContentResolver(),
2572 Settings.System.NEXT_ALARM_FORMATTED,
Selim Cinek9c4a7072014-11-21 17:44:34 +01002573 formatNextAlarm(getContext(), alarmClock, userId),
Adrian Roosc42a1e12014-07-07 23:35:53 +02002574 userId);
2575
2576 getContext().sendBroadcastAsUser(NEXT_ALARM_CLOCK_CHANGED_INTENT,
2577 new UserHandle(userId));
2578 }
2579 }
2580
2581 /**
2582 * Formats an alarm like platform/packages/apps/DeskClock used to.
2583 */
Selim Cinek9c4a7072014-11-21 17:44:34 +01002584 private static String formatNextAlarm(final Context context, AlarmManager.AlarmClockInfo info,
2585 int userId) {
2586 String skeleton = DateFormat.is24HourFormat(context, userId) ? "EHm" : "Ehma";
Adrian Roosc42a1e12014-07-07 23:35:53 +02002587 String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton);
2588 return (info == null) ? "" :
2589 DateFormat.format(pattern, info.getTriggerTime()).toString();
2590 }
2591
Adam Lesinski182f73f2013-12-05 16:48:06 -08002592 void rescheduleKernelAlarmsLocked() {
2593 // Schedule the next upcoming wakeup alarm. If there is a deliverable batch
2594 // prior to that which contains no wakeups, we schedule that as well.
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07002595 long nextNonWakeup = 0;
Adam Lesinski182f73f2013-12-05 16:48:06 -08002596 if (mAlarmBatches.size() > 0) {
Christopher Tate0dab4dc2014-12-16 12:14:06 -08002597 final Batch firstWakeup = findFirstWakeupBatchLocked();
Adam Lesinski182f73f2013-12-05 16:48:06 -08002598 final Batch firstBatch = mAlarmBatches.get(0);
Suprabh Shukla2fa95452018-02-12 12:53:23 -08002599 if (firstWakeup != null) {
Christopher Tate0dab4dc2014-12-16 12:14:06 -08002600 mNextWakeup = firstWakeup.start;
Dianne Hackbornaa9a59d2016-05-23 15:59:18 -07002601 mLastWakeupSet = SystemClock.elapsedRealtime();
Christopher Tate0dab4dc2014-12-16 12:14:06 -08002602 setLocked(ELAPSED_REALTIME_WAKEUP, firstWakeup.start);
Adam Lesinski182f73f2013-12-05 16:48:06 -08002603 }
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07002604 if (firstBatch != firstWakeup) {
2605 nextNonWakeup = firstBatch.start;
Adam Lesinski182f73f2013-12-05 16:48:06 -08002606 }
2607 }
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07002608 if (mPendingNonWakeupAlarms.size() > 0) {
2609 if (nextNonWakeup == 0 || mNextNonWakeupDeliveryTime < nextNonWakeup) {
2610 nextNonWakeup = mNextNonWakeupDeliveryTime;
2611 }
2612 }
Suprabh Shukla2fa95452018-02-12 12:53:23 -08002613 if (nextNonWakeup != 0) {
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07002614 mNextNonWakeup = nextNonWakeup;
2615 setLocked(ELAPSED_REALTIME, nextNonWakeup);
2616 }
Adam Lesinski182f73f2013-12-05 16:48:06 -08002617 }
2618
Christopher Tate14a7bb02015-10-01 10:24:31 -07002619 private void removeLocked(PendingIntent operation, IAlarmListener directReceiver) {
Christopher Tate1d99c392017-12-07 16:54:04 -08002620 if (operation == null && directReceiver == null) {
2621 if (localLOGV) {
2622 Slog.w(TAG, "requested remove() of null operation",
2623 new RuntimeException("here"));
2624 }
2625 return;
2626 }
2627
Adam Lesinski182f73f2013-12-05 16:48:06 -08002628 boolean didRemove = false;
Christopher Tate1d99c392017-12-07 16:54:04 -08002629 final Predicate<Alarm> whichAlarms = (Alarm a) -> a.matches(operation, directReceiver);
Adam Lesinski182f73f2013-12-05 16:48:06 -08002630 for (int i = mAlarmBatches.size() - 1; i >= 0; i--) {
2631 Batch b = mAlarmBatches.get(i);
Christopher Tate1d99c392017-12-07 16:54:04 -08002632 didRemove |= b.remove(whichAlarms);
Adam Lesinski182f73f2013-12-05 16:48:06 -08002633 if (b.size() == 0) {
2634 mAlarmBatches.remove(i);
2635 }
2636 }
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07002637 for (int i = mPendingWhileIdleAlarms.size() - 1; i >= 0; i--) {
Christopher Tate14a7bb02015-10-01 10:24:31 -07002638 if (mPendingWhileIdleAlarms.get(i).matches(operation, directReceiver)) {
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07002639 // Don't set didRemove, since this doesn't impact the scheduled alarms.
2640 mPendingWhileIdleAlarms.remove(i);
2641 }
2642 }
Suprabh Shukladb6bf662017-08-30 15:41:53 -07002643 for (int i = mPendingBackgroundAlarms.size() - 1; i >= 0; i--) {
2644 final ArrayList<Alarm> alarmsForUid = mPendingBackgroundAlarms.valueAt(i);
2645 for (int j = alarmsForUid.size() - 1; j >= 0; j--) {
2646 if (alarmsForUid.get(j).matches(operation, directReceiver)) {
2647 // Don't set didRemove, since this doesn't impact the scheduled alarms.
2648 alarmsForUid.remove(j);
2649 }
2650 }
2651 if (alarmsForUid.size() == 0) {
2652 mPendingBackgroundAlarms.removeAt(i);
2653 }
2654 }
Adam Lesinski182f73f2013-12-05 16:48:06 -08002655 if (didRemove) {
2656 if (DEBUG_BATCH) {
2657 Slog.v(TAG, "remove(operation) changed bounds; rebatching");
2658 }
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07002659 boolean restorePending = false;
Christopher Tate14a7bb02015-10-01 10:24:31 -07002660 if (mPendingIdleUntil != null && mPendingIdleUntil.matches(operation, directReceiver)) {
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07002661 mPendingIdleUntil = null;
2662 restorePending = true;
2663 }
Christopher Tate14a7bb02015-10-01 10:24:31 -07002664 if (mNextWakeFromIdle != null && mNextWakeFromIdle.matches(operation, directReceiver)) {
Dianne Hackbornf70faed2015-04-21 14:11:38 -07002665 mNextWakeFromIdle = null;
2666 }
Adam Lesinski182f73f2013-12-05 16:48:06 -08002667 rebatchAllAlarmsLocked(true);
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07002668 if (restorePending) {
2669 restorePendingWhileIdleAlarmsLocked();
2670 }
Adrian Roosc42a1e12014-07-07 23:35:53 +02002671 updateNextAlarmClockLocked();
Adam Lesinski182f73f2013-12-05 16:48:06 -08002672 }
2673 }
2674
Christopher Tate1d99c392017-12-07 16:54:04 -08002675 void removeLocked(final int uid) {
Makoto Onuki5d93b832018-01-10 16:12:39 -08002676 if (uid == Process.SYSTEM_UID) {
2677 Slog.wtf(TAG, "removeLocked: Shouldn't for UID=" + uid);
2678 return;
2679 }
Adam Lesinski182f73f2013-12-05 16:48:06 -08002680 boolean didRemove = false;
Christopher Tate1d99c392017-12-07 16:54:04 -08002681 final Predicate<Alarm> whichAlarms = (Alarm a) -> a.uid == uid;
Adam Lesinski182f73f2013-12-05 16:48:06 -08002682 for (int i = mAlarmBatches.size() - 1; i >= 0; i--) {
2683 Batch b = mAlarmBatches.get(i);
Christopher Tate1d99c392017-12-07 16:54:04 -08002684 didRemove |= b.remove(whichAlarms);
2685 if (b.size() == 0) {
2686 mAlarmBatches.remove(i);
2687 }
2688 }
2689 for (int i = mPendingWhileIdleAlarms.size() - 1; i >= 0; i--) {
2690 final Alarm a = mPendingWhileIdleAlarms.get(i);
2691 if (a.uid == uid) {
2692 // Don't set didRemove, since this doesn't impact the scheduled alarms.
2693 mPendingWhileIdleAlarms.remove(i);
2694 }
2695 }
2696 for (int i = mPendingBackgroundAlarms.size() - 1; i >= 0; i --) {
2697 final ArrayList<Alarm> alarmsForUid = mPendingBackgroundAlarms.valueAt(i);
2698 for (int j = alarmsForUid.size() - 1; j >= 0; j--) {
2699 if (alarmsForUid.get(j).uid == uid) {
2700 alarmsForUid.remove(j);
2701 }
2702 }
2703 if (alarmsForUid.size() == 0) {
2704 mPendingBackgroundAlarms.removeAt(i);
2705 }
2706 }
2707 if (didRemove) {
2708 if (DEBUG_BATCH) {
2709 Slog.v(TAG, "remove(uid) changed bounds; rebatching");
2710 }
2711 rebatchAllAlarmsLocked(true);
2712 rescheduleKernelAlarmsLocked();
2713 updateNextAlarmClockLocked();
2714 }
2715 }
2716
2717 void removeLocked(final String packageName) {
2718 if (packageName == null) {
2719 if (localLOGV) {
2720 Slog.w(TAG, "requested remove() of null packageName",
2721 new RuntimeException("here"));
2722 }
2723 return;
2724 }
2725
2726 boolean didRemove = false;
2727 final Predicate<Alarm> whichAlarms = (Alarm a) -> a.matches(packageName);
Makoto Onuki5d93b832018-01-10 16:12:39 -08002728 final boolean oldHasTick = haveBatchesTimeTickAlarm(mAlarmBatches);
Christopher Tate1d99c392017-12-07 16:54:04 -08002729 for (int i = mAlarmBatches.size() - 1; i >= 0; i--) {
2730 Batch b = mAlarmBatches.get(i);
2731 didRemove |= b.remove(whichAlarms);
Adam Lesinski182f73f2013-12-05 16:48:06 -08002732 if (b.size() == 0) {
2733 mAlarmBatches.remove(i);
2734 }
2735 }
Makoto Onuki5d93b832018-01-10 16:12:39 -08002736 final boolean newHasTick = haveBatchesTimeTickAlarm(mAlarmBatches);
2737 if (oldHasTick != newHasTick) {
2738 Slog.wtf(TAG, "removeLocked: hasTick changed from " + oldHasTick + " to " + newHasTick);
2739 }
2740
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07002741 for (int i = mPendingWhileIdleAlarms.size() - 1; i >= 0; i--) {
Christopher Tate14a7bb02015-10-01 10:24:31 -07002742 final Alarm a = mPendingWhileIdleAlarms.get(i);
2743 if (a.matches(packageName)) {
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07002744 // Don't set didRemove, since this doesn't impact the scheduled alarms.
2745 mPendingWhileIdleAlarms.remove(i);
2746 }
2747 }
Suprabh Shukladb6bf662017-08-30 15:41:53 -07002748 for (int i = mPendingBackgroundAlarms.size() - 1; i >= 0; i --) {
2749 final ArrayList<Alarm> alarmsForUid = mPendingBackgroundAlarms.valueAt(i);
2750 for (int j = alarmsForUid.size() - 1; j >= 0; j--) {
2751 if (alarmsForUid.get(j).matches(packageName)) {
2752 alarmsForUid.remove(j);
2753 }
2754 }
2755 if (alarmsForUid.size() == 0) {
2756 mPendingBackgroundAlarms.removeAt(i);
2757 }
2758 }
Adam Lesinski182f73f2013-12-05 16:48:06 -08002759 if (didRemove) {
2760 if (DEBUG_BATCH) {
2761 Slog.v(TAG, "remove(package) changed bounds; rebatching");
2762 }
2763 rebatchAllAlarmsLocked(true);
2764 rescheduleKernelAlarmsLocked();
Adrian Roosc42a1e12014-07-07 23:35:53 +02002765 updateNextAlarmClockLocked();
Adam Lesinski182f73f2013-12-05 16:48:06 -08002766 }
2767 }
2768
Christopher Tate1d99c392017-12-07 16:54:04 -08002769 void removeForStoppedLocked(final int uid) {
Makoto Onuki5d93b832018-01-10 16:12:39 -08002770 if (uid == Process.SYSTEM_UID) {
2771 Slog.wtf(TAG, "removeForStoppedLocked: Shouldn't for UID=" + uid);
2772 return;
2773 }
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07002774 boolean didRemove = false;
Christopher Tate1d99c392017-12-07 16:54:04 -08002775 final Predicate<Alarm> whichAlarms = (Alarm a) -> {
2776 try {
2777 if (a.uid == uid && ActivityManager.getService().isAppStartModeDisabled(
2778 uid, a.packageName)) {
2779 return true;
2780 }
2781 } catch (RemoteException e) { /* fall through */}
2782 return false;
2783 };
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07002784 for (int i = mAlarmBatches.size() - 1; i >= 0; i--) {
2785 Batch b = mAlarmBatches.get(i);
Christopher Tate1d99c392017-12-07 16:54:04 -08002786 didRemove |= b.remove(whichAlarms);
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07002787 if (b.size() == 0) {
2788 mAlarmBatches.remove(i);
2789 }
2790 }
2791 for (int i = mPendingWhileIdleAlarms.size() - 1; i >= 0; i--) {
2792 final Alarm a = mPendingWhileIdleAlarms.get(i);
Dianne Hackborne07641d2016-11-09 15:07:23 -08002793 if (a.uid == uid) {
2794 // Don't set didRemove, since this doesn't impact the scheduled alarms.
2795 mPendingWhileIdleAlarms.remove(i);
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07002796 }
2797 }
Suprabh Shukladb6bf662017-08-30 15:41:53 -07002798 for (int i = mPendingBackgroundAlarms.size() - 1; i >= 0; i--) {
2799 if (mPendingBackgroundAlarms.keyAt(i) == uid) {
2800 mPendingBackgroundAlarms.removeAt(i);
2801 }
2802 }
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07002803 if (didRemove) {
2804 if (DEBUG_BATCH) {
2805 Slog.v(TAG, "remove(package) changed bounds; rebatching");
2806 }
2807 rebatchAllAlarmsLocked(true);
2808 rescheduleKernelAlarmsLocked();
2809 updateNextAlarmClockLocked();
2810 }
2811 }
2812
Adam Lesinski182f73f2013-12-05 16:48:06 -08002813 void removeUserLocked(int userHandle) {
Makoto Onuki5d93b832018-01-10 16:12:39 -08002814 if (userHandle == UserHandle.USER_SYSTEM) {
2815 Slog.wtf(TAG, "removeForStoppedLocked: Shouldn't for user=" + userHandle);
2816 return;
2817 }
Adam Lesinski182f73f2013-12-05 16:48:06 -08002818 boolean didRemove = false;
Christopher Tate1d99c392017-12-07 16:54:04 -08002819 final Predicate<Alarm> whichAlarms =
2820 (Alarm a) -> UserHandle.getUserId(a.creatorUid) == userHandle;
Adam Lesinski182f73f2013-12-05 16:48:06 -08002821 for (int i = mAlarmBatches.size() - 1; i >= 0; i--) {
2822 Batch b = mAlarmBatches.get(i);
Christopher Tate1d99c392017-12-07 16:54:04 -08002823 didRemove |= b.remove(whichAlarms);
Adam Lesinski182f73f2013-12-05 16:48:06 -08002824 if (b.size() == 0) {
2825 mAlarmBatches.remove(i);
2826 }
2827 }
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07002828 for (int i = mPendingWhileIdleAlarms.size() - 1; i >= 0; i--) {
Christopher Tate14a7bb02015-10-01 10:24:31 -07002829 if (UserHandle.getUserId(mPendingWhileIdleAlarms.get(i).creatorUid)
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07002830 == userHandle) {
2831 // Don't set didRemove, since this doesn't impact the scheduled alarms.
2832 mPendingWhileIdleAlarms.remove(i);
2833 }
2834 }
Suprabh Shukladb6bf662017-08-30 15:41:53 -07002835 for (int i = mPendingBackgroundAlarms.size() - 1; i >= 0; i--) {
2836 if (UserHandle.getUserId(mPendingBackgroundAlarms.keyAt(i)) == userHandle) {
2837 mPendingBackgroundAlarms.removeAt(i);
2838 }
2839 }
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07002840 for (int i = mLastAllowWhileIdleDispatch.size() - 1; i >= 0; i--) {
2841 if (UserHandle.getUserId(mLastAllowWhileIdleDispatch.keyAt(i)) == userHandle) {
2842 mLastAllowWhileIdleDispatch.removeAt(i);
2843 }
2844 }
Adam Lesinski182f73f2013-12-05 16:48:06 -08002845
2846 if (didRemove) {
2847 if (DEBUG_BATCH) {
2848 Slog.v(TAG, "remove(user) changed bounds; rebatching");
2849 }
2850 rebatchAllAlarmsLocked(true);
2851 rescheduleKernelAlarmsLocked();
Adrian Roosc42a1e12014-07-07 23:35:53 +02002852 updateNextAlarmClockLocked();
Adam Lesinski182f73f2013-12-05 16:48:06 -08002853 }
2854 }
2855
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07002856 void interactiveStateChangedLocked(boolean interactive) {
2857 if (mInteractive != interactive) {
2858 mInteractive = interactive;
2859 final long nowELAPSED = SystemClock.elapsedRealtime();
2860 if (interactive) {
2861 if (mPendingNonWakeupAlarms.size() > 0) {
2862 final long thisDelayTime = nowELAPSED - mStartCurrentDelayTime;
2863 mTotalDelayTime += thisDelayTime;
2864 if (mMaxDelayTime < thisDelayTime) {
2865 mMaxDelayTime = thisDelayTime;
2866 }
2867 deliverAlarmsLocked(mPendingNonWakeupAlarms, nowELAPSED);
2868 mPendingNonWakeupAlarms.clear();
2869 }
2870 if (mNonInteractiveStartTime > 0) {
2871 long dur = nowELAPSED - mNonInteractiveStartTime;
2872 if (dur > mNonInteractiveTime) {
2873 mNonInteractiveTime = dur;
2874 }
2875 }
2876 } else {
2877 mNonInteractiveStartTime = nowELAPSED;
2878 }
2879 }
2880 }
2881
Adam Lesinski182f73f2013-12-05 16:48:06 -08002882 boolean lookForPackageLocked(String packageName) {
2883 for (int i = 0; i < mAlarmBatches.size(); i++) {
2884 Batch b = mAlarmBatches.get(i);
2885 if (b.hasPackage(packageName)) {
2886 return true;
2887 }
2888 }
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07002889 for (int i = 0; i < mPendingWhileIdleAlarms.size(); i++) {
Christopher Tate14a7bb02015-10-01 10:24:31 -07002890 final Alarm a = mPendingWhileIdleAlarms.get(i);
2891 if (a.matches(packageName)) {
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07002892 return true;
2893 }
2894 }
Adam Lesinski182f73f2013-12-05 16:48:06 -08002895 return false;
2896 }
2897
2898 private void setLocked(int type, long when) {
Greg Hackmannf1bdbdd2013-12-17 11:56:22 -08002899 if (mNativeData != 0) {
Adam Lesinski182f73f2013-12-05 16:48:06 -08002900 // The kernel never triggers alarms with negative wakeup times
2901 // so we ensure they are positive.
2902 long alarmSeconds, alarmNanoseconds;
2903 if (when < 0) {
2904 alarmSeconds = 0;
2905 alarmNanoseconds = 0;
2906 } else {
2907 alarmSeconds = when / 1000;
2908 alarmNanoseconds = (when % 1000) * 1000 * 1000;
2909 }
Kweku Adams61e03292017-10-19 14:27:12 -07002910
Christopher Tate8b98ade2018-02-09 11:13:19 -08002911 final int result = set(mNativeData, type, alarmSeconds, alarmNanoseconds);
2912 if (result != 0) {
2913 final long nowElapsed = SystemClock.elapsedRealtime();
2914 Slog.wtf(TAG, "Unable to set kernel alarm, now=" + nowElapsed
2915 + " type=" + type + " when=" + when
2916 + " @ (" + alarmSeconds + "," + alarmNanoseconds
2917 + "), ret = " + result + " = " + Os.strerror(result));
2918 }
Adam Lesinski182f73f2013-12-05 16:48:06 -08002919 } else {
2920 Message msg = Message.obtain();
2921 msg.what = ALARM_EVENT;
Kweku Adams61e03292017-10-19 14:27:12 -07002922
Adam Lesinski182f73f2013-12-05 16:48:06 -08002923 mHandler.removeMessages(ALARM_EVENT);
2924 mHandler.sendMessageAtTime(msg, when);
2925 }
2926 }
2927
Dianne Hackborn043fcd92010-10-06 14:27:34 -07002928 private static final void dumpAlarmList(PrintWriter pw, ArrayList<Alarm> list,
Kweku Adams61e03292017-10-19 14:27:12 -07002929 String prefix, String label, long nowELAPSED, long nowRTC, SimpleDateFormat sdf) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002930 for (int i=list.size()-1; i>=0; i--) {
2931 Alarm a = list.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07002932 pw.print(prefix); pw.print(label); pw.print(" #"); pw.print(i);
2933 pw.print(": "); pw.println(a);
Kweku Adams61e03292017-10-19 14:27:12 -07002934 a.dump(pw, prefix + " ", nowELAPSED, nowRTC, sdf);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002935 }
2936 }
Christopher Tatee0a22b32013-07-11 14:43:13 -07002937
2938 private static final String labelForType(int type) {
2939 switch (type) {
2940 case RTC: return "RTC";
2941 case RTC_WAKEUP : return "RTC_WAKEUP";
2942 case ELAPSED_REALTIME : return "ELAPSED";
2943 case ELAPSED_REALTIME_WAKEUP: return "ELAPSED_WAKEUP";
Christopher Tatee0a22b32013-07-11 14:43:13 -07002944 }
2945 return "--unknown--";
2946 }
2947
2948 private static final void dumpAlarmList(PrintWriter pw, ArrayList<Alarm> list,
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07002949 String prefix, long nowELAPSED, long nowRTC, SimpleDateFormat sdf) {
Christopher Tatee0a22b32013-07-11 14:43:13 -07002950 for (int i=list.size()-1; i>=0; i--) {
2951 Alarm a = list.get(i);
2952 final String label = labelForType(a.type);
Christopher Tatee0a22b32013-07-11 14:43:13 -07002953 pw.print(prefix); pw.print(label); pw.print(" #"); pw.print(i);
2954 pw.print(": "); pw.println(a);
Kweku Adams61e03292017-10-19 14:27:12 -07002955 a.dump(pw, prefix + " ", nowELAPSED, nowRTC, sdf);
Christopher Tatee0a22b32013-07-11 14:43:13 -07002956 }
2957 }
2958
Suprabh Shukladb6bf662017-08-30 15:41:53 -07002959 private boolean isBackgroundRestricted(Alarm alarm) {
Suprabh Shuklac25447d2018-01-19 16:43:35 -08002960 final boolean allowWhileIdle = (alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0;
Suprabh Shukladb6bf662017-08-30 15:41:53 -07002961 if (alarm.alarmClock != null) {
2962 // Don't block alarm clocks
2963 return false;
2964 }
2965 if (alarm.operation != null
2966 && (alarm.operation.isActivity() || alarm.operation.isForegroundService())) {
2967 // Don't block starting foreground components
2968 return false;
2969 }
Suprabh Shukla75edab12018-01-29 14:09:06 -08002970 final String sourcePackage = alarm.sourcePackage;
Suprabh Shukladb6bf662017-08-30 15:41:53 -07002971 final int sourceUid = alarm.creatorUid;
Makoto Onukie4918212018-02-06 11:30:15 -08002972 return (mAppStateTracker != null) &&
2973 mAppStateTracker.areAlarmsRestricted(sourceUid, sourcePackage, allowWhileIdle);
Suprabh Shukladb6bf662017-08-30 15:41:53 -07002974 }
2975
Greg Hackmanna1d6f922013-12-09 16:56:53 -08002976 private native long init();
2977 private native void close(long nativeData);
Christopher Tate8b98ade2018-02-09 11:13:19 -08002978 private native int set(long nativeData, int type, long seconds, long nanoseconds);
Greg Hackmanna1d6f922013-12-09 16:56:53 -08002979 private native int waitForAlarm(long nativeData);
Greg Hackmann38bf5142014-02-19 16:39:36 -08002980 private native int setKernelTime(long nativeData, long millis);
Greg Hackmanna1d6f922013-12-09 16:56:53 -08002981 private native int setKernelTimezone(long nativeData, int minuteswest);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002982
Makoto Onukiadb50d82018-01-29 16:20:30 -08002983 private long getWhileIdleMinIntervalLocked(int uid) {
2984 final boolean dozing = mPendingIdleUntil != null;
Makoto Onukie4918212018-02-06 11:30:15 -08002985 final boolean ebs = (mAppStateTracker != null)
2986 && mAppStateTracker.isForceAllAppsStandbyEnabled();
Makoto Onukiadb50d82018-01-29 16:20:30 -08002987 if (!dozing && !ebs) {
2988 return mConstants.ALLOW_WHILE_IDLE_SHORT_TIME;
2989 }
2990 if (dozing) {
2991 return mConstants.ALLOW_WHILE_IDLE_LONG_TIME;
2992 }
2993 if (mUseAllowWhileIdleShortTime.get(uid)) {
2994 // if the last allow-while-idle went off while uid was fg, or the uid
2995 // recently came into fg, don't block the alarm for long.
2996 return mConstants.ALLOW_WHILE_IDLE_SHORT_TIME;
2997 }
2998 return mConstants.ALLOW_WHILE_IDLE_LONG_TIME;
2999 }
3000
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07003001 boolean triggerAlarmsLocked(ArrayList<Alarm> triggerList, final long nowELAPSED,
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003002 final long nowRTC) {
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07003003 boolean hasWakeup = false;
Christopher Tatee0a22b32013-07-11 14:43:13 -07003004 // batches are temporally sorted, so we need only pull from the
3005 // start of the list until we either empty it or hit a batch
3006 // that is not yet deliverable
Christopher Tate6578ad12013-09-24 17:12:46 -07003007 while (mAlarmBatches.size() > 0) {
3008 Batch batch = mAlarmBatches.get(0);
Christopher Tatee0a22b32013-07-11 14:43:13 -07003009 if (batch.start > nowELAPSED) {
3010 // Everything else is scheduled for the future
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003011 break;
3012 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003013
Christopher Tatee0a22b32013-07-11 14:43:13 -07003014 // We will (re)schedule some alarms now; don't let that interfere
3015 // with delivery of this current batch
3016 mAlarmBatches.remove(0);
Dianne Hackborn390517b2013-05-30 15:03:32 -07003017
Christopher Tatee0a22b32013-07-11 14:43:13 -07003018 final int N = batch.size();
3019 for (int i = 0; i < N; i++) {
3020 Alarm alarm = batch.get(i);
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07003021
3022 if ((alarm.flags&AlarmManager.FLAG_ALLOW_WHILE_IDLE) != 0) {
3023 // If this is an ALLOW_WHILE_IDLE alarm, we constrain how frequently the app can
3024 // schedule such alarms.
Suprabh Shuklac25447d2018-01-19 16:43:35 -08003025 final long lastTime = mLastAllowWhileIdleDispatch.get(alarm.creatorUid, 0);
Makoto Onukiadb50d82018-01-29 16:20:30 -08003026 final long minTime = lastTime + getWhileIdleMinIntervalLocked(alarm.creatorUid);
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07003027 if (nowELAPSED < minTime) {
3028 // Whoops, it hasn't been long enough since the last ALLOW_WHILE_IDLE
3029 // alarm went off for this app. Reschedule the alarm to be in the
3030 // correct time period.
Suprabh Shuklad65e58a2018-02-05 20:36:08 -08003031 alarm.expectedWhenElapsed = alarm.whenElapsed = minTime;
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07003032 if (alarm.maxWhenElapsed < minTime) {
3033 alarm.maxWhenElapsed = minTime;
3034 }
Suprabh Shuklad65e58a2018-02-05 20:36:08 -08003035 alarm.expectedMaxWhenElapsed = alarm.maxWhenElapsed;
Dianne Hackbornae78bf82015-10-26 13:33:20 -07003036 if (RECORD_DEVICE_IDLE_ALARMS) {
3037 IdleDispatchEntry ent = new IdleDispatchEntry();
3038 ent.uid = alarm.uid;
3039 ent.pkg = alarm.operation.getCreatorPackage();
3040 ent.tag = alarm.operation.getTag("");
3041 ent.op = "RESCHEDULE";
3042 ent.elapsedRealtime = nowELAPSED;
3043 ent.argRealtime = lastTime;
3044 mAllowWhileIdleDispatches.add(ent);
3045 }
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07003046 setImplLocked(alarm, true, false);
3047 continue;
3048 }
3049 }
Suprabh Shukladb6bf662017-08-30 15:41:53 -07003050 if (isBackgroundRestricted(alarm)) {
3051 // Alarms with FLAG_WAKE_FROM_IDLE or mPendingIdleUntil alarm are not deferred
3052 if (DEBUG_BG_LIMIT) {
3053 Slog.d(TAG, "Deferring alarm " + alarm + " due to user forced app standby");
3054 }
3055 ArrayList<Alarm> alarmsForUid = mPendingBackgroundAlarms.get(alarm.creatorUid);
3056 if (alarmsForUid == null) {
3057 alarmsForUid = new ArrayList<>();
3058 mPendingBackgroundAlarms.put(alarm.creatorUid, alarmsForUid);
3059 }
3060 alarmsForUid.add(alarm);
3061 continue;
3062 }
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07003063
Christopher Tatee0a22b32013-07-11 14:43:13 -07003064 alarm.count = 1;
3065 triggerList.add(alarm);
Dianne Hackbornf70faed2015-04-21 14:11:38 -07003066 if ((alarm.flags&AlarmManager.FLAG_WAKE_FROM_IDLE) != 0) {
3067 EventLogTags.writeDeviceIdleWakeFromIdle(mPendingIdleUntil != null ? 1 : 0,
Christopher Tate14a7bb02015-10-01 10:24:31 -07003068 alarm.statsTag);
Dianne Hackbornf70faed2015-04-21 14:11:38 -07003069 }
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07003070 if (mPendingIdleUntil == alarm) {
3071 mPendingIdleUntil = null;
3072 rebatchAllAlarmsLocked(false);
3073 restorePendingWhileIdleAlarmsLocked();
3074 }
Dianne Hackbornf70faed2015-04-21 14:11:38 -07003075 if (mNextWakeFromIdle == alarm) {
3076 mNextWakeFromIdle = null;
3077 rebatchAllAlarmsLocked(false);
3078 }
Christopher Tatee0a22b32013-07-11 14:43:13 -07003079
3080 // Recurring alarms may have passed several alarm intervals while the
3081 // phone was asleep or off, so pass a trigger count when sending them.
3082 if (alarm.repeatInterval > 0) {
3083 // this adjustment will be zero if we're late by
3084 // less than one full repeat interval
Suprabh Shuklad65e58a2018-02-05 20:36:08 -08003085 alarm.count += (nowELAPSED - alarm.expectedWhenElapsed) / alarm.repeatInterval;
Christopher Tatee0a22b32013-07-11 14:43:13 -07003086
3087 // Also schedule its next recurrence
3088 final long delta = alarm.count * alarm.repeatInterval;
3089 final long nextElapsed = alarm.whenElapsed + delta;
Christopher Tate3e04b472013-10-21 17:51:31 -07003090 setImplLocked(alarm.type, alarm.when + delta, nextElapsed, alarm.windowLength,
Christopher Tatee0a22b32013-07-11 14:43:13 -07003091 maxTriggerTime(nowELAPSED, nextElapsed, alarm.repeatInterval),
Christopher Tate14a7bb02015-10-01 10:24:31 -07003092 alarm.repeatInterval, alarm.operation, null, null, alarm.flags, true,
3093 alarm.workSource, alarm.alarmClock, alarm.uid, alarm.packageName);
Christopher Tate864d42e2014-12-02 11:48:53 -08003094 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003095
Christopher Tate864d42e2014-12-02 11:48:53 -08003096 if (alarm.wakeup) {
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07003097 hasWakeup = true;
3098 }
Adrian Roosc42a1e12014-07-07 23:35:53 +02003099
3100 // We removed an alarm clock. Let the caller recompute the next alarm clock.
3101 if (alarm.alarmClock != null) {
3102 mNextAlarmClockMayChange = true;
3103 }
Dianne Hackborn390517b2013-05-30 15:03:32 -07003104 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003105 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003106
Christopher Tate1590f1e2014-10-02 17:27:57 -07003107 // This is a new alarm delivery set; bump the sequence number to indicate that
3108 // all apps' alarm delivery classes should be recalculated.
3109 mCurrentSeq++;
3110 calculateDeliveryPriorities(triggerList);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003111 Collections.sort(triggerList, mAlarmDispatchComparator);
3112
3113 if (localLOGV) {
3114 for (int i=0; i<triggerList.size(); i++) {
3115 Slog.v(TAG, "Triggering alarm #" + i + ": " + triggerList.get(i));
3116 }
3117 }
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07003118
3119 return hasWakeup;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003120 }
Christopher Tatee0a22b32013-07-11 14:43:13 -07003121
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003122 /**
3123 * This Comparator sorts Alarms into increasing time order.
3124 */
3125 public static class IncreasingTimeOrder implements Comparator<Alarm> {
3126 public int compare(Alarm a1, Alarm a2) {
jinho.park1acd32a2015-05-27 14:44:18 +09003127 long when1 = a1.whenElapsed;
3128 long when2 = a2.whenElapsed;
Charles Tsaicdaaeee2015-05-20 18:16:48 +08003129 if (when1 > when2) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003130 return 1;
3131 }
Charles Tsaicdaaeee2015-05-20 18:16:48 +08003132 if (when1 < when2) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003133 return -1;
3134 }
3135 return 0;
3136 }
3137 }
Kweku Adams61e03292017-10-19 14:27:12 -07003138
Makoto Onuki2206af32017-11-21 16:25:35 -08003139 @VisibleForTesting
3140 static class Alarm {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003141 public final int type;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07003142 public final long origWhen;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003143 public final boolean wakeup;
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07003144 public final PendingIntent operation;
Christopher Tate14a7bb02015-10-01 10:24:31 -07003145 public final IAlarmListener listener;
3146 public final String listenerTag;
3147 public final String statsTag;
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07003148 public final WorkSource workSource;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07003149 public final int flags;
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07003150 public final AlarmManager.AlarmClockInfo alarmClock;
3151 public final int uid;
Christopher Tate14a7bb02015-10-01 10:24:31 -07003152 public final int creatorUid;
3153 public final String packageName;
Suprabh Shukla75edab12018-01-29 14:09:06 -08003154 public final String sourcePackage;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003155 public int count;
3156 public long when;
Christopher Tate3e04b472013-10-21 17:51:31 -07003157 public long windowLength;
Christopher Tatee0a22b32013-07-11 14:43:13 -07003158 public long whenElapsed; // 'when' in the elapsed time base
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07003159 public long maxWhenElapsed; // also in the elapsed time base
Suprabh Shuklad65e58a2018-02-05 20:36:08 -08003160 // Expected alarm expiry time before app standby deferring is applied.
3161 public long expectedWhenElapsed;
3162 public long expectedMaxWhenElapsed;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003163 public long repeatInterval;
Christopher Tate1590f1e2014-10-02 17:27:57 -07003164 public PriorityClass priorityClass;
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07003165
Christopher Tate3e04b472013-10-21 17:51:31 -07003166 public Alarm(int _type, long _when, long _whenElapsed, long _windowLength, long _maxWhen,
Christopher Tate14a7bb02015-10-01 10:24:31 -07003167 long _interval, PendingIntent _op, IAlarmListener _rec, String _listenerTag,
3168 WorkSource _ws, int _flags, AlarmManager.AlarmClockInfo _info,
3169 int _uid, String _pkgName) {
Christopher Tatee0a22b32013-07-11 14:43:13 -07003170 type = _type;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07003171 origWhen = _when;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003172 wakeup = _type == AlarmManager.ELAPSED_REALTIME_WAKEUP
3173 || _type == AlarmManager.RTC_WAKEUP;
Christopher Tatee0a22b32013-07-11 14:43:13 -07003174 when = _when;
3175 whenElapsed = _whenElapsed;
Suprabh Shuklad65e58a2018-02-05 20:36:08 -08003176 expectedWhenElapsed = _whenElapsed;
Christopher Tate3e04b472013-10-21 17:51:31 -07003177 windowLength = _windowLength;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07003178 maxWhenElapsed = _maxWhen;
Suprabh Shuklad65e58a2018-02-05 20:36:08 -08003179 expectedMaxWhenElapsed = _maxWhen;
Christopher Tatee0a22b32013-07-11 14:43:13 -07003180 repeatInterval = _interval;
3181 operation = _op;
Christopher Tate14a7bb02015-10-01 10:24:31 -07003182 listener = _rec;
3183 listenerTag = _listenerTag;
3184 statsTag = makeTag(_op, _listenerTag, _type);
David Christieebe51fc2013-07-26 13:23:29 -07003185 workSource = _ws;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07003186 flags = _flags;
Adrian Roosc42a1e12014-07-07 23:35:53 +02003187 alarmClock = _info;
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07003188 uid = _uid;
Christopher Tate14a7bb02015-10-01 10:24:31 -07003189 packageName = _pkgName;
Suprabh Shukla75edab12018-01-29 14:09:06 -08003190 sourcePackage = (operation != null) ? operation.getCreatorPackage() : packageName;
Christopher Tate14a7bb02015-10-01 10:24:31 -07003191 creatorUid = (operation != null) ? operation.getCreatorUid() : uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003192 }
Christopher Tatee0a22b32013-07-11 14:43:13 -07003193
Christopher Tate14a7bb02015-10-01 10:24:31 -07003194 public static String makeTag(PendingIntent pi, String tag, int type) {
3195 final String alarmString = type == ELAPSED_REALTIME_WAKEUP || type == RTC_WAKEUP
3196 ? "*walarm*:" : "*alarm*:";
3197 return (pi != null) ? pi.getTag(alarmString) : (alarmString + tag);
3198 }
3199
3200 public WakeupEvent makeWakeupEvent(long nowRTC) {
3201 return new WakeupEvent(nowRTC, creatorUid,
3202 (operation != null)
3203 ? operation.getIntent().getAction()
3204 : ("<listener>:" + listenerTag));
3205 }
3206
3207 // Returns true if either matches
3208 public boolean matches(PendingIntent pi, IAlarmListener rec) {
3209 return (operation != null)
3210 ? operation.equals(pi)
Lorenzo Colitti9b43ce02015-11-22 22:00:08 +09003211 : rec != null && listener.asBinder().equals(rec.asBinder());
Christopher Tate14a7bb02015-10-01 10:24:31 -07003212 }
3213
3214 public boolean matches(String packageName) {
Suprabh Shukla75edab12018-01-29 14:09:06 -08003215 return packageName.equals(sourcePackage);
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07003216 }
3217
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003218 @Override
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07003219 public String toString() {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003220 StringBuilder sb = new StringBuilder(128);
3221 sb.append("Alarm{");
3222 sb.append(Integer.toHexString(System.identityHashCode(this)));
3223 sb.append(" type ");
3224 sb.append(type);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003225 sb.append(" when ");
3226 sb.append(when);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003227 sb.append(" ");
Suprabh Shukla75edab12018-01-29 14:09:06 -08003228 sb.append(sourcePackage);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003229 sb.append('}');
3230 return sb.toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003231 }
3232
Kweku Adams61e03292017-10-19 14:27:12 -07003233 public void dump(PrintWriter pw, String prefix, long nowELAPSED, long nowRTC,
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07003234 SimpleDateFormat sdf) {
3235 final boolean isRtc = (type == RTC || type == RTC_WAKEUP);
Christopher Tate14a7bb02015-10-01 10:24:31 -07003236 pw.print(prefix); pw.print("tag="); pw.println(statsTag);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003237 pw.print(prefix); pw.print("type="); pw.print(type);
Suprabh Shuklad65e58a2018-02-05 20:36:08 -08003238 pw.print(" expectedWhenElapsed="); TimeUtils.formatDuration(
3239 expectedWhenElapsed, nowELAPSED, pw);
3240 pw.print(" expectedMaxWhenElapsed="); TimeUtils.formatDuration(
3241 expectedMaxWhenElapsed, nowELAPSED, pw);
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07003242 pw.print(" whenElapsed="); TimeUtils.formatDuration(whenElapsed,
3243 nowELAPSED, pw);
Suprabh Shukla2fa95452018-02-12 12:53:23 -08003244 pw.print(" maxWhenElapsed="); TimeUtils.formatDuration(maxWhenElapsed,
3245 nowELAPSED, pw);
Christopher Tate14a7bb02015-10-01 10:24:31 -07003246 pw.print(" when=");
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07003247 if (isRtc) {
Christopher Tate14a7bb02015-10-01 10:24:31 -07003248 pw.print(sdf.format(new Date(when)));
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07003249 } else {
Christopher Tate14a7bb02015-10-01 10:24:31 -07003250 TimeUtils.formatDuration(when, nowELAPSED, pw);
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07003251 }
3252 pw.println();
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07003253 pw.print(prefix); pw.print("window="); TimeUtils.formatDuration(windowLength, pw);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003254 pw.print(" repeatInterval="); pw.print(repeatInterval);
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07003255 pw.print(" count="); pw.print(count);
3256 pw.print(" flags=0x"); pw.println(Integer.toHexString(flags));
Dianne Hackbornf70faed2015-04-21 14:11:38 -07003257 if (alarmClock != null) {
3258 pw.print(prefix); pw.println("Alarm clock:");
3259 pw.print(prefix); pw.print(" triggerTime=");
3260 pw.println(sdf.format(new Date(alarmClock.getTriggerTime())));
3261 pw.print(prefix); pw.print(" showIntent="); pw.println(alarmClock.getShowIntent());
3262 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07003263 pw.print(prefix); pw.print("operation="); pw.println(operation);
Christopher Tate14a7bb02015-10-01 10:24:31 -07003264 if (listener != null) {
3265 pw.print(prefix); pw.print("listener="); pw.println(listener.asBinder());
3266 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003267 }
Kweku Adams61e03292017-10-19 14:27:12 -07003268
3269 public void writeToProto(ProtoOutputStream proto, long fieldId, long nowElapsed,
3270 long nowRTC) {
3271 final long token = proto.start(fieldId);
3272
3273 proto.write(AlarmProto.TAG, statsTag);
3274 proto.write(AlarmProto.TYPE, type);
Kweku Adams923ec432017-12-11 18:05:38 -08003275 proto.write(AlarmProto.TIME_UNTIL_WHEN_ELAPSED_MS, whenElapsed - nowElapsed);
Kweku Adams61e03292017-10-19 14:27:12 -07003276 proto.write(AlarmProto.WINDOW_LENGTH_MS, windowLength);
3277 proto.write(AlarmProto.REPEAT_INTERVAL_MS, repeatInterval);
3278 proto.write(AlarmProto.COUNT, count);
3279 proto.write(AlarmProto.FLAGS, flags);
3280 if (alarmClock != null) {
3281 alarmClock.writeToProto(proto, AlarmProto.ALARM_CLOCK);
3282 }
3283 if (operation != null) {
3284 operation.writeToProto(proto, AlarmProto.OPERATION);
3285 }
3286 if (listener != null) {
3287 proto.write(AlarmProto.LISTENER, listener.asBinder().toString());
3288 }
3289
3290 proto.end(token);
3291 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003292 }
Christopher Tate18a75f12013-07-01 18:18:59 -07003293
Christopher Tatee0a22b32013-07-11 14:43:13 -07003294 void recordWakeupAlarms(ArrayList<Batch> batches, long nowELAPSED, long nowRTC) {
3295 final int numBatches = batches.size();
Christopher Tatee982faf2013-07-19 14:51:44 -07003296 for (int nextBatch = 0; nextBatch < numBatches; nextBatch++) {
3297 Batch b = batches.get(nextBatch);
Christopher Tatee0a22b32013-07-11 14:43:13 -07003298 if (b.start > nowELAPSED) {
Christopher Tate18a75f12013-07-01 18:18:59 -07003299 break;
3300 }
3301
Christopher Tatee0a22b32013-07-11 14:43:13 -07003302 final int numAlarms = b.alarms.size();
Christopher Tatee982faf2013-07-19 14:51:44 -07003303 for (int nextAlarm = 0; nextAlarm < numAlarms; nextAlarm++) {
3304 Alarm a = b.alarms.get(nextAlarm);
Christopher Tate14a7bb02015-10-01 10:24:31 -07003305 mRecentWakeups.add(a.makeWakeupEvent(nowRTC));
Christopher Tatee0a22b32013-07-11 14:43:13 -07003306 }
Christopher Tate18a75f12013-07-01 18:18:59 -07003307 }
3308 }
3309
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07003310 long currentNonWakeupFuzzLocked(long nowELAPSED) {
3311 long timeSinceOn = nowELAPSED - mNonInteractiveStartTime;
3312 if (timeSinceOn < 5*60*1000) {
3313 // If the screen has been off for 5 minutes, only delay by at most two minutes.
3314 return 2*60*1000;
3315 } else if (timeSinceOn < 30*60*1000) {
3316 // If the screen has been off for 30 minutes, only delay by at most 15 minutes.
3317 return 15*60*1000;
3318 } else {
3319 // Otherwise, we will delay by at most an hour.
3320 return 60*60*1000;
3321 }
3322 }
3323
Dianne Hackbornf70faed2015-04-21 14:11:38 -07003324 static int fuzzForDuration(long duration) {
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07003325 if (duration < 15*60*1000) {
3326 // If the duration until the time is less than 15 minutes, the maximum fuzz
3327 // is the duration.
Dianne Hackbornf70faed2015-04-21 14:11:38 -07003328 return (int)duration;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07003329 } else if (duration < 90*60*1000) {
3330 // If duration is less than 1 1/2 hours, the maximum fuzz is 15 minutes,
3331 return 15*60*1000;
3332 } else {
3333 // Otherwise, we will fuzz by at most half an hour.
3334 return 30*60*1000;
3335 }
3336 }
3337
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07003338 boolean checkAllowNonWakeupDelayLocked(long nowELAPSED) {
3339 if (mInteractive) {
3340 return false;
3341 }
3342 if (mLastAlarmDeliveryTime <= 0) {
3343 return false;
3344 }
minho.choo649acab2014-12-12 16:13:55 +09003345 if (mPendingNonWakeupAlarms.size() > 0 && mNextNonWakeupDeliveryTime < nowELAPSED) {
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07003346 // This is just a little paranoia, if somehow we have pending non-wakeup alarms
3347 // and the next delivery time is in the past, then just deliver them all. This
3348 // avoids bugs where we get stuck in a loop trying to poll for alarms.
3349 return false;
3350 }
3351 long timeSinceLast = nowELAPSED - mLastAlarmDeliveryTime;
3352 return timeSinceLast <= currentNonWakeupFuzzLocked(nowELAPSED);
3353 }
3354
3355 void deliverAlarmsLocked(ArrayList<Alarm> triggerList, long nowELAPSED) {
3356 mLastAlarmDeliveryTime = nowELAPSED;
3357 for (int i=0; i<triggerList.size(); i++) {
3358 Alarm alarm = triggerList.get(i);
Dianne Hackborna750a632015-06-16 17:18:23 -07003359 final boolean allowWhileIdle = (alarm.flags&AlarmManager.FLAG_ALLOW_WHILE_IDLE) != 0;
Tim Murray175c0f92017-11-28 15:01:04 -08003360 if (alarm.wakeup) {
3361 Trace.traceBegin(Trace.TRACE_TAG_POWER, "Dispatch wakeup alarm to " + alarm.packageName);
3362 } else {
3363 Trace.traceBegin(Trace.TRACE_TAG_POWER, "Dispatch non-wakeup alarm to " + alarm.packageName);
3364 }
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07003365 try {
Christopher Tate2ff5a732014-09-18 13:47:57 -07003366 if (localLOGV) {
3367 Slog.v(TAG, "sending alarm " + alarm);
3368 }
Dianne Hackborn1e383822015-04-10 14:02:33 -07003369 if (RECORD_ALARMS_IN_HISTORY) {
Narayan Kamath695cf722017-12-21 18:32:47 +00003370 ActivityManager.noteAlarmStart(alarm.operation, alarm.workSource, alarm.uid,
3371 alarm.statsTag);
Dianne Hackborn1e383822015-04-10 14:02:33 -07003372 }
Christopher Tate14a7bb02015-10-01 10:24:31 -07003373 mDeliveryTracker.deliverLocked(alarm, nowELAPSED, allowWhileIdle);
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07003374 } catch (RuntimeException e) {
3375 Slog.w(TAG, "Failure sending alarm.", e);
3376 }
Tim Murray175c0f92017-11-28 15:01:04 -08003377 Trace.traceEnd(Trace.TRACE_TAG_POWER);
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07003378 }
3379 }
3380
Suprabh Shuklad65e58a2018-02-05 20:36:08 -08003381 private boolean isExemptFromAppStandby(Alarm a) {
3382 return a.alarmClock != null || UserHandle.isCore(a.creatorUid)
3383 || (a.flags & FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED) != 0;
3384 }
3385
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003386 private class AlarmThread extends Thread
3387 {
3388 public AlarmThread()
3389 {
3390 super("AlarmManager");
3391 }
Kweku Adams61e03292017-10-19 14:27:12 -07003392
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003393 public void run()
3394 {
Dianne Hackborn390517b2013-05-30 15:03:32 -07003395 ArrayList<Alarm> triggerList = new ArrayList<Alarm>();
3396
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003397 while (true)
3398 {
Greg Hackmanna1d6f922013-12-09 16:56:53 -08003399 int result = waitForAlarm(mNativeData);
Dianne Hackborn390517b2013-05-30 15:03:32 -07003400
Dianne Hackbornc3527222015-05-13 14:03:20 -07003401 final long nowRTC = System.currentTimeMillis();
3402 final long nowELAPSED = SystemClock.elapsedRealtime();
Christopher Tate8b98ade2018-02-09 11:13:19 -08003403 synchronized (mLock) {
3404 mLastWakeup = nowELAPSED;
3405 }
3406
3407 triggerList.clear();
Dianne Hackbornc3527222015-05-13 14:03:20 -07003408
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003409 if ((result & TIME_CHANGED_MASK) != 0) {
Dianne Hackbornc3527222015-05-13 14:03:20 -07003410 // The kernel can give us spurious time change notifications due to
3411 // small adjustments it makes internally; we want to filter those out.
3412 final long lastTimeChangeClockTime;
3413 final long expectedClockTime;
Dianne Hackborn998e6082014-09-11 19:13:23 -07003414 synchronized (mLock) {
Dianne Hackbornc3527222015-05-13 14:03:20 -07003415 lastTimeChangeClockTime = mLastTimeChangeClockTime;
3416 expectedClockTime = lastTimeChangeClockTime
3417 + (nowELAPSED - mLastTimeChangeRealtime);
Dianne Hackborn998e6082014-09-11 19:13:23 -07003418 }
Christopher Tate2b6e459e2017-02-17 14:33:52 -08003419 if (lastTimeChangeClockTime == 0 || nowRTC < (expectedClockTime-1000)
3420 || nowRTC > (expectedClockTime+1000)) {
3421 // The change is by at least +/- 1000 ms (or this is the first change),
Dianne Hackbornc3527222015-05-13 14:03:20 -07003422 // let's do it!
3423 if (DEBUG_BATCH) {
3424 Slog.v(TAG, "Time changed notification from kernel; rebatching");
3425 }
3426 removeImpl(mTimeTickSender);
Christopher Tatecf024712016-08-05 13:21:45 -07003427 removeImpl(mDateChangeSender);
Dianne Hackbornc3527222015-05-13 14:03:20 -07003428 rebatchAllAlarms();
3429 mClockReceiver.scheduleTimeTickEvent();
Christopher Tatecf024712016-08-05 13:21:45 -07003430 mClockReceiver.scheduleDateChangedEvent();
Dianne Hackbornc3527222015-05-13 14:03:20 -07003431 synchronized (mLock) {
3432 mNumTimeChanged++;
3433 mLastTimeChangeClockTime = nowRTC;
3434 mLastTimeChangeRealtime = nowELAPSED;
3435 }
3436 Intent intent = new Intent(Intent.ACTION_TIME_CHANGED);
3437 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
Christopher Tate2b6e459e2017-02-17 14:33:52 -08003438 | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
Chad Brubaker291df4f2017-03-14 10:23:02 -07003439 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
3440 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
Dianne Hackbornc3527222015-05-13 14:03:20 -07003441 getContext().sendBroadcastAsUser(intent, UserHandle.ALL);
3442
3443 // The world has changed on us, so we need to re-evaluate alarms
3444 // regardless of whether the kernel has told us one went off.
3445 result |= IS_WAKEUP_MASK;
3446 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003447 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003448
Dianne Hackbornc3527222015-05-13 14:03:20 -07003449 if (result != TIME_CHANGED_MASK) {
3450 // If this was anything besides just a time change, then figure what if
3451 // anything to do about alarms.
3452 synchronized (mLock) {
3453 if (localLOGV) Slog.v(
3454 TAG, "Checking for alarms... rtc=" + nowRTC
3455 + ", elapsed=" + nowELAPSED);
Christopher Tate18a75f12013-07-01 18:18:59 -07003456
Dianne Hackbornc3527222015-05-13 14:03:20 -07003457 if (WAKEUP_STATS) {
3458 if ((result & IS_WAKEUP_MASK) != 0) {
3459 long newEarliest = nowRTC - RECENT_WAKEUP_PERIOD;
3460 int n = 0;
3461 for (WakeupEvent event : mRecentWakeups) {
3462 if (event.when > newEarliest) break;
3463 n++; // number of now-stale entries at the list head
3464 }
3465 for (int i = 0; i < n; i++) {
3466 mRecentWakeups.remove();
3467 }
Christopher Tate18a75f12013-07-01 18:18:59 -07003468
Dianne Hackbornc3527222015-05-13 14:03:20 -07003469 recordWakeupAlarms(mAlarmBatches, nowELAPSED, nowRTC);
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07003470 }
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07003471 }
Dianne Hackbornc3527222015-05-13 14:03:20 -07003472
Christopher Tate8b98ade2018-02-09 11:13:19 -08003473 mLastTrigger = nowELAPSED;
Dianne Hackbornc3527222015-05-13 14:03:20 -07003474 boolean hasWakeup = triggerAlarmsLocked(triggerList, nowELAPSED, nowRTC);
3475 if (!hasWakeup && checkAllowNonWakeupDelayLocked(nowELAPSED)) {
3476 // if there are no wakeup alarms and the screen is off, we can
3477 // delay what we have so far until the future.
3478 if (mPendingNonWakeupAlarms.size() == 0) {
3479 mStartCurrentDelayTime = nowELAPSED;
3480 mNextNonWakeupDeliveryTime = nowELAPSED
3481 + ((currentNonWakeupFuzzLocked(nowELAPSED)*3)/2);
3482 }
3483 mPendingNonWakeupAlarms.addAll(triggerList);
3484 mNumDelayedAlarms += triggerList.size();
3485 rescheduleKernelAlarmsLocked();
3486 updateNextAlarmClockLocked();
3487 } else {
3488 // now deliver the alarm intents; if there are pending non-wakeup
3489 // alarms, we need to merge them in to the list. note we don't
3490 // just deliver them first because we generally want non-wakeup
3491 // alarms delivered after wakeup alarms.
Dianne Hackbornc3527222015-05-13 14:03:20 -07003492 if (mPendingNonWakeupAlarms.size() > 0) {
3493 calculateDeliveryPriorities(mPendingNonWakeupAlarms);
3494 triggerList.addAll(mPendingNonWakeupAlarms);
3495 Collections.sort(triggerList, mAlarmDispatchComparator);
3496 final long thisDelayTime = nowELAPSED - mStartCurrentDelayTime;
3497 mTotalDelayTime += thisDelayTime;
3498 if (mMaxDelayTime < thisDelayTime) {
3499 mMaxDelayTime = thisDelayTime;
3500 }
3501 mPendingNonWakeupAlarms.clear();
3502 }
Suprabh Shukla92994ab2018-01-31 17:39:30 -08003503 final ArraySet<Pair<String, Integer>> triggerPackages =
3504 new ArraySet<>();
3505 for (int i = 0; i < triggerList.size(); i++) {
3506 final Alarm a = triggerList.get(i);
Suprabh Shuklad65e58a2018-02-05 20:36:08 -08003507 if (!isExemptFromAppStandby(a)) {
Suprabh Shukla92994ab2018-01-31 17:39:30 -08003508 triggerPackages.add(Pair.create(
3509 a.sourcePackage, UserHandle.getUserId(a.creatorUid)));
Suprabh Shukla75edab12018-01-29 14:09:06 -08003510 }
3511 }
Dianne Hackbornc3527222015-05-13 14:03:20 -07003512 deliverAlarmsLocked(triggerList, nowELAPSED);
Suprabh Shukla92994ab2018-01-31 17:39:30 -08003513 reorderAlarmsBasedOnStandbyBuckets(triggerPackages);
3514 rescheduleKernelAlarmsLocked();
3515 updateNextAlarmClockLocked();
Dianne Hackbornc3527222015-05-13 14:03:20 -07003516 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003517 }
Dianne Hackbornaa9a59d2016-05-23 15:59:18 -07003518
3519 } else {
3520 // Just in case -- even though no wakeup flag was set, make sure
3521 // we have updated the kernel to the next alarm time.
Christopher Tate7b5b7cb2016-07-07 14:41:36 -07003522 synchronized (mLock) {
3523 rescheduleKernelAlarmsLocked();
3524 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003525 }
3526 }
3527 }
3528 }
Christopher Tatec4a07d12012-04-06 14:19:13 -07003529
David Christieebe51fc2013-07-26 13:23:29 -07003530 /**
3531 * Attribute blame for a WakeLock.
3532 * @param pi PendingIntent to attribute blame to if ws is null.
3533 * @param ws WorkSource to attribute blame.
Christopher Tate14a7bb02015-10-01 10:24:31 -07003534 * @param knownUid attribution uid; < 0 if we need to derive it from the PendingIntent sender
David Christieebe51fc2013-07-26 13:23:29 -07003535 */
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07003536 void setWakelockWorkSource(PendingIntent pi, WorkSource ws, int type, String tag,
Christopher Tate14a7bb02015-10-01 10:24:31 -07003537 int knownUid, boolean first) {
Christopher Tatec4a07d12012-04-06 14:19:13 -07003538 try {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003539 final boolean unimportant = pi == mTimeTickSender;
3540 mWakeLock.setUnimportantForLogging(unimportant);
Dianne Hackborn4590e522014-03-24 13:36:46 -07003541 if (first || mLastWakeLockUnimportantForLogging) {
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07003542 mWakeLock.setHistoryTag(tag);
Dianne Hackborn4590e522014-03-24 13:36:46 -07003543 } else {
3544 mWakeLock.setHistoryTag(null);
3545 }
3546 mLastWakeLockUnimportantForLogging = unimportant;
David Christieebe51fc2013-07-26 13:23:29 -07003547 if (ws != null) {
3548 mWakeLock.setWorkSource(ws);
3549 return;
3550 }
3551
Christopher Tate14a7bb02015-10-01 10:24:31 -07003552 final int uid = (knownUid >= 0)
3553 ? knownUid
Sudheer Shankadc589ac2016-11-10 15:30:17 -08003554 : ActivityManager.getService().getUidForIntentSender(pi.getTarget());
Christopher Tatec4a07d12012-04-06 14:19:13 -07003555 if (uid >= 0) {
3556 mWakeLock.setWorkSource(new WorkSource(uid));
3557 return;
3558 }
3559 } catch (Exception e) {
3560 }
3561
3562 // Something went wrong; fall back to attributing the lock to the OS
3563 mWakeLock.setWorkSource(null);
3564 }
3565
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003566 private class AlarmHandler extends Handler {
3567 public static final int ALARM_EVENT = 1;
Dianne Hackborn627dfa12015-11-11 18:10:30 -08003568 public static final int SEND_NEXT_ALARM_CLOCK_CHANGED = 2;
3569 public static final int LISTENER_TIMEOUT = 3;
3570 public static final int REPORT_ALARMS_ACTIVE = 4;
Suprabh Shukla75edab12018-01-29 14:09:06 -08003571 public static final int APP_STANDBY_BUCKET_CHANGED = 5;
3572 public static final int APP_STANDBY_PAROLE_CHANGED = 6;
Makoto Onuki4d298b52018-02-05 10:54:58 -08003573 public static final int REMOVE_FOR_STOPPED = 7;
Kweku Adams61e03292017-10-19 14:27:12 -07003574
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003575 public AlarmHandler() {
3576 }
Kweku Adams61e03292017-10-19 14:27:12 -07003577
Makoto Onuki4d298b52018-02-05 10:54:58 -08003578 public void postRemoveForStopped(int uid) {
3579 obtainMessage(REMOVE_FOR_STOPPED, uid, 0).sendToTarget();
3580 }
3581
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003582 public void handleMessage(Message msg) {
Christopher Tate14a7bb02015-10-01 10:24:31 -07003583 switch (msg.what) {
3584 case ALARM_EVENT: {
3585 ArrayList<Alarm> triggerList = new ArrayList<Alarm>();
3586 synchronized (mLock) {
3587 final long nowRTC = System.currentTimeMillis();
3588 final long nowELAPSED = SystemClock.elapsedRealtime();
3589 triggerAlarmsLocked(triggerList, nowELAPSED, nowRTC);
3590 updateNextAlarmClockLocked();
3591 }
Adrian Roosc42a1e12014-07-07 23:35:53 +02003592
Christopher Tate14a7bb02015-10-01 10:24:31 -07003593 // now trigger the alarms without the lock held
3594 for (int i=0; i<triggerList.size(); i++) {
3595 Alarm alarm = triggerList.get(i);
3596 try {
3597 alarm.operation.send();
3598 } catch (PendingIntent.CanceledException e) {
3599 if (alarm.repeatInterval > 0) {
3600 // This IntentSender is no longer valid, but this
3601 // is a repeating alarm, so toss the hoser.
3602 removeImpl(alarm.operation);
3603 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003604 }
3605 }
Christopher Tate14a7bb02015-10-01 10:24:31 -07003606 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003607 }
Christopher Tate14a7bb02015-10-01 10:24:31 -07003608
3609 case SEND_NEXT_ALARM_CLOCK_CHANGED:
3610 sendNextAlarmClockChanged();
3611 break;
3612
3613 case LISTENER_TIMEOUT:
3614 mDeliveryTracker.alarmTimedOut((IBinder) msg.obj);
3615 break;
3616
Dianne Hackborn627dfa12015-11-11 18:10:30 -08003617 case REPORT_ALARMS_ACTIVE:
3618 if (mLocalDeviceIdleController != null) {
3619 mLocalDeviceIdleController.setAlarmsActive(msg.arg1 != 0);
3620 }
3621 break;
3622
Suprabh Shukla75edab12018-01-29 14:09:06 -08003623 case APP_STANDBY_PAROLE_CHANGED:
3624 synchronized (mLock) {
3625 mAppStandbyParole = (Boolean) msg.obj;
Suprabh Shukla92994ab2018-01-31 17:39:30 -08003626 if (reorderAlarmsBasedOnStandbyBuckets(null)) {
3627 rescheduleKernelAlarmsLocked();
3628 updateNextAlarmClockLocked();
3629 }
Suprabh Shukla75edab12018-01-29 14:09:06 -08003630 }
3631 break;
3632
3633 case APP_STANDBY_BUCKET_CHANGED:
3634 synchronized (mLock) {
Suprabh Shukla92994ab2018-01-31 17:39:30 -08003635 final ArraySet<Pair<String, Integer>> filterPackages = new ArraySet<>();
3636 filterPackages.add(Pair.create((String) msg.obj, msg.arg1));
3637 if (reorderAlarmsBasedOnStandbyBuckets(filterPackages)) {
3638 rescheduleKernelAlarmsLocked();
3639 updateNextAlarmClockLocked();
3640 }
Suprabh Shukla75edab12018-01-29 14:09:06 -08003641 }
3642 break;
3643
Makoto Onuki4d298b52018-02-05 10:54:58 -08003644 case REMOVE_FOR_STOPPED:
3645 synchronized (mLock) {
3646 removeForStoppedLocked(msg.arg1);
3647 }
3648 break;
3649
Christopher Tate14a7bb02015-10-01 10:24:31 -07003650 default:
3651 // nope, just ignore it
3652 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003653 }
3654 }
3655 }
Kweku Adams61e03292017-10-19 14:27:12 -07003656
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003657 class ClockReceiver extends BroadcastReceiver {
3658 public ClockReceiver() {
3659 IntentFilter filter = new IntentFilter();
3660 filter.addAction(Intent.ACTION_TIME_TICK);
3661 filter.addAction(Intent.ACTION_DATE_CHANGED);
Adam Lesinski182f73f2013-12-05 16:48:06 -08003662 getContext().registerReceiver(this, filter);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003663 }
Kweku Adams61e03292017-10-19 14:27:12 -07003664
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003665 @Override
3666 public void onReceive(Context context, Intent intent) {
3667 if (intent.getAction().equals(Intent.ACTION_TIME_TICK)) {
Christopher Tate385e4982013-07-23 18:22:29 -07003668 if (DEBUG_BATCH) {
3669 Slog.v(TAG, "Received TIME_TICK alarm; rescheduling");
3670 }
Christopher Tate12cf0b62018-01-05 18:40:14 -08003671 synchronized (mLock) {
3672 mLastTickReceived = System.currentTimeMillis();
3673 }
Christopher Tate385e4982013-07-23 18:22:29 -07003674 scheduleTimeTickEvent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003675 } else if (intent.getAction().equals(Intent.ACTION_DATE_CHANGED)) {
3676 // Since the kernel does not keep track of DST, we need to
3677 // reset the TZ information at the beginning of each day
3678 // based off of the current Zone gmt offset + userspace tracked
3679 // daylight savings information.
3680 TimeZone zone = TimeZone.getTimeZone(SystemProperties.get(TIMEZONE_PROPERTY));
Lavettacn Xiaoc84cc4f2010-08-30 12:47:23 +02003681 int gmtOffset = zone.getOffset(System.currentTimeMillis());
Greg Hackmanna1d6f922013-12-09 16:56:53 -08003682 setKernelTimezone(mNativeData, -(gmtOffset / 60000));
Christopher Tate385e4982013-07-23 18:22:29 -07003683 scheduleDateChangedEvent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003684 }
3685 }
Kweku Adams61e03292017-10-19 14:27:12 -07003686
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003687 public void scheduleTimeTickEvent() {
Paul Westbrook51608a52011-08-25 13:18:54 -07003688 final long currentTime = System.currentTimeMillis();
Sungmin Choi563914a2013-01-10 17:28:40 +09003689 final long nextTime = 60000 * ((currentTime / 60000) + 1);
Paul Westbrook51608a52011-08-25 13:18:54 -07003690
3691 // Schedule this event for the amount of time that it would take to get to
3692 // the top of the next minute.
Sungmin Choi563914a2013-01-10 17:28:40 +09003693 final long tickEventDelay = nextTime - currentTime;
Paul Westbrook51608a52011-08-25 13:18:54 -07003694
David Christieebe51fc2013-07-26 13:23:29 -07003695 final WorkSource workSource = null; // Let system take blame for time tick events.
Adam Lesinski182f73f2013-12-05 16:48:06 -08003696 setImpl(ELAPSED_REALTIME, SystemClock.elapsedRealtime() + tickEventDelay, 0,
Christopher Tate14a7bb02015-10-01 10:24:31 -07003697 0, mTimeTickSender, null, null, AlarmManager.FLAG_STANDALONE, workSource,
3698 null, Process.myUid(), "android");
Christopher Tate12cf0b62018-01-05 18:40:14 -08003699
3700 // Finally, remember when we set the tick alarm
3701 synchronized (mLock) {
3702 mLastTickSet = currentTime;
3703 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003704 }
Christopher Tate385e4982013-07-23 18:22:29 -07003705
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003706 public void scheduleDateChangedEvent() {
3707 Calendar calendar = Calendar.getInstance();
3708 calendar.setTimeInMillis(System.currentTimeMillis());
Christopher Tateafa8b982016-08-10 16:15:48 -07003709 calendar.set(Calendar.HOUR_OF_DAY, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003710 calendar.set(Calendar.MINUTE, 0);
3711 calendar.set(Calendar.SECOND, 0);
3712 calendar.set(Calendar.MILLISECOND, 0);
3713 calendar.add(Calendar.DAY_OF_MONTH, 1);
David Christieebe51fc2013-07-26 13:23:29 -07003714
3715 final WorkSource workSource = null; // Let system take blame for date change events.
Christopher Tate14a7bb02015-10-01 10:24:31 -07003716 setImpl(RTC, calendar.getTimeInMillis(), 0, 0, mDateChangeSender, null, null,
3717 AlarmManager.FLAG_STANDALONE, workSource, null,
3718 Process.myUid(), "android");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003719 }
3720 }
Kweku Adams61e03292017-10-19 14:27:12 -07003721
Dianne Hackbornd4e6d462014-05-16 16:32:37 -07003722 class InteractiveStateReceiver extends BroadcastReceiver {
3723 public InteractiveStateReceiver() {
3724 IntentFilter filter = new IntentFilter();
3725 filter.addAction(Intent.ACTION_SCREEN_OFF);
3726 filter.addAction(Intent.ACTION_SCREEN_ON);
3727 filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
3728 getContext().registerReceiver(this, filter);
3729 }
3730
3731 @Override
3732 public void onReceive(Context context, Intent intent) {
3733 synchronized (mLock) {
3734 interactiveStateChangedLocked(Intent.ACTION_SCREEN_ON.equals(intent.getAction()));
3735 }
3736 }
3737 }
3738
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003739 class UninstallReceiver extends BroadcastReceiver {
3740 public UninstallReceiver() {
3741 IntentFilter filter = new IntentFilter();
3742 filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
3743 filter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003744 filter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003745 filter.addDataScheme("package");
Adam Lesinski182f73f2013-12-05 16:48:06 -08003746 getContext().registerReceiver(this, filter);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003747 // Register for events related to sdcard installation.
3748 IntentFilter sdFilter = new IntentFilter();
Suchi Amalapurapub56ae202010-02-04 22:51:07 -08003749 sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003750 sdFilter.addAction(Intent.ACTION_USER_STOPPED);
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07003751 sdFilter.addAction(Intent.ACTION_UID_REMOVED);
Adam Lesinski182f73f2013-12-05 16:48:06 -08003752 getContext().registerReceiver(this, sdFilter);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003753 }
Kweku Adams61e03292017-10-19 14:27:12 -07003754
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003755 @Override
3756 public void onReceive(Context context, Intent intent) {
Christopher Tate1d99c392017-12-07 16:54:04 -08003757 final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003758 synchronized (mLock) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003759 String action = intent.getAction();
3760 String pkgList[] = null;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003761 if (Intent.ACTION_QUERY_PACKAGE_RESTART.equals(action)) {
3762 pkgList = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3763 for (String packageName : pkgList) {
3764 if (lookForPackageLocked(packageName)) {
3765 setResultCode(Activity.RESULT_OK);
3766 return;
3767 }
3768 }
3769 return;
3770 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003771 pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003772 } else if (Intent.ACTION_USER_STOPPED.equals(action)) {
3773 int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
3774 if (userHandle >= 0) {
3775 removeUserLocked(userHandle);
Suprabh Shukla75edab12018-01-29 14:09:06 -08003776 for (int i = mLastAlarmDeliveredForPackage.size() - 1; i >= 0; i--) {
3777 final Pair<String, Integer> packageUser =
3778 mLastAlarmDeliveredForPackage.keyAt(i);
3779 if (packageUser.second == userHandle) {
3780 mLastAlarmDeliveredForPackage.removeAt(i);
3781 }
3782 }
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003783 }
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07003784 } else if (Intent.ACTION_UID_REMOVED.equals(action)) {
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07003785 if (uid >= 0) {
3786 mLastAllowWhileIdleDispatch.delete(uid);
Makoto Onukiadb50d82018-01-29 16:20:30 -08003787 mUseAllowWhileIdleShortTime.delete(uid);
Dianne Hackborn3d1933c42015-06-10 16:25:57 -07003788 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003789 } else {
Dianne Hackborn409578f2010-03-10 17:23:43 -08003790 if (Intent.ACTION_PACKAGE_REMOVED.equals(action)
3791 && intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
3792 // This package is being updated; don't kill its alarms.
3793 return;
3794 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003795 Uri data = intent.getData();
3796 if (data != null) {
3797 String pkg = data.getSchemeSpecificPart();
3798 if (pkg != null) {
3799 pkgList = new String[]{pkg};
3800 }
3801 }
3802 }
3803 if (pkgList != null && (pkgList.length > 0)) {
Suprabh Shukla75edab12018-01-29 14:09:06 -08003804 for (int i = mLastAlarmDeliveredForPackage.size() - 1; i >= 0; i--) {
3805 Pair<String, Integer> packageUser = mLastAlarmDeliveredForPackage.keyAt(i);
3806 if (ArrayUtils.contains(pkgList, packageUser.first)
3807 && packageUser.second == UserHandle.getUserId(uid)) {
3808 mLastAlarmDeliveredForPackage.removeAt(i);
3809 }
3810 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003811 for (String pkg : pkgList) {
Christopher Tate1d99c392017-12-07 16:54:04 -08003812 if (uid >= 0) {
3813 // package-removed case
3814 removeLocked(uid);
3815 } else {
3816 // external-applications-unavailable etc case
3817 removeLocked(pkg);
3818 }
Christopher Tate1590f1e2014-10-02 17:27:57 -07003819 mPriorities.remove(pkg);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003820 for (int i=mBroadcastStats.size()-1; i>=0; i--) {
3821 ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(i);
3822 if (uidStats.remove(pkg) != null) {
3823 if (uidStats.size() <= 0) {
3824 mBroadcastStats.removeAt(i);
3825 }
3826 }
3827 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003828 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003829 }
3830 }
3831 }
3832 }
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07003833
3834 final class UidObserver extends IUidObserver.Stub {
Dianne Hackborn3e99f652017-07-05 16:33:56 -07003835 @Override public void onUidStateChanged(int uid, int procState, long procStateSeq) {
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07003836 }
3837
Dianne Hackborn3e99f652017-07-05 16:33:56 -07003838 @Override public void onUidGone(int uid, boolean disabled) {
Makoto Onuki4d298b52018-02-05 10:54:58 -08003839 if (disabled) {
3840 mHandler.postRemoveForStopped(uid);
Dianne Hackborne07641d2016-11-09 15:07:23 -08003841 }
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07003842 }
3843
Dianne Hackborn3e99f652017-07-05 16:33:56 -07003844 @Override public void onUidActive(int uid) {
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07003845 }
3846
Dianne Hackborn3e99f652017-07-05 16:33:56 -07003847 @Override public void onUidIdle(int uid, boolean disabled) {
Makoto Onuki4d298b52018-02-05 10:54:58 -08003848 if (disabled) {
3849 mHandler.postRemoveForStopped(uid);
Dianne Hackbornde9c48b2015-11-20 14:49:59 -08003850 }
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07003851 }
Dianne Hackborn3e99f652017-07-05 16:33:56 -07003852
3853 @Override public void onUidCachedChanged(int uid, boolean cached) {
3854 }
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07003855 };
3856
Suprabh Shukla75edab12018-01-29 14:09:06 -08003857 /**
3858 * Tracking of app assignments to standby buckets
3859 */
3860 final class AppStandbyTracker extends UsageStatsManagerInternal.AppIdleStateChangeListener {
3861 @Override
3862 public void onAppIdleStateChanged(final String packageName, final @UserIdInt int userId,
Amith Yamasani119be9a2018-02-18 22:23:00 -08003863 boolean idle, int bucket, int reason) {
Suprabh Shukla75edab12018-01-29 14:09:06 -08003864 if (DEBUG_STANDBY) {
3865 Slog.d(TAG, "Package " + packageName + " for user " + userId + " now in bucket " +
3866 bucket);
3867 }
3868 mHandler.removeMessages(AlarmHandler.APP_STANDBY_BUCKET_CHANGED);
Suprabh Shukla92994ab2018-01-31 17:39:30 -08003869 mHandler.obtainMessage(AlarmHandler.APP_STANDBY_BUCKET_CHANGED, userId, -1, packageName)
3870 .sendToTarget();
Suprabh Shukla75edab12018-01-29 14:09:06 -08003871 }
3872
3873 @Override
3874 public void onParoleStateChanged(boolean isParoleOn) {
3875 if (DEBUG_STANDBY) {
3876 Slog.d(TAG, "Global parole state now " + (isParoleOn ? "ON" : "OFF"));
3877 }
3878 mHandler.removeMessages(AlarmHandler.APP_STANDBY_BUCKET_CHANGED);
3879 mHandler.removeMessages(AlarmHandler.APP_STANDBY_PAROLE_CHANGED);
3880 mHandler.obtainMessage(AlarmHandler.APP_STANDBY_PAROLE_CHANGED,
3881 Boolean.valueOf(isParoleOn)).sendToTarget();
3882 }
3883 };
3884
Makoto Onuki2206af32017-11-21 16:25:35 -08003885 private final Listener mForceAppStandbyListener = new Listener() {
Suprabh Shukladb6bf662017-08-30 15:41:53 -07003886 @Override
Makoto Onuki2206af32017-11-21 16:25:35 -08003887 public void unblockAllUnrestrictedAlarms() {
Suprabh Shukladb6bf662017-08-30 15:41:53 -07003888 synchronized (mLock) {
Makoto Onuki2206af32017-11-21 16:25:35 -08003889 sendAllUnrestrictedPendingBackgroundAlarmsLocked();
Suprabh Shukladb6bf662017-08-30 15:41:53 -07003890 }
3891 }
Makoto Onuki2206af32017-11-21 16:25:35 -08003892
3893 @Override
3894 public void unblockAlarmsForUid(int uid) {
3895 synchronized (mLock) {
3896 sendPendingBackgroundAlarmsLocked(uid, null);
3897 }
3898 }
3899
3900 @Override
3901 public void unblockAlarmsForUidPackage(int uid, String packageName) {
3902 synchronized (mLock) {
3903 sendPendingBackgroundAlarmsLocked(uid, packageName);
3904 }
3905 }
Makoto Onukiadb50d82018-01-29 16:20:30 -08003906
3907 @Override
3908 public void onUidForeground(int uid, boolean foreground) {
3909 synchronized (mLock) {
3910 if (foreground) {
3911 mUseAllowWhileIdleShortTime.put(uid, true);
3912
3913 // Note we don't have to drain the pending while-idle alarms here, because
3914 // this event should coincide with unblockAlarmsForUid().
3915 }
3916 }
3917 }
Makoto Onuki2206af32017-11-21 16:25:35 -08003918 };
Suprabh Shukladb6bf662017-08-30 15:41:53 -07003919
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003920 private final BroadcastStats getStatsLocked(PendingIntent pi) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003921 String pkg = pi.getCreatorPackage();
3922 int uid = pi.getCreatorUid();
Christopher Tate14a7bb02015-10-01 10:24:31 -07003923 return getStatsLocked(uid, pkg);
3924 }
3925
3926 private final BroadcastStats getStatsLocked(int uid, String pkgName) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003927 ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.get(uid);
3928 if (uidStats == null) {
3929 uidStats = new ArrayMap<String, BroadcastStats>();
3930 mBroadcastStats.put(uid, uidStats);
3931 }
Christopher Tate14a7bb02015-10-01 10:24:31 -07003932 BroadcastStats bs = uidStats.get(pkgName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003933 if (bs == null) {
Christopher Tate14a7bb02015-10-01 10:24:31 -07003934 bs = new BroadcastStats(uid, pkgName);
3935 uidStats.put(pkgName, bs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003936 }
3937 return bs;
3938 }
Dianne Hackborn81038902012-11-26 17:04:09 -08003939
Christopher Tate21e9f192017-08-08 13:49:11 -07003940 /**
3941 * Canonical count of (operation.send() - onSendFinished()) and
3942 * listener send/complete/timeout invocations.
3943 * Guarded by the usual lock.
3944 */
3945 @GuardedBy("mLock")
3946 private int mSendCount = 0;
3947 @GuardedBy("mLock")
Christopher Tateeabba732017-08-17 17:12:52 -07003948 private int mSendFinishCount = 0;
3949 @GuardedBy("mLock")
Christopher Tate21e9f192017-08-08 13:49:11 -07003950 private int mListenerCount = 0;
Christopher Tateeabba732017-08-17 17:12:52 -07003951 @GuardedBy("mLock")
3952 private int mListenerFinishCount = 0;
Christopher Tate21e9f192017-08-08 13:49:11 -07003953
Christopher Tate14a7bb02015-10-01 10:24:31 -07003954 class DeliveryTracker extends IAlarmCompleteListener.Stub implements PendingIntent.OnFinished {
Christopher Tate21e9f192017-08-08 13:49:11 -07003955
Christopher Tate14a7bb02015-10-01 10:24:31 -07003956 private InFlight removeLocked(PendingIntent pi, Intent intent) {
3957 for (int i = 0; i < mInFlight.size(); i++) {
Christopher Tatedb9ae422017-08-21 11:24:30 -07003958 if (mInFlight.get(i).mPendingIntent == pi) {
Christopher Tate14a7bb02015-10-01 10:24:31 -07003959 return mInFlight.remove(i);
3960 }
3961 }
3962 mLog.w("No in-flight alarm for " + pi + " " + intent);
3963 return null;
3964 }
3965
3966 private InFlight removeLocked(IBinder listener) {
3967 for (int i = 0; i < mInFlight.size(); i++) {
3968 if (mInFlight.get(i).mListener == listener) {
3969 return mInFlight.remove(i);
3970 }
3971 }
3972 mLog.w("No in-flight alarm for listener " + listener);
3973 return null;
3974 }
3975
3976 private void updateStatsLocked(InFlight inflight) {
3977 final long nowELAPSED = SystemClock.elapsedRealtime();
3978 BroadcastStats bs = inflight.mBroadcastStats;
3979 bs.nesting--;
3980 if (bs.nesting <= 0) {
3981 bs.nesting = 0;
3982 bs.aggregateTime += nowELAPSED - bs.startTime;
3983 }
3984 FilterStats fs = inflight.mFilterStats;
3985 fs.nesting--;
3986 if (fs.nesting <= 0) {
3987 fs.nesting = 0;
3988 fs.aggregateTime += nowELAPSED - fs.startTime;
3989 }
3990 if (RECORD_ALARMS_IN_HISTORY) {
Narayan Kamath695cf722017-12-21 18:32:47 +00003991 ActivityManager.noteAlarmFinish(inflight.mPendingIntent, inflight.mWorkSource,
3992 inflight.mUid, inflight.mTag);
Christopher Tate14a7bb02015-10-01 10:24:31 -07003993 }
3994 }
3995
3996 private void updateTrackingLocked(InFlight inflight) {
3997 if (inflight != null) {
3998 updateStatsLocked(inflight);
3999 }
4000 mBroadcastRefCount--;
Makoto Onuki3e7d8452017-03-02 15:33:17 -08004001 if (DEBUG_WAKELOCK) {
4002 Slog.d(TAG, "mBroadcastRefCount -> " + mBroadcastRefCount);
4003 }
Christopher Tate14a7bb02015-10-01 10:24:31 -07004004 if (mBroadcastRefCount == 0) {
Dianne Hackborn627dfa12015-11-11 18:10:30 -08004005 mHandler.obtainMessage(AlarmHandler.REPORT_ALARMS_ACTIVE, 0).sendToTarget();
Christopher Tate14a7bb02015-10-01 10:24:31 -07004006 mWakeLock.release();
4007 if (mInFlight.size() > 0) {
4008 mLog.w("Finished all dispatches with " + mInFlight.size()
4009 + " remaining inflights");
4010 for (int i=0; i<mInFlight.size(); i++) {
4011 mLog.w(" Remaining #" + i + ": " + mInFlight.get(i));
4012 }
4013 mInFlight.clear();
4014 }
4015 } else {
4016 // the next of our alarms is now in flight. reattribute the wakelock.
4017 if (mInFlight.size() > 0) {
4018 InFlight inFlight = mInFlight.get(0);
4019 setWakelockWorkSource(inFlight.mPendingIntent, inFlight.mWorkSource,
4020 inFlight.mAlarmType, inFlight.mTag, -1, false);
4021 } else {
4022 // should never happen
4023 mLog.w("Alarm wakelock still held but sent queue empty");
4024 mWakeLock.setWorkSource(null);
4025 }
4026 }
4027 }
4028
4029 /**
4030 * Callback that arrives when a direct-call alarm reports that delivery has finished
4031 */
4032 @Override
4033 public void alarmComplete(IBinder who) {
4034 if (who == null) {
Christopher Tate21e9f192017-08-08 13:49:11 -07004035 mLog.w("Invalid alarmComplete: uid=" + Binder.getCallingUid()
Christopher Tate14a7bb02015-10-01 10:24:31 -07004036 + " pid=" + Binder.getCallingPid());
4037 return;
4038 }
4039
4040 final long ident = Binder.clearCallingIdentity();
4041 try {
4042 synchronized (mLock) {
4043 mHandler.removeMessages(AlarmHandler.LISTENER_TIMEOUT, who);
4044 InFlight inflight = removeLocked(who);
4045 if (inflight != null) {
4046 if (DEBUG_LISTENER_CALLBACK) {
4047 Slog.i(TAG, "alarmComplete() from " + who);
4048 }
4049 updateTrackingLocked(inflight);
Christopher Tateeabba732017-08-17 17:12:52 -07004050 mListenerFinishCount++;
Christopher Tate14a7bb02015-10-01 10:24:31 -07004051 } else {
4052 // Delivery timed out, and the timeout handling already took care of
4053 // updating our tracking here, so we needn't do anything further.
4054 if (DEBUG_LISTENER_CALLBACK) {
4055 Slog.i(TAG, "Late alarmComplete() from " + who);
4056 }
4057 }
4058 }
4059 } finally {
4060 Binder.restoreCallingIdentity(ident);
4061 }
4062 }
4063
4064 /**
4065 * Callback that arrives when a PendingIntent alarm has finished delivery
4066 */
4067 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004068 public void onSendFinished(PendingIntent pi, Intent intent, int resultCode,
4069 String resultData, Bundle resultExtras) {
4070 synchronized (mLock) {
Christopher Tateeabba732017-08-17 17:12:52 -07004071 mSendFinishCount++;
Christopher Tate14a7bb02015-10-01 10:24:31 -07004072 updateTrackingLocked(removeLocked(pi, intent));
4073 }
4074 }
4075
4076 /**
4077 * Timeout of a direct-call alarm delivery
4078 */
4079 public void alarmTimedOut(IBinder who) {
4080 synchronized (mLock) {
4081 InFlight inflight = removeLocked(who);
Dianne Hackborn81038902012-11-26 17:04:09 -08004082 if (inflight != null) {
Christopher Tate14a7bb02015-10-01 10:24:31 -07004083 // TODO: implement ANR policy for the target
4084 if (DEBUG_LISTENER_CALLBACK) {
4085 Slog.i(TAG, "Alarm listener " + who + " timed out in delivery");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004086 }
Christopher Tate14a7bb02015-10-01 10:24:31 -07004087 updateTrackingLocked(inflight);
Christopher Tateeabba732017-08-17 17:12:52 -07004088 mListenerFinishCount++;
Dianne Hackborn81038902012-11-26 17:04:09 -08004089 } else {
Christopher Tate14a7bb02015-10-01 10:24:31 -07004090 if (DEBUG_LISTENER_CALLBACK) {
4091 Slog.i(TAG, "Spurious timeout of listener " + who);
4092 }
Christopher Tate21e9f192017-08-08 13:49:11 -07004093 mLog.w("Spurious timeout of listener " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004094 }
Christopher Tate14a7bb02015-10-01 10:24:31 -07004095 }
4096 }
4097
4098 /**
4099 * Deliver an alarm and set up the post-delivery handling appropriately
4100 */
Andreas Gampea36dc622018-02-05 17:19:22 -08004101 @GuardedBy("mLock")
Christopher Tate14a7bb02015-10-01 10:24:31 -07004102 public void deliverLocked(Alarm alarm, long nowELAPSED, boolean allowWhileIdle) {
4103 if (alarm.operation != null) {
4104 // PendingIntent alarm
Christopher Tate21e9f192017-08-08 13:49:11 -07004105 mSendCount++;
Christopher Tate12cf0b62018-01-05 18:40:14 -08004106
4107 if (alarm.priorityClass.priority == PRIO_TICK) {
4108 mLastTickIssued = nowELAPSED;
4109 }
4110
Christopher Tate14a7bb02015-10-01 10:24:31 -07004111 try {
4112 alarm.operation.send(getContext(), 0,
4113 mBackgroundIntent.putExtra(
4114 Intent.EXTRA_ALARM_COUNT, alarm.count),
4115 mDeliveryTracker, mHandler, null,
4116 allowWhileIdle ? mIdleOptions : null);
4117 } catch (PendingIntent.CanceledException e) {
Makoto Onuki5d93b832018-01-10 16:12:39 -08004118 if (alarm.operation == mTimeTickSender) {
4119 Slog.wtf(TAG, "mTimeTickSender canceled");
4120 }
Christopher Tate14a7bb02015-10-01 10:24:31 -07004121 if (alarm.repeatInterval > 0) {
4122 // This IntentSender is no longer valid, but this
4123 // is a repeating alarm, so toss it
4124 removeImpl(alarm.operation);
4125 }
Christopher Tate7f2a0352015-12-08 10:24:33 -08004126 // No actual delivery was possible, so the delivery tracker's
4127 // 'finished' callback won't be invoked. We also don't need
4128 // to do any wakelock or stats tracking, so we have nothing
4129 // left to do here but go on to the next thing.
Christopher Tateeabba732017-08-17 17:12:52 -07004130 mSendFinishCount++;
Christopher Tate7f2a0352015-12-08 10:24:33 -08004131 return;
Christopher Tate14a7bb02015-10-01 10:24:31 -07004132 }
4133 } else {
4134 // Direct listener callback alarm
Christopher Tate21e9f192017-08-08 13:49:11 -07004135 mListenerCount++;
Christopher Tate14a7bb02015-10-01 10:24:31 -07004136 try {
4137 if (DEBUG_LISTENER_CALLBACK) {
4138 Slog.v(TAG, "Alarm to uid=" + alarm.uid
4139 + " listener=" + alarm.listener.asBinder());
4140 }
4141 alarm.listener.doAlarm(this);
4142 mHandler.sendMessageDelayed(
4143 mHandler.obtainMessage(AlarmHandler.LISTENER_TIMEOUT,
4144 alarm.listener.asBinder()),
4145 mConstants.LISTENER_TIMEOUT);
4146 } catch (Exception e) {
4147 if (DEBUG_LISTENER_CALLBACK) {
4148 Slog.i(TAG, "Alarm undeliverable to listener "
4149 + alarm.listener.asBinder(), e);
4150 }
Christopher Tate7f2a0352015-12-08 10:24:33 -08004151 // As in the PendingIntent.CanceledException case, delivery of the
4152 // alarm was not possible, so we have no wakelock or timeout or
4153 // stats management to do. It threw before we posted the delayed
4154 // timeout message, so we're done here.
Christopher Tateeabba732017-08-17 17:12:52 -07004155 mListenerFinishCount++;
Christopher Tate7f2a0352015-12-08 10:24:33 -08004156 return;
Christopher Tate14a7bb02015-10-01 10:24:31 -07004157 }
4158 }
4159
4160 // The alarm is now in flight; now arrange wakelock and stats tracking
Makoto Onuki3e7d8452017-03-02 15:33:17 -08004161 if (DEBUG_WAKELOCK) {
4162 Slog.d(TAG, "mBroadcastRefCount -> " + (mBroadcastRefCount + 1));
4163 }
Christopher Tate14a7bb02015-10-01 10:24:31 -07004164 if (mBroadcastRefCount == 0) {
4165 setWakelockWorkSource(alarm.operation, alarm.workSource,
4166 alarm.type, alarm.statsTag, (alarm.operation == null) ? alarm.uid : -1,
4167 true);
4168 mWakeLock.acquire();
Dianne Hackborn627dfa12015-11-11 18:10:30 -08004169 mHandler.obtainMessage(AlarmHandler.REPORT_ALARMS_ACTIVE, 1).sendToTarget();
Christopher Tate14a7bb02015-10-01 10:24:31 -07004170 }
4171 final InFlight inflight = new InFlight(AlarmManagerService.this,
4172 alarm.operation, alarm.listener, alarm.workSource, alarm.uid,
4173 alarm.packageName, alarm.type, alarm.statsTag, nowELAPSED);
4174 mInFlight.add(inflight);
4175 mBroadcastRefCount++;
Christopher Tate14a7bb02015-10-01 10:24:31 -07004176 if (allowWhileIdle) {
4177 // Record the last time this uid handled an ALLOW_WHILE_IDLE alarm.
Suprabh Shuklac25447d2018-01-19 16:43:35 -08004178 mLastAllowWhileIdleDispatch.put(alarm.creatorUid, nowELAPSED);
Makoto Onukie4918212018-02-06 11:30:15 -08004179 if ((mAppStateTracker == null)
4180 || mAppStateTracker.isUidInForeground(alarm.creatorUid)) {
Suprabh Shuklac25447d2018-01-19 16:43:35 -08004181 mUseAllowWhileIdleShortTime.put(alarm.creatorUid, true);
4182 } else {
4183 mUseAllowWhileIdleShortTime.put(alarm.creatorUid, false);
4184 }
Christopher Tate14a7bb02015-10-01 10:24:31 -07004185 if (RECORD_DEVICE_IDLE_ALARMS) {
4186 IdleDispatchEntry ent = new IdleDispatchEntry();
4187 ent.uid = alarm.uid;
4188 ent.pkg = alarm.packageName;
4189 ent.tag = alarm.statsTag;
4190 ent.op = "DELIVER";
4191 ent.elapsedRealtime = nowELAPSED;
4192 mAllowWhileIdleDispatches.add(ent);
4193 }
4194 }
Suprabh Shuklad65e58a2018-02-05 20:36:08 -08004195 if (!isExemptFromAppStandby(alarm)) {
Suprabh Shukla75edab12018-01-29 14:09:06 -08004196 final Pair<String, Integer> packageUser = Pair.create(alarm.sourcePackage,
4197 UserHandle.getUserId(alarm.creatorUid));
4198 mLastAlarmDeliveredForPackage.put(packageUser, nowELAPSED);
4199 }
Christopher Tate14a7bb02015-10-01 10:24:31 -07004200
4201 final BroadcastStats bs = inflight.mBroadcastStats;
4202 bs.count++;
4203 if (bs.nesting == 0) {
4204 bs.nesting = 1;
4205 bs.startTime = nowELAPSED;
4206 } else {
4207 bs.nesting++;
4208 }
4209 final FilterStats fs = inflight.mFilterStats;
4210 fs.count++;
4211 if (fs.nesting == 0) {
4212 fs.nesting = 1;
4213 fs.startTime = nowELAPSED;
4214 } else {
4215 fs.nesting++;
4216 }
4217 if (alarm.type == ELAPSED_REALTIME_WAKEUP
4218 || alarm.type == RTC_WAKEUP) {
4219 bs.numWakeup++;
4220 fs.numWakeup++;
Narayan Kamath695cf722017-12-21 18:32:47 +00004221 ActivityManager.noteWakeupAlarm(
4222 alarm.operation, alarm.workSource, alarm.uid, alarm.packageName,
4223 alarm.statsTag);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004224 }
4225 }
4226 }
4227}