19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.server; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackbornimport android.app.Activity; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.ActivityManagerNative; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.AlarmManager; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.IAlarmManager; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.PendingIntent; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.BroadcastReceiver; 258103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackbornimport android.content.ComponentName; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.IntentFilter; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.Uri; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.PowerManager; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemClock; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemProperties; 3880a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackbornimport android.os.UserHandle; 39c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tateimport android.os.WorkSource; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextUtils; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.format.Time; 428103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackbornimport android.util.Pair; 438a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog; 44043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackbornimport android.util.TimeUtils; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.PrintWriter; 48043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackbornimport java.text.SimpleDateFormat; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 508103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackbornimport java.util.Arrays; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Calendar; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Collections; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Comparator; 541f7b4134db07acbb429cd770441ff460fa6f4b1bMike Lockwoodimport java.util.Date; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.HashMap; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Iterator; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Map; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.TimeZone; 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 608103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackbornimport com.android.internal.util.LocalLog; 618103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass AlarmManagerService extends IAlarmManager.Stub { 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The threshold for how long an alarm can be late before we print a 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // warning message. The time duration is in milliseconds. 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final long LATE_ALARM_THRESHOLD = 10 * 1000; 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int RTC_WAKEUP_MASK = 1 << AlarmManager.RTC_WAKEUP; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int RTC_MASK = 1 << AlarmManager.RTC; 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int ELAPSED_REALTIME_WAKEUP_MASK = 1 << AlarmManager.ELAPSED_REALTIME_WAKEUP; 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int ELAPSED_REALTIME_MASK = 1 << AlarmManager.ELAPSED_REALTIME; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int TIME_CHANGED_MASK = 1 << 16; 72b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate 73b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate // Alignment quantum for inexact repeating alarms 74b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate private static final long QUANTUM = AlarmManager.INTERVAL_FIFTEEN_MINUTES; 75b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "AlarmManager"; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String ClockReceiver_TAG = "ClockReceiver"; 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final boolean localLOGV = false; 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int ALARM_EVENT = 1; 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TIMEZONE_PROPERTY = "persist.sys.timezone"; 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final Intent mBackgroundIntent 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = new Intent().addFlags(Intent.FLAG_FROM_BACKGROUND); 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Context mContext; 868103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn 878103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn private final LocalLog mLog = new LocalLog(TAG); 888103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Object mLock = new Object(); 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final ArrayList<Alarm> mRtcWakeupAlarms = new ArrayList<Alarm>(); 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final ArrayList<Alarm> mRtcAlarms = new ArrayList<Alarm>(); 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final ArrayList<Alarm> mElapsedRealtimeWakeupAlarms = new ArrayList<Alarm>(); 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final ArrayList<Alarm> mElapsedRealtimeAlarms = new ArrayList<Alarm>(); 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final IncreasingTimeOrder mIncreasingTimeOrder = new IncreasingTimeOrder(); 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mDescriptor; 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mBroadcastRefCount = 0; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private PowerManager.WakeLock mWakeLock; 1008103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn private ArrayList<InFlight> mInFlight = new ArrayList<InFlight>(); 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final AlarmThread mWaitThread = new AlarmThread(); 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final AlarmHandler mHandler = new AlarmHandler(); 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ClockReceiver mClockReceiver; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private UninstallReceiver mUninstallReceiver; 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final ResultReceiver mResultReceiver = new ResultReceiver(); 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final PendingIntent mTimeTickSender; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final PendingIntent mDateChangeSender; 1088103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn 1098103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn private static final class InFlight extends Intent { 1108103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn final PendingIntent mPendingIntent; 1118103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn final Pair<String, ComponentName> mTarget; 1128103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn final BroadcastStats mBroadcastStats; 1138103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn final FilterStats mFilterStats; 1148103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn 1158103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn InFlight(AlarmManagerService service, PendingIntent pendingIntent) { 1168103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn mPendingIntent = pendingIntent; 1178103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn Intent intent = pendingIntent.getIntent(); 1188103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn mTarget = intent != null 1198103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn ? new Pair<String, ComponentName>(intent.getAction(), intent.getComponent()) 1208103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn : null; 1218103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn mBroadcastStats = service.getStatsLocked(pendingIntent); 1228103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn FilterStats fs = mBroadcastStats.filterStats.get(mTarget); 1238103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn if (fs == null) { 1248103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn fs = new FilterStats(mBroadcastStats, mTarget); 1258103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn mBroadcastStats.filterStats.put(mTarget, fs); 1268103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } 1278103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn mFilterStats = fs; 1288103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } 1298103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } 1308103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final class FilterStats { 1328103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn final BroadcastStats mBroadcastStats; 1338103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn final Pair<String, ComponentName> mTarget; 1348103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn 1358103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn long aggregateTime; 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int count; 1378103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn int numWakeup; 1388103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn long startTime; 1398103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn int nesting; 1408103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn 1418103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn FilterStats(BroadcastStats broadcastStats, Pair<String, ComponentName> target) { 1428103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn mBroadcastStats = broadcastStats; 1438103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn mTarget = target; 1448103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final class BroadcastStats { 1488103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn final String mPackageName; 1498103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long aggregateTime; 1518103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn int count; 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int numWakeup; 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long startTime; 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int nesting; 1558103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn final HashMap<Pair<String, ComponentName>, FilterStats> filterStats 1568103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn = new HashMap<Pair<String, ComponentName>, FilterStats>(); 1578103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn 1588103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn BroadcastStats(String packageName) { 1598103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn mPackageName = packageName; 1608103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final HashMap<String, BroadcastStats> mBroadcastStats 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = new HashMap<String, BroadcastStats>(); 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AlarmManagerService(Context context) { 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDescriptor = init(); 16964ba8e4038ade025da5e02f882219432d6bf1016Robert CH Chou 17064ba8e4038ade025da5e02f882219432d6bf1016Robert CH Chou // We have to set current TimeZone info to kernel 17164ba8e4038ade025da5e02f882219432d6bf1016Robert CH Chou // because kernel doesn't keep this after reboot 17264ba8e4038ade025da5e02f882219432d6bf1016Robert CH Chou String tz = SystemProperties.get(TIMEZONE_PROPERTY); 17364ba8e4038ade025da5e02f882219432d6bf1016Robert CH Chou if (tz != null) { 17464ba8e4038ade025da5e02f882219432d6bf1016Robert CH Chou setTimeZone(tz); 17564ba8e4038ade025da5e02f882219432d6bf1016Robert CH Chou } 17664ba8e4038ade025da5e02f882219432d6bf1016Robert CH Chou 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 180db5aca9aa6a3cb70c865e7f825a2826ccef5bb32Dianne Hackborn mTimeTickSender = PendingIntent.getBroadcastAsUser(context, 0, 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new Intent(Intent.ACTION_TIME_TICK).addFlags( 182db5aca9aa6a3cb70c865e7f825a2826ccef5bb32Dianne Hackborn Intent.FLAG_RECEIVER_REGISTERED_ONLY), 0, 183db5aca9aa6a3cb70c865e7f825a2826ccef5bb32Dianne Hackborn UserHandle.ALL); 1841c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn Intent intent = new Intent(Intent.ACTION_DATE_CHANGED); 1851c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 186db5aca9aa6a3cb70c865e7f825a2826ccef5bb32Dianne Hackborn mDateChangeSender = PendingIntent.getBroadcastAsUser(context, 0, intent, 187db5aca9aa6a3cb70c865e7f825a2826ccef5bb32Dianne Hackborn Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT, UserHandle.ALL); 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // now that we have initied the driver schedule the alarm 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mClockReceiver= new ClockReceiver(); 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mClockReceiver.scheduleTimeTickEvent(); 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mClockReceiver.scheduleDateChangedEvent(); 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUninstallReceiver = new UninstallReceiver(); 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDescriptor != -1) { 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWaitThread.start(); 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1988a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Failed to open alarm driver. Falling back to a handler."); 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() throws Throwable { 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(mDescriptor); 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.finalize(); 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void set(int type, long triggerAtTime, PendingIntent operation) { 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setRepeating(type, triggerAtTime, 0, operation); 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setRepeating(int type, long triggerAtTime, long interval, 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PendingIntent operation) { 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (operation == null) { 2178a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "set/setRepeating ignored because there is no intent"); 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm alarm = new Alarm(); 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.type = type; 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.when = triggerAtTime; 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.repeatInterval = interval; 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.operation = operation; 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remove this alarm if already scheduled. 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(operation); 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2308a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, "set: " + alarm); 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index = addAlarmLocked(alarm); 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (index == 0) { 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setLocked(alarm); 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setInexactRepeating(int type, long triggerAtTime, long interval, 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PendingIntent operation) { 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (operation == null) { 2428a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "setInexactRepeating ignored because there is no intent"); 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 246b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate if (interval <= 0) { 247b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate Slog.w(TAG, "setInexactRepeating ignored because interval " + interval 248b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate + " is invalid"); 249b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate return; 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 251b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate 252b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate // If the requested interval isn't a multiple of 15 minutes, just treat it as exact 253b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate if (interval % QUANTUM != 0) { 254b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate if (localLOGV) Slog.v(TAG, "Interval " + interval + " not a quantum multiple"); 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setRepeating(type, triggerAtTime, interval, operation); 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 259b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate // Translate times into the ELAPSED timebase for alignment purposes so that 260b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate // alignment never tries to match against wall clock times. 261b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate final boolean isRtc = (type == AlarmManager.RTC || type == AlarmManager.RTC_WAKEUP); 262b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate final long skew = (isRtc) 263b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate ? System.currentTimeMillis() - SystemClock.elapsedRealtime() 264b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate : 0; 265b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate 266b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate // Slip forward to the next ELAPSED-timebase quantum after the stated time. If 267b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate // we're *at* a quantum point, leave it alone. 268b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate final long adjustedTriggerTime; 269b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate long offset = (triggerAtTime - skew) % QUANTUM; 270b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate if (offset != 0) { 271b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate adjustedTriggerTime = triggerAtTime - offset + QUANTUM; 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 273b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate adjustedTriggerTime = triggerAtTime; 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 276b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate // Set the alarm based on the quantum-aligned start time 277b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate if (localLOGV) Slog.v(TAG, "setInexactRepeating: type=" + type + " interval=" + interval 278b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate + " trigger=" + adjustedTriggerTime + " orig=" + triggerAtTime); 279b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate setRepeating(type, adjustedTriggerTime, interval, operation); 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28297e44947282b3918ee0bed2d16b33b983f882580Dan Egnor public void setTime(long millis) { 28397e44947282b3918ee0bed2d16b33b983f882580Dan Egnor mContext.enforceCallingOrSelfPermission( 28497e44947282b3918ee0bed2d16b33b983f882580Dan Egnor "android.permission.SET_TIME", 28597e44947282b3918ee0bed2d16b33b983f882580Dan Egnor "setTime"); 28697e44947282b3918ee0bed2d16b33b983f882580Dan Egnor 28797e44947282b3918ee0bed2d16b33b983f882580Dan Egnor SystemClock.setCurrentTimeMillis(millis); 28897e44947282b3918ee0bed2d16b33b983f882580Dan Egnor } 28997e44947282b3918ee0bed2d16b33b983f882580Dan Egnor 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTimeZone(String tz) { 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.enforceCallingOrSelfPermission( 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.permission.SET_TIME_ZONE", 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "setTimeZone"); 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 295897798225d9c48bd3424757059318ed1eb3207deChristopher Tate long oldId = Binder.clearCallingIdentity(); 296897798225d9c48bd3424757059318ed1eb3207deChristopher Tate try { 297897798225d9c48bd3424757059318ed1eb3207deChristopher Tate if (TextUtils.isEmpty(tz)) return; 298897798225d9c48bd3424757059318ed1eb3207deChristopher Tate TimeZone zone = TimeZone.getTimeZone(tz); 299897798225d9c48bd3424757059318ed1eb3207deChristopher Tate // Prevent reentrant calls from stepping on each other when writing 300897798225d9c48bd3424757059318ed1eb3207deChristopher Tate // the time zone property 301897798225d9c48bd3424757059318ed1eb3207deChristopher Tate boolean timeZoneWasChanged = false; 302897798225d9c48bd3424757059318ed1eb3207deChristopher Tate synchronized (this) { 303897798225d9c48bd3424757059318ed1eb3207deChristopher Tate String current = SystemProperties.get(TIMEZONE_PROPERTY); 304897798225d9c48bd3424757059318ed1eb3207deChristopher Tate if (current == null || !current.equals(zone.getID())) { 305897798225d9c48bd3424757059318ed1eb3207deChristopher Tate if (localLOGV) { 306897798225d9c48bd3424757059318ed1eb3207deChristopher Tate Slog.v(TAG, "timezone changed: " + current + ", new=" + zone.getID()); 307897798225d9c48bd3424757059318ed1eb3207deChristopher Tate } 308897798225d9c48bd3424757059318ed1eb3207deChristopher Tate timeZoneWasChanged = true; 309897798225d9c48bd3424757059318ed1eb3207deChristopher Tate SystemProperties.set(TIMEZONE_PROPERTY, zone.getID()); 310897798225d9c48bd3424757059318ed1eb3207deChristopher Tate } 311897798225d9c48bd3424757059318ed1eb3207deChristopher Tate 312897798225d9c48bd3424757059318ed1eb3207deChristopher Tate // Update the kernel timezone information 313897798225d9c48bd3424757059318ed1eb3207deChristopher Tate // Kernel tracks time offsets as 'minutes west of GMT' 314897798225d9c48bd3424757059318ed1eb3207deChristopher Tate int gmtOffset = zone.getOffset(System.currentTimeMillis()); 315897798225d9c48bd3424757059318ed1eb3207deChristopher Tate setKernelTimezone(mDescriptor, -(gmtOffset / 60000)); 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 318897798225d9c48bd3424757059318ed1eb3207deChristopher Tate TimeZone.setDefault(null); 319897798225d9c48bd3424757059318ed1eb3207deChristopher Tate 320897798225d9c48bd3424757059318ed1eb3207deChristopher Tate if (timeZoneWasChanged) { 321897798225d9c48bd3424757059318ed1eb3207deChristopher Tate Intent intent = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 322897798225d9c48bd3424757059318ed1eb3207deChristopher Tate intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 323897798225d9c48bd3424757059318ed1eb3207deChristopher Tate intent.putExtra("time-zone", zone.getID()); 324897798225d9c48bd3424757059318ed1eb3207deChristopher Tate mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 325897798225d9c48bd3424757059318ed1eb3207deChristopher Tate } 326897798225d9c48bd3424757059318ed1eb3207deChristopher Tate } finally { 327897798225d9c48bd3424757059318ed1eb3207deChristopher Tate Binder.restoreCallingIdentity(oldId); 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void remove(PendingIntent operation) { 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (operation == null) { 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(operation); 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeLocked(PendingIntent operation) { 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mRtcWakeupAlarms, operation); 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mRtcAlarms, operation); 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mElapsedRealtimeWakeupAlarms, operation); 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mElapsedRealtimeAlarms, operation); 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void removeLocked(ArrayList<Alarm> alarmList, 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PendingIntent operation) { 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarmList.size() <= 0) { 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // iterator over the list removing any it where the intent match 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Iterator<Alarm> it = alarmList.iterator(); 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (it.hasNext()) { 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm alarm = it.next(); 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.operation.equals(operation)) { 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project it.remove(); 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 36380a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeLocked(String packageName) { 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mRtcWakeupAlarms, packageName); 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mRtcAlarms, packageName); 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mElapsedRealtimeWakeupAlarms, packageName); 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mElapsedRealtimeAlarms, packageName); 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void removeLocked(ArrayList<Alarm> alarmList, 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String packageName) { 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarmList.size() <= 0) { 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // iterator over the list removing any it where the intent match 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Iterator<Alarm> it = alarmList.iterator(); 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (it.hasNext()) { 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm alarm = it.next(); 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.operation.getTargetPackage().equals(packageName)) { 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project it.remove(); 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 38780a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn 38880a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn public void removeUserLocked(int userHandle) { 38980a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn removeUserLocked(mRtcWakeupAlarms, userHandle); 39080a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn removeUserLocked(mRtcAlarms, userHandle); 39180a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn removeUserLocked(mElapsedRealtimeWakeupAlarms, userHandle); 39280a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn removeUserLocked(mElapsedRealtimeAlarms, userHandle); 39380a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn } 39480a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn 39580a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn private void removeUserLocked(ArrayList<Alarm> alarmList, int userHandle) { 39680a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn if (alarmList.size() <= 0) { 39780a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn return; 39880a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn } 39980a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn 40080a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn // iterator over the list removing any it where the intent match 40180a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn Iterator<Alarm> it = alarmList.iterator(); 40280a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn 40380a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn while (it.hasNext()) { 40480a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn Alarm alarm = it.next(); 4058832c18d8b63367929c2d394c9c508f56003d400Dianne Hackborn if (UserHandle.getUserId(alarm.operation.getCreatorUid()) == userHandle) { 40680a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn it.remove(); 40780a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn } 40880a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn } 40980a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn } 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 41121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn public boolean lookForPackageLocked(String packageName) { 41221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return lookForPackageLocked(mRtcWakeupAlarms, packageName) 41321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn || lookForPackageLocked(mRtcAlarms, packageName) 41421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn || lookForPackageLocked(mElapsedRealtimeWakeupAlarms, packageName) 41521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn || lookForPackageLocked(mElapsedRealtimeAlarms, packageName); 41621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 41721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 41821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn private boolean lookForPackageLocked(ArrayList<Alarm> alarmList, String packageName) { 41921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn for (int i=alarmList.size()-1; i>=0; i--) { 42021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (alarmList.get(i).operation.getTargetPackage().equals(packageName)) { 42121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return true; 42221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 42321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 42421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return false; 42521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 42621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ArrayList<Alarm> getAlarmList(int type) { 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (type) { 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case AlarmManager.RTC_WAKEUP: return mRtcWakeupAlarms; 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case AlarmManager.RTC: return mRtcAlarms; 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case AlarmManager.ELAPSED_REALTIME_WAKEUP: return mElapsedRealtimeWakeupAlarms; 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case AlarmManager.ELAPSED_REALTIME: return mElapsedRealtimeAlarms; 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int addAlarmLocked(Alarm alarm) { 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Alarm> alarmList = getAlarmList(alarm.type); 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index = Collections.binarySearch(alarmList, alarm, mIncreasingTimeOrder); 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (index < 0) { 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index = 0 - index - 1; 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4458a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, "Adding alarm " + alarm + " at " + index); 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarmList.add(index, alarm); 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (localLOGV) { 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Display the list of alarms for this alarm type 4508a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "alarms: " + alarmList.size() + " type: " + alarm.type); 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int position = 0; 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Alarm a : alarmList) { 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Time time = new Time(); 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project time.set(a.when); 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String timeStr = time.format("%b %d %I:%M:%S %p"); 4568a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, position + ": " + timeStr 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " " + a.operation.getTargetPackage()); 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project position += 1; 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return index; 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long timeToNextAlarm() { 46611c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown long nextAlarm = Long.MAX_VALUE; 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=AlarmManager.RTC_WAKEUP; 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i<=AlarmManager.ELAPSED_REALTIME; i++) { 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Alarm> alarmList = getAlarmList(i); 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarmList.size() > 0) { 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm a = alarmList.get(0); 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (a.when < nextAlarm) { 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nextAlarm = a.when; 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return nextAlarm; 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void setLocked(Alarm alarm) 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDescriptor != -1) 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 48611c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown // The kernel never triggers alarms with negative wakeup times 48711c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown // so we ensure they are positive. 48811c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown long alarmSeconds, alarmNanoseconds; 48911c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown if (alarm.when < 0) { 49011c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown alarmSeconds = 0; 49111c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown alarmNanoseconds = 0; 49211c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown } else { 49311c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown alarmSeconds = alarm.when / 1000; 49411c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown alarmNanoseconds = (alarm.when % 1000) * 1000 * 1000; 49511c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown } 49611c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown 49711c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown set(mDescriptor, alarm.type, alarmSeconds, alarmNanoseconds); 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message msg = Message.obtain(); 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.what = ALARM_EVENT; 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.removeMessages(ALARM_EVENT); 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.sendMessageAtTime(msg, alarm.when); 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED) { 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println("Permission Denial: can't dump AlarmManager from from pid=" 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Binder.getCallingPid() 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ", uid=" + Binder.getCallingUid()); 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println("Current Alarm Manager state:"); 5211d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn if (mRtcWakeupAlarms.size() > 0 || mRtcAlarms.size() > 0) { 522043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn final long now = System.currentTimeMillis(); 523043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" "); 5251d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" Realtime wakeup (now="); 526043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn pw.print(sdf.format(new Date(now))); pw.println("):"); 5271d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn if (mRtcWakeupAlarms.size() > 0) { 528043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn dumpAlarmList(pw, mRtcWakeupAlarms, " ", "RTC_WAKEUP", now); 5291d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn } 5301d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn if (mRtcAlarms.size() > 0) { 531043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn dumpAlarmList(pw, mRtcAlarms, " ", "RTC", now); 5321d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn } 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5341d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn if (mElapsedRealtimeWakeupAlarms.size() > 0 || mElapsedRealtimeAlarms.size() > 0) { 535043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn final long now = SystemClock.elapsedRealtime(); 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" "); 5371d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" Elapsed realtime wakeup (now="); 538043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn TimeUtils.formatDuration(now, pw); pw.println("):"); 5391d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn if (mElapsedRealtimeWakeupAlarms.size() > 0) { 540043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn dumpAlarmList(pw, mElapsedRealtimeWakeupAlarms, " ", "ELAPSED_WAKEUP", now); 5411d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn } 5421d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn if (mElapsedRealtimeAlarms.size() > 0) { 543043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn dumpAlarmList(pw, mElapsedRealtimeAlarms, " ", "ELAPSED", now); 5441d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn } 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5468103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn 5478103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn pw.println(); 5481d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" Broadcast ref count: "); pw.println(mBroadcastRefCount); 5498103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn pw.println(); 5508103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn 5518103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn if (mLog.dump(pw, " Recent problems", " ")) { 5528103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn pw.println(); 5538103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } 5548103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn 5558103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn final FilterStats[] topFilters = new FilterStats[10]; 5568103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn final Comparator<FilterStats> comparator = new Comparator<FilterStats>() { 5578103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn @Override 5588103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn public int compare(FilterStats lhs, FilterStats rhs) { 5598103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn if (lhs.aggregateTime < rhs.aggregateTime) { 5608103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn return 1; 5618103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } else if (lhs.aggregateTime > rhs.aggregateTime) { 5628103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn return -1; 5638103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } 5648103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn return 0; 5658103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } 5668103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn }; 5678103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn int len = 0; 5688103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn for (Map.Entry<String, BroadcastStats> be : mBroadcastStats.entrySet()) { 5698103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn BroadcastStats bs = be.getValue(); 5708103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn for (Map.Entry<Pair<String, ComponentName>, FilterStats> fe 5718103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn : bs.filterStats.entrySet()) { 5728103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn FilterStats fs = fe.getValue(); 5738103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn int pos = len > 0 5748103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn ? Arrays.binarySearch(topFilters, 0, len, fs, comparator) : 0; 5758103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn if (pos < 0) { 5768103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn pos = -pos - 1; 5778103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } 5788103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn if (pos < topFilters.length) { 5798103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn int copylen = topFilters.length - pos - 1; 5808103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn if (copylen > 0) { 5818103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn System.arraycopy(topFilters, pos, topFilters, pos+1, copylen); 5828103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } 5838103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn topFilters[pos] = fs; 5848103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn if (len < topFilters.length) { 5858103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn len++; 5868103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } 5878103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } 5888103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } 5898103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } 5908103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn if (len > 0) { 5918103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn pw.println(" Top Alarms:"); 5928103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn for (int i=0; i<len; i++) { 5938103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn FilterStats fs = topFilters[i]; 5948103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn pw.print(" "); 5958103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn if (fs.nesting > 0) pw.print("*ACTIVE* "); 5968103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn TimeUtils.formatDuration(fs.aggregateTime, pw); 5978103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn pw.print(" running, "); pw.print(fs.numWakeup); 5988103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn pw.print(" wakeups, "); pw.print(fs.count); 5998103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn pw.print(" alarms: "); pw.print(fs.mBroadcastStats.mPackageName); 6008103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn pw.println(); 6018103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn pw.print(" "); 6028103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn if (fs.mTarget.first != null) { 6038103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn pw.print(" act="); pw.print(fs.mTarget.first); 6048103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } 6058103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn if (fs.mTarget.second != null) { 6068103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn pw.print(" cmp="); pw.print(fs.mTarget.second.toShortString()); 6078103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } 6088103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn pw.println(); 6098103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } 6108103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } 6118103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" "); 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Alarm Stats:"); 6148103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn final ArrayList<FilterStats> tmpFilters = new ArrayList<FilterStats>(); 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Map.Entry<String, BroadcastStats> be : mBroadcastStats.entrySet()) { 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BroadcastStats bs = be.getValue(); 6178103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn pw.print(" "); 6188103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn if (bs.nesting > 0) pw.print("*ACTIVE* "); 6198103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn pw.print(be.getKey()); 6208103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn pw.print(" "); TimeUtils.formatDuration(bs.aggregateTime, pw); 6218103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn pw.print(" running, "); pw.print(bs.numWakeup); 6228103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn pw.println(" wakeups:"); 6238103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn tmpFilters.clear(); 6248103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn for (Map.Entry<Pair<String, ComponentName>, FilterStats> fe 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : bs.filterStats.entrySet()) { 6268103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn tmpFilters.add(fe.getValue()); 6278103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } 6288103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn Collections.sort(tmpFilters, comparator); 6298103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn for (int i=0; i<tmpFilters.size(); i++) { 6308103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn FilterStats fs = tmpFilters.get(i); 6318103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn pw.print(" "); 6328103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn if (fs.nesting > 0) pw.print("*ACTIVE* "); 6338103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn TimeUtils.formatDuration(fs.aggregateTime, pw); 6348103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn pw.print(" "); pw.print(fs.numWakeup); 6358103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn pw.print(" wakes " ); pw.print(fs.count); 6368103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn pw.print(" alarms:"); 6378103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn if (fs.mTarget.first != null) { 6388103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn pw.print(" act="); pw.print(fs.mTarget.first); 6398103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } 6408103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn if (fs.mTarget.second != null) { 6418103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn pw.print(" cmp="); pw.print(fs.mTarget.second.toShortString()); 6428103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } 6438103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn pw.println(); 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 649043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn private static final void dumpAlarmList(PrintWriter pw, ArrayList<Alarm> list, 650043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn String prefix, String label, long now) { 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=list.size()-1; i>=0; i--) { 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm a = list.get(i); 6531d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(prefix); pw.print(label); pw.print(" #"); pw.print(i); 6541d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(": "); pw.println(a); 655043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn a.dump(pw, prefix + " ", now); 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native int init(); 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void close(int fd); 66111c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown private native void set(int fd, int type, long seconds, long nanoseconds); 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native int waitForAlarm(int fd); 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native int setKernelTimezone(int fd, int minuteswest); 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void triggerAlarmsLocked(ArrayList<Alarm> alarmList, 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Alarm> triggerList, 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long now) 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Iterator<Alarm> it = alarmList.iterator(); 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Alarm> repeats = new ArrayList<Alarm>(); 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (it.hasNext()) 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm alarm = it.next(); 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6768a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, "Checking active alarm when=" + alarm.when + " " + alarm); 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.when > now) { 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // don't fire alarms in the future 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the alarm is late, then print a warning message. 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note that this can happen if the user creates a new event on 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the Calendar app with a reminder that is in the past. In that 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // case, the reminder alarm will fire immediately. 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (localLOGV && now - alarm.when > LATE_ALARM_THRESHOLD) { 6888a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "alarm is late! alarm time: " + alarm.when 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " now: " + now + " delay (in seconds): " 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + (now - alarm.when) / 1000); 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Recurring alarms may have passed several alarm intervals while the 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // phone was asleep or off, so pass a trigger count when sending them. 6958a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, "Alarm triggering: " + alarm); 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.count = 1; 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.repeatInterval > 0) { 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this adjustment will be zero if we're late by 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // less than one full repeat interval 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.count += (now - alarm.when) / alarm.repeatInterval; 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerList.add(alarm); 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // remove the alarm from the list 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project it.remove(); 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if it repeats queue it up to be read-added to the list 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.repeatInterval > 0) { 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project repeats.add(alarm); 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reset any repeating alarms. 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project it = repeats.iterator(); 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (it.hasNext()) { 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm alarm = it.next(); 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.when += alarm.count * alarm.repeatInterval; 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addAlarmLocked(alarm); 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarmList.size() > 0) { 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setLocked(alarmList.get(0)); 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This Comparator sorts Alarms into increasing time order. 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static class IncreasingTimeOrder implements Comparator<Alarm> { 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int compare(Alarm a1, Alarm a2) { 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long when1 = a1.when; 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long when2 = a2.when; 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (when1 - when2 > 0) { 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 1; 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (when1 - when2 < 0) { 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static class Alarm { 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int type; 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int count; 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long when; 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long repeatInterval; 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PendingIntent operation; 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Alarm() { 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project when = 0; 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project repeatInterval = 0; 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project operation = null; 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 7591d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn StringBuilder sb = new StringBuilder(128); 7601d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn sb.append("Alarm{"); 7611d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn sb.append(Integer.toHexString(System.identityHashCode(this))); 7621d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn sb.append(" type "); 7631d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn sb.append(type); 7641d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn sb.append(" "); 7651d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn sb.append(operation.getTargetPackage()); 7661d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn sb.append('}'); 7671d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn return sb.toString(); 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 770043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn public void dump(PrintWriter pw, String prefix, long now) { 7711d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(prefix); pw.print("type="); pw.print(type); 772043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn pw.print(" when="); TimeUtils.formatDuration(when, now, pw); 7731d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" repeatInterval="); pw.print(repeatInterval); 7741d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" count="); pw.println(count); 7751d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(prefix); pw.print("operation="); pw.println(operation); 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class AlarmThread extends Thread 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AlarmThread() 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super("AlarmManager"); 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void run() 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (true) 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int result = waitForAlarm(mDescriptor); 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Alarm> triggerList = new ArrayList<Alarm>(); 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((result & TIME_CHANGED_MASK) != 0) { 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project remove(mTimeTickSender); 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mClockReceiver.scheduleTimeTickEvent(); 7971c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn Intent intent = new Intent(Intent.ACTION_TIME_CHANGED); 79889ba6750e5310c4da51786bd7eb559a43cab3982Dianne Hackborn intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING 79989ba6750e5310c4da51786bd7eb559a43cab3982Dianne Hackborn | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 8005ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long nowRTC = System.currentTimeMillis(); 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long nowELAPSED = SystemClock.elapsedRealtime(); 8068a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v( 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TAG, "Checking for alarms... rtc=" + nowRTC 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ", elapsed=" + nowELAPSED); 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((result & RTC_WAKEUP_MASK) != 0) 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mRtcWakeupAlarms, triggerList, nowRTC); 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((result & RTC_MASK) != 0) 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mRtcAlarms, triggerList, nowRTC); 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((result & ELAPSED_REALTIME_WAKEUP_MASK) != 0) 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mElapsedRealtimeWakeupAlarms, triggerList, nowELAPSED); 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((result & ELAPSED_REALTIME_MASK) != 0) 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mElapsedRealtimeAlarms, triggerList, nowELAPSED); 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // now trigger the alarms 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Iterator<Alarm> it = triggerList.iterator(); 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (it.hasNext()) { 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm alarm = it.next(); 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8278a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, "sending alarm " + alarm); 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.operation.send(mContext, 0, 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBackgroundIntent.putExtra( 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent.EXTRA_ALARM_COUNT, alarm.count), 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mResultReceiver, mHandler); 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 833c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate // we have an active broadcast so stay awake. 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBroadcastRefCount == 0) { 835c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate setWakelockWorkSource(alarm.operation); 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWakeLock.acquire(); 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8388103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn final InFlight inflight = new InFlight(AlarmManagerService.this, 8398103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn alarm.operation); 8408103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn mInFlight.add(inflight); 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBroadcastRefCount++; 8428103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn 8438103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn final BroadcastStats bs = inflight.mBroadcastStats; 8448103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn bs.count++; 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bs.nesting == 0) { 8468103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn bs.nesting = 1; 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bs.startTime = nowELAPSED; 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bs.nesting++; 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8518103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn final FilterStats fs = inflight.mFilterStats; 8528103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn fs.count++; 8538103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn if (fs.nesting == 0) { 8548103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn fs.nesting = 1; 8558103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn fs.startTime = nowELAPSED; 8568103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } else { 8578103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn fs.nesting++; 8588103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.type == AlarmManager.ELAPSED_REALTIME_WAKEUP 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || alarm.type == AlarmManager.RTC_WAKEUP) { 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bs.numWakeup++; 8628103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn fs.numWakeup++; 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ActivityManagerNative.noteWakeupAlarm( 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.operation); 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (PendingIntent.CanceledException e) { 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.repeatInterval > 0) { 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This IntentSender is no longer valid, but this 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // is a repeating alarm, so toss the hoser. 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project remove(alarm.operation); 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RuntimeException e) { 8738a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Failure sending alarm.", e); 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 880c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate 881c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate void setWakelockWorkSource(PendingIntent pi) { 882c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate try { 883c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate final int uid = ActivityManagerNative.getDefault() 884c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate .getUidForIntentSender(pi.getTarget()); 885c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate if (uid >= 0) { 886c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate mWakeLock.setWorkSource(new WorkSource(uid)); 887c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate return; 888c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate } 889c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate } catch (Exception e) { 890c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate } 891c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate 892c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate // Something went wrong; fall back to attributing the lock to the OS 893c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate mWakeLock.setWorkSource(null); 894c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate } 895c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class AlarmHandler extends Handler { 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int ALARM_EVENT = 1; 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int MINUTE_CHANGE_EVENT = 2; 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int DATE_CHANGE_EVENT = 3; 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AlarmHandler() { 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void handleMessage(Message msg) { 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (msg.what == ALARM_EVENT) { 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Alarm> triggerList = new ArrayList<Alarm>(); 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long nowRTC = System.currentTimeMillis(); 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mRtcWakeupAlarms, triggerList, nowRTC); 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mRtcAlarms, triggerList, nowRTC); 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mElapsedRealtimeWakeupAlarms, triggerList, nowRTC); 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mElapsedRealtimeAlarms, triggerList, nowRTC); 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // now trigger the alarms without the lock held 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Iterator<Alarm> it = triggerList.iterator(); 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (it.hasNext()) 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm alarm = it.next(); 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.operation.send(); 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (PendingIntent.CanceledException e) { 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.repeatInterval > 0) { 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This IntentSender is no longer valid, but this 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // is a repeating alarm, so toss the hoser. 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project remove(alarm.operation); 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class ClockReceiver extends BroadcastReceiver { 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ClockReceiver() { 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IntentFilter filter = new IntentFilter(); 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project filter.addAction(Intent.ACTION_TIME_TICK); 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project filter.addAction(Intent.ACTION_DATE_CHANGED); 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.registerReceiver(this, filter); 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onReceive(Context context, Intent intent) { 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (intent.getAction().equals(Intent.ACTION_TIME_TICK)) { 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scheduleTimeTickEvent(); 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (intent.getAction().equals(Intent.ACTION_DATE_CHANGED)) { 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Since the kernel does not keep track of DST, we need to 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reset the TZ information at the beginning of each day 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // based off of the current Zone gmt offset + userspace tracked 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // daylight savings information. 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TimeZone zone = TimeZone.getTimeZone(SystemProperties.get(TIMEZONE_PROPERTY)); 952c84cc4f183cb18f299bed237235fa64e013d0fcaLavettacn Xiao int gmtOffset = zone.getOffset(System.currentTimeMillis()); 953c84cc4f183cb18f299bed237235fa64e013d0fcaLavettacn Xiao setKernelTimezone(mDescriptor, -(gmtOffset / 60000)); 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scheduleDateChangedEvent(); 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void scheduleTimeTickEvent() { 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Calendar calendar = Calendar.getInstance(); 96051608a53040cd4bc3694dac2bf67dc18a4b5b235Paul Westbrook final long currentTime = System.currentTimeMillis(); 96151608a53040cd4bc3694dac2bf67dc18a4b5b235Paul Westbrook calendar.setTimeInMillis(currentTime); 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.add(Calendar.MINUTE, 1); 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.set(Calendar.SECOND, 0); 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.set(Calendar.MILLISECOND, 0); 96551608a53040cd4bc3694dac2bf67dc18a4b5b235Paul Westbrook 96651608a53040cd4bc3694dac2bf67dc18a4b5b235Paul Westbrook // Schedule this event for the amount of time that it would take to get to 96751608a53040cd4bc3694dac2bf67dc18a4b5b235Paul Westbrook // the top of the next minute. 96851608a53040cd4bc3694dac2bf67dc18a4b5b235Paul Westbrook final long tickEventDelay = calendar.getTimeInMillis() - currentTime; 96951608a53040cd4bc3694dac2bf67dc18a4b5b235Paul Westbrook 97051608a53040cd4bc3694dac2bf67dc18a4b5b235Paul Westbrook set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + tickEventDelay, 97151608a53040cd4bc3694dac2bf67dc18a4b5b235Paul Westbrook mTimeTickSender); 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void scheduleDateChangedEvent() { 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Calendar calendar = Calendar.getInstance(); 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.setTimeInMillis(System.currentTimeMillis()); 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.set(Calendar.HOUR, 0); 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.set(Calendar.MINUTE, 0); 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.set(Calendar.SECOND, 0); 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.set(Calendar.MILLISECOND, 0); 9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.add(Calendar.DAY_OF_MONTH, 1); 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set(AlarmManager.RTC, calendar.getTimeInMillis(), mDateChangeSender); 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class UninstallReceiver extends BroadcastReceiver { 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public UninstallReceiver() { 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IntentFilter filter = new IntentFilter(); 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project filter.addAction(Intent.ACTION_PACKAGE_REMOVED); 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project filter.addAction(Intent.ACTION_PACKAGE_RESTARTED); 99221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn filter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project filter.addDataScheme("package"); 9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.registerReceiver(this, filter); 99508675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu // Register for events related to sdcard installation. 99608675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu IntentFilter sdFilter = new IntentFilter(); 997b56ae20b22fd7283df32072a431ab6d4965f3c1bSuchi Amalapurapu sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); 99880a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn sdFilter.addAction(Intent.ACTION_USER_STOPPED); 99908675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu mContext.registerReceiver(this, sdFilter); 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onReceive(Context context, Intent intent) { 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 100508675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu String action = intent.getAction(); 100608675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu String pkgList[] = null; 100721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (Intent.ACTION_QUERY_PACKAGE_RESTART.equals(action)) { 100821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn pkgList = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 100921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn for (String packageName : pkgList) { 101021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (lookForPackageLocked(packageName)) { 101121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn setResultCode(Activity.RESULT_OK); 101221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return; 101321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 101421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 101521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return; 101621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) { 101708675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 101880a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn } else if (Intent.ACTION_USER_STOPPED.equals(action)) { 101980a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 102080a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn if (userHandle >= 0) { 102180a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn removeUserLocked(userHandle); 102280a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn } 102308675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } else { 1024409578fcb1d8ecfee0ae07b1a34a6e6cb184a0ceDianne Hackborn if (Intent.ACTION_PACKAGE_REMOVED.equals(action) 1025409578fcb1d8ecfee0ae07b1a34a6e6cb184a0ceDianne Hackborn && intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 1026409578fcb1d8ecfee0ae07b1a34a6e6cb184a0ceDianne Hackborn // This package is being updated; don't kill its alarms. 1027409578fcb1d8ecfee0ae07b1a34a6e6cb184a0ceDianne Hackborn return; 1028409578fcb1d8ecfee0ae07b1a34a6e6cb184a0ceDianne Hackborn } 102908675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu Uri data = intent.getData(); 103008675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (data != null) { 103108675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu String pkg = data.getSchemeSpecificPart(); 103208675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (pkg != null) { 103308675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu pkgList = new String[]{pkg}; 103408675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 103508675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 103608675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 103708675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (pkgList != null && (pkgList.length > 0)) { 103808675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu for (String pkg : pkgList) { 103908675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu removeLocked(pkg); 104008675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu mBroadcastStats.remove(pkg); 104108675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final BroadcastStats getStatsLocked(PendingIntent pi) { 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String pkg = pi.getTargetPackage(); 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BroadcastStats bs = mBroadcastStats.get(pkg); 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bs == null) { 10518103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn bs = new BroadcastStats(pkg); 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBroadcastStats.put(pkg, bs); 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return bs; 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10568103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class ResultReceiver implements PendingIntent.OnFinished { 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onSendFinished(PendingIntent pi, Intent intent, int resultCode, 10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String resultData, Bundle resultExtras) { 10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 10618103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn InFlight inflight = null; 10628103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn for (int i=0; i<mInFlight.size(); i++) { 10638103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn if (mInFlight.get(i).mPendingIntent == pi) { 10648103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn inflight = mInFlight.remove(i); 10658103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn break; 10668103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } 10678103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } 10688103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn if (inflight != null) { 10698103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn final long nowELAPSED = SystemClock.elapsedRealtime(); 10708103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn BroadcastStats bs = inflight.mBroadcastStats; 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bs.nesting--; 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bs.nesting <= 0) { 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bs.nesting = 0; 10748103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn bs.aggregateTime += nowELAPSED - bs.startTime; 10758103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } 10768103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn FilterStats fs = inflight.mFilterStats; 10778103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn fs.nesting--; 10788103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn if (fs.nesting <= 0) { 10798103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn fs.nesting = 0; 10808103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn fs.aggregateTime += nowELAPSED - fs.startTime; 10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10828103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } else { 10838103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn mLog.w("No in-flight alarm for " + pi + " " + intent); 10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBroadcastRefCount--; 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBroadcastRefCount == 0) { 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWakeLock.release(); 10888103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn if (mInFlight.size() > 0) { 10898103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn mLog.w("Finished all broadcasts with " + mInFlight.size() 10908103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn + " remaining inflights"); 10918103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn for (int i=0; i<mInFlight.size(); i++) { 10928103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn mLog.w(" Remaining #" + i + ": " + mInFlight.get(i)); 10938103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } 10948103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn mInFlight.clear(); 10958103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn } 1096c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate } else { 1097c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate // the next of our alarms is now in flight. reattribute the wakelock. 10988103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn if (mInFlight.size() > 0) { 10998103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn setWakelockWorkSource(mInFlight.get(0).mPendingIntent); 1100c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate } else { 1101c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate // should never happen 11028103890a59de6ed4abaedaad80e66666ea59f9b5Dianne Hackborn mLog.w("Alarm wakelock still held but sent queue empty"); 1103c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate mWakeLock.setWorkSource(null); 1104c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate } 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1110