AlarmManagerService.java revision 5ac72a29593ab9a20337a2225df52bdf4754be02
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; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.IntentFilter; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.Uri; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.PowerManager; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemClock; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemProperties; 3780a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackbornimport android.os.UserHandle; 38c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tateimport android.os.WorkSource; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextUtils; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.format.Time; 418a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog; 42043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackbornimport android.util.TimeUtils; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.PrintWriter; 46043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackbornimport java.text.SimpleDateFormat; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Calendar; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Collections; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Comparator; 511f7b4134db07acbb429cd770441ff460fa6f4b1bMike Lockwoodimport java.util.Date; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.HashMap; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Iterator; 54c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tateimport java.util.LinkedList; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Map; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.TimeZone; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass AlarmManagerService extends IAlarmManager.Stub { 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The threshold for how long an alarm can be late before we print a 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // warning message. The time duration is in milliseconds. 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final long LATE_ALARM_THRESHOLD = 10 * 1000; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int RTC_WAKEUP_MASK = 1 << AlarmManager.RTC_WAKEUP; 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int RTC_MASK = 1 << AlarmManager.RTC; 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int ELAPSED_REALTIME_WAKEUP_MASK = 1 << AlarmManager.ELAPSED_REALTIME_WAKEUP; 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int ELAPSED_REALTIME_MASK = 1 << AlarmManager.ELAPSED_REALTIME; 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int TIME_CHANGED_MASK = 1 << 16; 68b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate 69b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate // Alignment quantum for inexact repeating alarms 70b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate private static final long QUANTUM = AlarmManager.INTERVAL_FIFTEEN_MINUTES; 71b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "AlarmManager"; 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String ClockReceiver_TAG = "ClockReceiver"; 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final boolean localLOGV = false; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int ALARM_EVENT = 1; 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TIMEZONE_PROPERTY = "persist.sys.timezone"; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final Intent mBackgroundIntent 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = new Intent().addFlags(Intent.FLAG_FROM_BACKGROUND); 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Context mContext; 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Object mLock = new Object(); 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final ArrayList<Alarm> mRtcWakeupAlarms = new ArrayList<Alarm>(); 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final ArrayList<Alarm> mRtcAlarms = new ArrayList<Alarm>(); 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final ArrayList<Alarm> mElapsedRealtimeWakeupAlarms = new ArrayList<Alarm>(); 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final ArrayList<Alarm> mElapsedRealtimeAlarms = new ArrayList<Alarm>(); 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final IncreasingTimeOrder mIncreasingTimeOrder = new IncreasingTimeOrder(); 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mDescriptor; 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mBroadcastRefCount = 0; 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private PowerManager.WakeLock mWakeLock; 94c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate private LinkedList<PendingIntent> mInFlight = new LinkedList<PendingIntent>(); 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final AlarmThread mWaitThread = new AlarmThread(); 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final AlarmHandler mHandler = new AlarmHandler(); 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ClockReceiver mClockReceiver; 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private UninstallReceiver mUninstallReceiver; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final ResultReceiver mResultReceiver = new ResultReceiver(); 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final PendingIntent mTimeTickSender; 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final PendingIntent mDateChangeSender; 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final class FilterStats { 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int count; 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final class BroadcastStats { 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long aggregateTime; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int numWakeup; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long startTime; 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int nesting; 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project HashMap<Intent.FilterComparison, FilterStats> filterStats 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = new HashMap<Intent.FilterComparison, FilterStats>(); 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final HashMap<String, BroadcastStats> mBroadcastStats 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = new HashMap<String, BroadcastStats>(); 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AlarmManagerService(Context context) { 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDescriptor = init(); 12264ba8e4038ade025da5e02f882219432d6bf1016Robert CH Chou 12364ba8e4038ade025da5e02f882219432d6bf1016Robert CH Chou // We have to set current TimeZone info to kernel 12464ba8e4038ade025da5e02f882219432d6bf1016Robert CH Chou // because kernel doesn't keep this after reboot 12564ba8e4038ade025da5e02f882219432d6bf1016Robert CH Chou String tz = SystemProperties.get(TIMEZONE_PROPERTY); 12664ba8e4038ade025da5e02f882219432d6bf1016Robert CH Chou if (tz != null) { 12764ba8e4038ade025da5e02f882219432d6bf1016Robert CH Chou setTimeZone(tz); 12864ba8e4038ade025da5e02f882219432d6bf1016Robert CH Chou } 12964ba8e4038ade025da5e02f882219432d6bf1016Robert CH Chou 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTimeTickSender = PendingIntent.getBroadcast(context, 0, 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new Intent(Intent.ACTION_TIME_TICK).addFlags( 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent.FLAG_RECEIVER_REGISTERED_ONLY), 0); 1361c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn Intent intent = new Intent(Intent.ACTION_DATE_CHANGED); 1371c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 1381c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn mDateChangeSender = PendingIntent.getBroadcast(context, 0, intent, 0); 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // now that we have initied the driver schedule the alarm 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mClockReceiver= new ClockReceiver(); 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mClockReceiver.scheduleTimeTickEvent(); 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mClockReceiver.scheduleDateChangedEvent(); 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUninstallReceiver = new UninstallReceiver(); 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDescriptor != -1) { 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWaitThread.start(); 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1498a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Failed to open alarm driver. Falling back to a handler."); 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() throws Throwable { 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(mDescriptor); 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.finalize(); 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void set(int type, long triggerAtTime, PendingIntent operation) { 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setRepeating(type, triggerAtTime, 0, operation); 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setRepeating(int type, long triggerAtTime, long interval, 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PendingIntent operation) { 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (operation == null) { 1688a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "set/setRepeating ignored because there is no intent"); 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm alarm = new Alarm(); 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.type = type; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.when = triggerAtTime; 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.repeatInterval = interval; 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.operation = operation; 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remove this alarm if already scheduled. 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(operation); 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1818a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, "set: " + alarm); 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index = addAlarmLocked(alarm); 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (index == 0) { 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setLocked(alarm); 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setInexactRepeating(int type, long triggerAtTime, long interval, 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PendingIntent operation) { 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (operation == null) { 1938a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "setInexactRepeating ignored because there is no intent"); 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 197b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate if (interval <= 0) { 198b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate Slog.w(TAG, "setInexactRepeating ignored because interval " + interval 199b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate + " is invalid"); 200b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate return; 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 202b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate 203b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate // If the requested interval isn't a multiple of 15 minutes, just treat it as exact 204b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate if (interval % QUANTUM != 0) { 205b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate if (localLOGV) Slog.v(TAG, "Interval " + interval + " not a quantum multiple"); 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setRepeating(type, triggerAtTime, interval, operation); 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 210b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate // Translate times into the ELAPSED timebase for alignment purposes so that 211b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate // alignment never tries to match against wall clock times. 212b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate final boolean isRtc = (type == AlarmManager.RTC || type == AlarmManager.RTC_WAKEUP); 213b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate final long skew = (isRtc) 214b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate ? System.currentTimeMillis() - SystemClock.elapsedRealtime() 215b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate : 0; 216b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate 217b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate // Slip forward to the next ELAPSED-timebase quantum after the stated time. If 218b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate // we're *at* a quantum point, leave it alone. 219b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate final long adjustedTriggerTime; 220b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate long offset = (triggerAtTime - skew) % QUANTUM; 221b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate if (offset != 0) { 222b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate adjustedTriggerTime = triggerAtTime - offset + QUANTUM; 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 224b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate adjustedTriggerTime = triggerAtTime; 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 227b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate // Set the alarm based on the quantum-aligned start time 228b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate if (localLOGV) Slog.v(TAG, "setInexactRepeating: type=" + type + " interval=" + interval 229b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate + " trigger=" + adjustedTriggerTime + " orig=" + triggerAtTime); 230b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate setRepeating(type, adjustedTriggerTime, interval, operation); 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23397e44947282b3918ee0bed2d16b33b983f882580Dan Egnor public void setTime(long millis) { 23497e44947282b3918ee0bed2d16b33b983f882580Dan Egnor mContext.enforceCallingOrSelfPermission( 23597e44947282b3918ee0bed2d16b33b983f882580Dan Egnor "android.permission.SET_TIME", 23697e44947282b3918ee0bed2d16b33b983f882580Dan Egnor "setTime"); 23797e44947282b3918ee0bed2d16b33b983f882580Dan Egnor 23897e44947282b3918ee0bed2d16b33b983f882580Dan Egnor SystemClock.setCurrentTimeMillis(millis); 23997e44947282b3918ee0bed2d16b33b983f882580Dan Egnor } 24097e44947282b3918ee0bed2d16b33b983f882580Dan Egnor 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTimeZone(String tz) { 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.enforceCallingOrSelfPermission( 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.permission.SET_TIME_ZONE", 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "setTimeZone"); 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (TextUtils.isEmpty(tz)) return; 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TimeZone zone = TimeZone.getTimeZone(tz); 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Prevent reentrant calls from stepping on each other when writing 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the time zone property 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean timeZoneWasChanged = false; 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String current = SystemProperties.get(TIMEZONE_PROPERTY); 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (current == null || !current.equals(zone.getID())) { 2548a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, "timezone changed: " + current + ", new=" + zone.getID()); 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project timeZoneWasChanged = true; 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SystemProperties.set(TIMEZONE_PROPERTY, zone.getID()); 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Update the kernel timezone information 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Kernel tracks time offsets as 'minutes west of GMT' 261c84cc4f183cb18f299bed237235fa64e013d0fcaLavettacn Xiao int gmtOffset = zone.getOffset(System.currentTimeMillis()); 2621f7b4134db07acbb429cd770441ff460fa6f4b1bMike Lockwood setKernelTimezone(mDescriptor, -(gmtOffset / 60000)); 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TimeZone.setDefault(null); 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (timeZoneWasChanged) { 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 2691c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra("time-zone", zone.getID()); 2715ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void remove(PendingIntent operation) { 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (operation == null) { 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(operation); 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeLocked(PendingIntent operation) { 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mRtcWakeupAlarms, operation); 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mRtcAlarms, operation); 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mElapsedRealtimeWakeupAlarms, operation); 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mElapsedRealtimeAlarms, operation); 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void removeLocked(ArrayList<Alarm> alarmList, 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PendingIntent operation) { 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarmList.size() <= 0) { 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // iterator over the list removing any it where the intent match 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Iterator<Alarm> it = alarmList.iterator(); 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (it.hasNext()) { 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm alarm = it.next(); 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.operation.equals(operation)) { 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project it.remove(); 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 30780a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeLocked(String packageName) { 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mRtcWakeupAlarms, packageName); 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mRtcAlarms, packageName); 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mElapsedRealtimeWakeupAlarms, packageName); 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mElapsedRealtimeAlarms, packageName); 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void removeLocked(ArrayList<Alarm> alarmList, 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String packageName) { 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarmList.size() <= 0) { 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // iterator over the list removing any it where the intent match 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Iterator<Alarm> it = alarmList.iterator(); 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (it.hasNext()) { 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm alarm = it.next(); 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.operation.getTargetPackage().equals(packageName)) { 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project it.remove(); 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 33180a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn 33280a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn public void removeUserLocked(int userHandle) { 33380a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn removeUserLocked(mRtcWakeupAlarms, userHandle); 33480a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn removeUserLocked(mRtcAlarms, userHandle); 33580a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn removeUserLocked(mElapsedRealtimeWakeupAlarms, userHandle); 33680a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn removeUserLocked(mElapsedRealtimeAlarms, userHandle); 33780a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn } 33880a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn 33980a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn private void removeUserLocked(ArrayList<Alarm> alarmList, int userHandle) { 34080a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn if (alarmList.size() <= 0) { 34180a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn return; 34280a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn } 34380a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn 34480a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn // iterator over the list removing any it where the intent match 34580a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn Iterator<Alarm> it = alarmList.iterator(); 34680a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn 34780a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn while (it.hasNext()) { 34880a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn Alarm alarm = it.next(); 34980a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn if (UserHandle.getUserId(alarm.operation.getTargetUid()) == userHandle) { 35080a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn it.remove(); 35180a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn } 35280a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn } 35380a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn } 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 35521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn public boolean lookForPackageLocked(String packageName) { 35621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return lookForPackageLocked(mRtcWakeupAlarms, packageName) 35721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn || lookForPackageLocked(mRtcAlarms, packageName) 35821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn || lookForPackageLocked(mElapsedRealtimeWakeupAlarms, packageName) 35921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn || lookForPackageLocked(mElapsedRealtimeAlarms, packageName); 36021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 36121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 36221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn private boolean lookForPackageLocked(ArrayList<Alarm> alarmList, String packageName) { 36321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn for (int i=alarmList.size()-1; i>=0; i--) { 36421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (alarmList.get(i).operation.getTargetPackage().equals(packageName)) { 36521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return true; 36621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 36721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 36821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return false; 36921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 37021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ArrayList<Alarm> getAlarmList(int type) { 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (type) { 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case AlarmManager.RTC_WAKEUP: return mRtcWakeupAlarms; 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case AlarmManager.RTC: return mRtcAlarms; 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case AlarmManager.ELAPSED_REALTIME_WAKEUP: return mElapsedRealtimeWakeupAlarms; 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case AlarmManager.ELAPSED_REALTIME: return mElapsedRealtimeAlarms; 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int addAlarmLocked(Alarm alarm) { 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Alarm> alarmList = getAlarmList(alarm.type); 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index = Collections.binarySearch(alarmList, alarm, mIncreasingTimeOrder); 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (index < 0) { 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index = 0 - index - 1; 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3898a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, "Adding alarm " + alarm + " at " + index); 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarmList.add(index, alarm); 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (localLOGV) { 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Display the list of alarms for this alarm type 3948a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "alarms: " + alarmList.size() + " type: " + alarm.type); 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int position = 0; 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Alarm a : alarmList) { 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Time time = new Time(); 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project time.set(a.when); 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String timeStr = time.format("%b %d %I:%M:%S %p"); 4008a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, position + ": " + timeStr 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " " + a.operation.getTargetPackage()); 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project position += 1; 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return index; 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long timeToNextAlarm() { 41011c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown long nextAlarm = Long.MAX_VALUE; 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=AlarmManager.RTC_WAKEUP; 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i<=AlarmManager.ELAPSED_REALTIME; i++) { 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Alarm> alarmList = getAlarmList(i); 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarmList.size() > 0) { 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm a = alarmList.get(0); 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (a.when < nextAlarm) { 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nextAlarm = a.when; 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return nextAlarm; 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void setLocked(Alarm alarm) 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDescriptor != -1) 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 43011c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown // The kernel never triggers alarms with negative wakeup times 43111c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown // so we ensure they are positive. 43211c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown long alarmSeconds, alarmNanoseconds; 43311c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown if (alarm.when < 0) { 43411c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown alarmSeconds = 0; 43511c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown alarmNanoseconds = 0; 43611c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown } else { 43711c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown alarmSeconds = alarm.when / 1000; 43811c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown alarmNanoseconds = (alarm.when % 1000) * 1000 * 1000; 43911c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown } 44011c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown 44111c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown set(mDescriptor, alarm.type, alarmSeconds, alarmNanoseconds); 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message msg = Message.obtain(); 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.what = ALARM_EVENT; 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.removeMessages(ALARM_EVENT); 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.sendMessageAtTime(msg, alarm.when); 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED) { 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println("Permission Denial: can't dump AlarmManager from from pid=" 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Binder.getCallingPid() 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ", uid=" + Binder.getCallingUid()); 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println("Current Alarm Manager state:"); 4651d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn if (mRtcWakeupAlarms.size() > 0 || mRtcAlarms.size() > 0) { 466043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn final long now = System.currentTimeMillis(); 467043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" "); 4691d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" Realtime wakeup (now="); 470043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn pw.print(sdf.format(new Date(now))); pw.println("):"); 4711d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn if (mRtcWakeupAlarms.size() > 0) { 472043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn dumpAlarmList(pw, mRtcWakeupAlarms, " ", "RTC_WAKEUP", now); 4731d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn } 4741d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn if (mRtcAlarms.size() > 0) { 475043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn dumpAlarmList(pw, mRtcAlarms, " ", "RTC", now); 4761d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn } 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4781d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn if (mElapsedRealtimeWakeupAlarms.size() > 0 || mElapsedRealtimeAlarms.size() > 0) { 479043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn final long now = SystemClock.elapsedRealtime(); 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" "); 4811d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" Elapsed realtime wakeup (now="); 482043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn TimeUtils.formatDuration(now, pw); pw.println("):"); 4831d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn if (mElapsedRealtimeWakeupAlarms.size() > 0) { 484043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn dumpAlarmList(pw, mElapsedRealtimeWakeupAlarms, " ", "ELAPSED_WAKEUP", now); 4851d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn } 4861d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn if (mElapsedRealtimeAlarms.size() > 0) { 487043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn dumpAlarmList(pw, mElapsedRealtimeAlarms, " ", "ELAPSED", now); 4881d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn } 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" "); 4921d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" Broadcast ref count: "); pw.println(mBroadcastRefCount); 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" "); 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Alarm Stats:"); 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Map.Entry<String, BroadcastStats> be : mBroadcastStats.entrySet()) { 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BroadcastStats bs = be.getValue(); 4981d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" "); pw.println(be.getKey()); 4991d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" "); pw.print(bs.aggregateTime); 5001d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print("ms running, "); pw.print(bs.numWakeup); 5011d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.println(" wakeups"); 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Map.Entry<Intent.FilterComparison, FilterStats> fe 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : bs.filterStats.entrySet()) { 5041d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" "); pw.print(fe.getValue().count); 5051d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" alarms: "); 50621c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn pw.println(fe.getKey().getIntent().toShortString( 50721c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn false, true, false, true)); 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 513043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn private static final void dumpAlarmList(PrintWriter pw, ArrayList<Alarm> list, 514043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn String prefix, String label, long now) { 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=list.size()-1; i>=0; i--) { 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm a = list.get(i); 5171d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(prefix); pw.print(label); pw.print(" #"); pw.print(i); 5181d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(": "); pw.println(a); 519043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn a.dump(pw, prefix + " ", now); 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native int init(); 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void close(int fd); 52511c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown private native void set(int fd, int type, long seconds, long nanoseconds); 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native int waitForAlarm(int fd); 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native int setKernelTimezone(int fd, int minuteswest); 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void triggerAlarmsLocked(ArrayList<Alarm> alarmList, 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Alarm> triggerList, 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long now) 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Iterator<Alarm> it = alarmList.iterator(); 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Alarm> repeats = new ArrayList<Alarm>(); 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (it.hasNext()) 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm alarm = it.next(); 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5408a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, "Checking active alarm when=" + alarm.when + " " + alarm); 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.when > now) { 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // don't fire alarms in the future 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the alarm is late, then print a warning message. 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note that this can happen if the user creates a new event on 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the Calendar app with a reminder that is in the past. In that 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // case, the reminder alarm will fire immediately. 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (localLOGV && now - alarm.when > LATE_ALARM_THRESHOLD) { 5528a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "alarm is late! alarm time: " + alarm.when 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " now: " + now + " delay (in seconds): " 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + (now - alarm.when) / 1000); 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Recurring alarms may have passed several alarm intervals while the 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // phone was asleep or off, so pass a trigger count when sending them. 5598a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, "Alarm triggering: " + alarm); 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.count = 1; 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.repeatInterval > 0) { 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this adjustment will be zero if we're late by 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // less than one full repeat interval 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.count += (now - alarm.when) / alarm.repeatInterval; 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerList.add(alarm); 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // remove the alarm from the list 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project it.remove(); 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if it repeats queue it up to be read-added to the list 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.repeatInterval > 0) { 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project repeats.add(alarm); 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reset any repeating alarms. 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project it = repeats.iterator(); 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (it.hasNext()) { 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm alarm = it.next(); 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.when += alarm.count * alarm.repeatInterval; 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addAlarmLocked(alarm); 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarmList.size() > 0) { 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setLocked(alarmList.get(0)); 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This Comparator sorts Alarms into increasing time order. 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static class IncreasingTimeOrder implements Comparator<Alarm> { 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int compare(Alarm a1, Alarm a2) { 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long when1 = a1.when; 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long when2 = a2.when; 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (when1 - when2 > 0) { 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 1; 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (when1 - when2 < 0) { 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static class Alarm { 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int type; 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int count; 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long when; 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long repeatInterval; 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PendingIntent operation; 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Alarm() { 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project when = 0; 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project repeatInterval = 0; 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project operation = null; 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6231d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn StringBuilder sb = new StringBuilder(128); 6241d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn sb.append("Alarm{"); 6251d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn sb.append(Integer.toHexString(System.identityHashCode(this))); 6261d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn sb.append(" type "); 6271d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn sb.append(type); 6281d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn sb.append(" "); 6291d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn sb.append(operation.getTargetPackage()); 6301d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn sb.append('}'); 6311d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn return sb.toString(); 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 634043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn public void dump(PrintWriter pw, String prefix, long now) { 6351d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(prefix); pw.print("type="); pw.print(type); 636043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn pw.print(" when="); TimeUtils.formatDuration(when, now, pw); 6371d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" repeatInterval="); pw.print(repeatInterval); 6381d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" count="); pw.println(count); 6391d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(prefix); pw.print("operation="); pw.println(operation); 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class AlarmThread extends Thread 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AlarmThread() 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super("AlarmManager"); 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void run() 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (true) 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int result = waitForAlarm(mDescriptor); 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Alarm> triggerList = new ArrayList<Alarm>(); 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((result & TIME_CHANGED_MASK) != 0) { 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project remove(mTimeTickSender); 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mClockReceiver.scheduleTimeTickEvent(); 6611c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn Intent intent = new Intent(Intent.ACTION_TIME_CHANGED); 66289ba6750e5310c4da51786bd7eb559a43cab3982Dianne Hackborn intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING 66389ba6750e5310c4da51786bd7eb559a43cab3982Dianne Hackborn | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 6645ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long nowRTC = System.currentTimeMillis(); 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long nowELAPSED = SystemClock.elapsedRealtime(); 6708a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v( 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TAG, "Checking for alarms... rtc=" + nowRTC 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ", elapsed=" + nowELAPSED); 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((result & RTC_WAKEUP_MASK) != 0) 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mRtcWakeupAlarms, triggerList, nowRTC); 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((result & RTC_MASK) != 0) 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mRtcAlarms, triggerList, nowRTC); 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((result & ELAPSED_REALTIME_WAKEUP_MASK) != 0) 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mElapsedRealtimeWakeupAlarms, triggerList, nowELAPSED); 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((result & ELAPSED_REALTIME_MASK) != 0) 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mElapsedRealtimeAlarms, triggerList, nowELAPSED); 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // now trigger the alarms 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Iterator<Alarm> it = triggerList.iterator(); 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (it.hasNext()) { 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm alarm = it.next(); 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 6918a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, "sending alarm " + alarm); 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.operation.send(mContext, 0, 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBackgroundIntent.putExtra( 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent.EXTRA_ALARM_COUNT, alarm.count), 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mResultReceiver, mHandler); 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 697c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate // we have an active broadcast so stay awake. 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBroadcastRefCount == 0) { 699c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate setWakelockWorkSource(alarm.operation); 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWakeLock.acquire(); 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 702c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate mInFlight.add(alarm.operation); 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBroadcastRefCount++; 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BroadcastStats bs = getStatsLocked(alarm.operation); 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bs.nesting == 0) { 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bs.startTime = nowELAPSED; 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bs.nesting++; 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.type == AlarmManager.ELAPSED_REALTIME_WAKEUP 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || alarm.type == AlarmManager.RTC_WAKEUP) { 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bs.numWakeup++; 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ActivityManagerNative.noteWakeupAlarm( 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.operation); 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (PendingIntent.CanceledException e) { 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.repeatInterval > 0) { 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This IntentSender is no longer valid, but this 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // is a repeating alarm, so toss the hoser. 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project remove(alarm.operation); 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RuntimeException e) { 7248a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Failure sending alarm.", e); 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 731c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate 732c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate void setWakelockWorkSource(PendingIntent pi) { 733c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate try { 734c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate final int uid = ActivityManagerNative.getDefault() 735c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate .getUidForIntentSender(pi.getTarget()); 736c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate if (uid >= 0) { 737c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate mWakeLock.setWorkSource(new WorkSource(uid)); 738c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate return; 739c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate } 740c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate } catch (Exception e) { 741c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate } 742c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate 743c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate // Something went wrong; fall back to attributing the lock to the OS 744c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate mWakeLock.setWorkSource(null); 745c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate } 746c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class AlarmHandler extends Handler { 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int ALARM_EVENT = 1; 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int MINUTE_CHANGE_EVENT = 2; 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int DATE_CHANGE_EVENT = 3; 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AlarmHandler() { 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void handleMessage(Message msg) { 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (msg.what == ALARM_EVENT) { 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Alarm> triggerList = new ArrayList<Alarm>(); 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long nowRTC = System.currentTimeMillis(); 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mRtcWakeupAlarms, triggerList, nowRTC); 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mRtcAlarms, triggerList, nowRTC); 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mElapsedRealtimeWakeupAlarms, triggerList, nowRTC); 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mElapsedRealtimeAlarms, triggerList, nowRTC); 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // now trigger the alarms without the lock held 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Iterator<Alarm> it = triggerList.iterator(); 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (it.hasNext()) 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm alarm = it.next(); 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.operation.send(); 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (PendingIntent.CanceledException e) { 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.repeatInterval > 0) { 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This IntentSender is no longer valid, but this 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // is a repeating alarm, so toss the hoser. 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project remove(alarm.operation); 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class ClockReceiver extends BroadcastReceiver { 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ClockReceiver() { 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IntentFilter filter = new IntentFilter(); 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project filter.addAction(Intent.ACTION_TIME_TICK); 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project filter.addAction(Intent.ACTION_DATE_CHANGED); 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.registerReceiver(this, filter); 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onReceive(Context context, Intent intent) { 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (intent.getAction().equals(Intent.ACTION_TIME_TICK)) { 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scheduleTimeTickEvent(); 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (intent.getAction().equals(Intent.ACTION_DATE_CHANGED)) { 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Since the kernel does not keep track of DST, we need to 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reset the TZ information at the beginning of each day 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // based off of the current Zone gmt offset + userspace tracked 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // daylight savings information. 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TimeZone zone = TimeZone.getTimeZone(SystemProperties.get(TIMEZONE_PROPERTY)); 803c84cc4f183cb18f299bed237235fa64e013d0fcaLavettacn Xiao int gmtOffset = zone.getOffset(System.currentTimeMillis()); 804c84cc4f183cb18f299bed237235fa64e013d0fcaLavettacn Xiao setKernelTimezone(mDescriptor, -(gmtOffset / 60000)); 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scheduleDateChangedEvent(); 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void scheduleTimeTickEvent() { 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Calendar calendar = Calendar.getInstance(); 81151608a53040cd4bc3694dac2bf67dc18a4b5b235Paul Westbrook final long currentTime = System.currentTimeMillis(); 81251608a53040cd4bc3694dac2bf67dc18a4b5b235Paul Westbrook calendar.setTimeInMillis(currentTime); 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.add(Calendar.MINUTE, 1); 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.set(Calendar.SECOND, 0); 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.set(Calendar.MILLISECOND, 0); 81651608a53040cd4bc3694dac2bf67dc18a4b5b235Paul Westbrook 81751608a53040cd4bc3694dac2bf67dc18a4b5b235Paul Westbrook // Schedule this event for the amount of time that it would take to get to 81851608a53040cd4bc3694dac2bf67dc18a4b5b235Paul Westbrook // the top of the next minute. 81951608a53040cd4bc3694dac2bf67dc18a4b5b235Paul Westbrook final long tickEventDelay = calendar.getTimeInMillis() - currentTime; 82051608a53040cd4bc3694dac2bf67dc18a4b5b235Paul Westbrook 82151608a53040cd4bc3694dac2bf67dc18a4b5b235Paul Westbrook set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + tickEventDelay, 82251608a53040cd4bc3694dac2bf67dc18a4b5b235Paul Westbrook mTimeTickSender); 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void scheduleDateChangedEvent() { 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Calendar calendar = Calendar.getInstance(); 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.setTimeInMillis(System.currentTimeMillis()); 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.set(Calendar.HOUR, 0); 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.set(Calendar.MINUTE, 0); 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.set(Calendar.SECOND, 0); 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.set(Calendar.MILLISECOND, 0); 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.add(Calendar.DAY_OF_MONTH, 1); 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set(AlarmManager.RTC, calendar.getTimeInMillis(), mDateChangeSender); 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class UninstallReceiver extends BroadcastReceiver { 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public UninstallReceiver() { 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IntentFilter filter = new IntentFilter(); 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project filter.addAction(Intent.ACTION_PACKAGE_REMOVED); 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project filter.addAction(Intent.ACTION_PACKAGE_RESTARTED); 84321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn filter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project filter.addDataScheme("package"); 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.registerReceiver(this, filter); 84608675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu // Register for events related to sdcard installation. 84708675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu IntentFilter sdFilter = new IntentFilter(); 848b56ae20b22fd7283df32072a431ab6d4965f3c1bSuchi Amalapurapu sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); 84980a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn sdFilter.addAction(Intent.ACTION_USER_STOPPED); 85008675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu mContext.registerReceiver(this, sdFilter); 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onReceive(Context context, Intent intent) { 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 85608675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu String action = intent.getAction(); 85708675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu String pkgList[] = null; 85821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (Intent.ACTION_QUERY_PACKAGE_RESTART.equals(action)) { 85921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn pkgList = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 86021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn for (String packageName : pkgList) { 86121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (lookForPackageLocked(packageName)) { 86221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn setResultCode(Activity.RESULT_OK); 86321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return; 86421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 86521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 86621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return; 86721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) { 86808675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 86980a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn } else if (Intent.ACTION_USER_STOPPED.equals(action)) { 87080a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 87180a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn if (userHandle >= 0) { 87280a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn removeUserLocked(userHandle); 87380a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn } 87408675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } else { 875409578fcb1d8ecfee0ae07b1a34a6e6cb184a0ceDianne Hackborn if (Intent.ACTION_PACKAGE_REMOVED.equals(action) 876409578fcb1d8ecfee0ae07b1a34a6e6cb184a0ceDianne Hackborn && intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 877409578fcb1d8ecfee0ae07b1a34a6e6cb184a0ceDianne Hackborn // This package is being updated; don't kill its alarms. 878409578fcb1d8ecfee0ae07b1a34a6e6cb184a0ceDianne Hackborn return; 879409578fcb1d8ecfee0ae07b1a34a6e6cb184a0ceDianne Hackborn } 88008675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu Uri data = intent.getData(); 88108675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (data != null) { 88208675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu String pkg = data.getSchemeSpecificPart(); 88308675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (pkg != null) { 88408675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu pkgList = new String[]{pkg}; 88508675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 88608675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 88708675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 88808675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (pkgList != null && (pkgList.length > 0)) { 88908675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu for (String pkg : pkgList) { 89008675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu removeLocked(pkg); 89108675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu mBroadcastStats.remove(pkg); 89208675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final BroadcastStats getStatsLocked(PendingIntent pi) { 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String pkg = pi.getTargetPackage(); 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BroadcastStats bs = mBroadcastStats.get(pkg); 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bs == null) { 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bs = new BroadcastStats(); 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBroadcastStats.put(pkg, bs); 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return bs; 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class ResultReceiver implements PendingIntent.OnFinished { 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onSendFinished(PendingIntent pi, Intent intent, int resultCode, 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String resultData, Bundle resultExtras) { 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BroadcastStats bs = getStatsLocked(pi); 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bs != null) { 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bs.nesting--; 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bs.nesting <= 0) { 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bs.nesting = 0; 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bs.aggregateTime += SystemClock.elapsedRealtime() 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project - bs.startTime; 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent.FilterComparison fc = new Intent.FilterComparison(intent); 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FilterStats fs = bs.filterStats.get(fc); 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fs == null) { 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fs = new FilterStats(); 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bs.filterStats.put(fc, fs); 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fs.count++; 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 928c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate mInFlight.removeFirst(); 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBroadcastRefCount--; 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBroadcastRefCount == 0) { 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWakeLock.release(); 932c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate } else { 933c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate // the next of our alarms is now in flight. reattribute the wakelock. 934c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate final PendingIntent nowInFlight = mInFlight.peekFirst(); 935c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate if (nowInFlight != null) { 936c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate setWakelockWorkSource(nowInFlight); 937c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate } else { 938c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate // should never happen 939c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate Slog.e(TAG, "Alarm wakelock still held but sent queue empty"); 940c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate mWakeLock.setWorkSource(null); 941c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate } 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 947