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 133db5aca9aa6a3cb70c865e7f825a2826ccef5bb32Dianne Hackborn mTimeTickSender = PendingIntent.getBroadcastAsUser(context, 0, 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new Intent(Intent.ACTION_TIME_TICK).addFlags( 135db5aca9aa6a3cb70c865e7f825a2826ccef5bb32Dianne Hackborn Intent.FLAG_RECEIVER_REGISTERED_ONLY), 0, 136db5aca9aa6a3cb70c865e7f825a2826ccef5bb32Dianne Hackborn UserHandle.ALL); 1371c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn Intent intent = new Intent(Intent.ACTION_DATE_CHANGED); 1381c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 139db5aca9aa6a3cb70c865e7f825a2826ccef5bb32Dianne Hackborn mDateChangeSender = PendingIntent.getBroadcastAsUser(context, 0, intent, 140db5aca9aa6a3cb70c865e7f825a2826ccef5bb32Dianne Hackborn Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT, UserHandle.ALL); 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // now that we have initied the driver schedule the alarm 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mClockReceiver= new ClockReceiver(); 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mClockReceiver.scheduleTimeTickEvent(); 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mClockReceiver.scheduleDateChangedEvent(); 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUninstallReceiver = new UninstallReceiver(); 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDescriptor != -1) { 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWaitThread.start(); 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1518a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Failed to open alarm driver. Falling back to a handler."); 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() throws Throwable { 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(mDescriptor); 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.finalize(); 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void set(int type, long triggerAtTime, PendingIntent operation) { 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setRepeating(type, triggerAtTime, 0, operation); 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setRepeating(int type, long triggerAtTime, long interval, 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PendingIntent operation) { 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (operation == null) { 1708a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "set/setRepeating ignored because there is no intent"); 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm alarm = new Alarm(); 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.type = type; 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.when = triggerAtTime; 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.repeatInterval = interval; 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.operation = operation; 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remove this alarm if already scheduled. 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(operation); 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1838a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, "set: " + alarm); 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index = addAlarmLocked(alarm); 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (index == 0) { 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setLocked(alarm); 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setInexactRepeating(int type, long triggerAtTime, long interval, 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PendingIntent operation) { 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (operation == null) { 1958a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "setInexactRepeating ignored because there is no intent"); 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate if (interval <= 0) { 200b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate Slog.w(TAG, "setInexactRepeating ignored because interval " + interval 201b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate + " is invalid"); 202b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate return; 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 204b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate 205b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate // If the requested interval isn't a multiple of 15 minutes, just treat it as exact 206b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate if (interval % QUANTUM != 0) { 207b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate if (localLOGV) Slog.v(TAG, "Interval " + interval + " not a quantum multiple"); 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setRepeating(type, triggerAtTime, interval, operation); 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 212b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate // Translate times into the ELAPSED timebase for alignment purposes so that 213b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate // alignment never tries to match against wall clock times. 214b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate final boolean isRtc = (type == AlarmManager.RTC || type == AlarmManager.RTC_WAKEUP); 215b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate final long skew = (isRtc) 216b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate ? System.currentTimeMillis() - SystemClock.elapsedRealtime() 217b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate : 0; 218b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate 219b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate // Slip forward to the next ELAPSED-timebase quantum after the stated time. If 220b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate // we're *at* a quantum point, leave it alone. 221b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate final long adjustedTriggerTime; 222b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate long offset = (triggerAtTime - skew) % QUANTUM; 223b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate if (offset != 0) { 224b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate adjustedTriggerTime = triggerAtTime - offset + QUANTUM; 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 226b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate adjustedTriggerTime = triggerAtTime; 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 229b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate // Set the alarm based on the quantum-aligned start time 230b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate if (localLOGV) Slog.v(TAG, "setInexactRepeating: type=" + type + " interval=" + interval 231b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate + " trigger=" + adjustedTriggerTime + " orig=" + triggerAtTime); 232b8849c1e858c726eaf04f7c5a5a08036faa171dfChristopher Tate setRepeating(type, adjustedTriggerTime, interval, operation); 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23597e44947282b3918ee0bed2d16b33b983f882580Dan Egnor public void setTime(long millis) { 23697e44947282b3918ee0bed2d16b33b983f882580Dan Egnor mContext.enforceCallingOrSelfPermission( 23797e44947282b3918ee0bed2d16b33b983f882580Dan Egnor "android.permission.SET_TIME", 23897e44947282b3918ee0bed2d16b33b983f882580Dan Egnor "setTime"); 23997e44947282b3918ee0bed2d16b33b983f882580Dan Egnor 24097e44947282b3918ee0bed2d16b33b983f882580Dan Egnor SystemClock.setCurrentTimeMillis(millis); 24197e44947282b3918ee0bed2d16b33b983f882580Dan Egnor } 24297e44947282b3918ee0bed2d16b33b983f882580Dan Egnor 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTimeZone(String tz) { 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.enforceCallingOrSelfPermission( 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.permission.SET_TIME_ZONE", 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "setTimeZone"); 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 248897798225d9c48bd3424757059318ed1eb3207deChristopher Tate long oldId = Binder.clearCallingIdentity(); 249897798225d9c48bd3424757059318ed1eb3207deChristopher Tate try { 250897798225d9c48bd3424757059318ed1eb3207deChristopher Tate if (TextUtils.isEmpty(tz)) return; 251897798225d9c48bd3424757059318ed1eb3207deChristopher Tate TimeZone zone = TimeZone.getTimeZone(tz); 252897798225d9c48bd3424757059318ed1eb3207deChristopher Tate // Prevent reentrant calls from stepping on each other when writing 253897798225d9c48bd3424757059318ed1eb3207deChristopher Tate // the time zone property 254897798225d9c48bd3424757059318ed1eb3207deChristopher Tate boolean timeZoneWasChanged = false; 255897798225d9c48bd3424757059318ed1eb3207deChristopher Tate synchronized (this) { 256897798225d9c48bd3424757059318ed1eb3207deChristopher Tate String current = SystemProperties.get(TIMEZONE_PROPERTY); 257897798225d9c48bd3424757059318ed1eb3207deChristopher Tate if (current == null || !current.equals(zone.getID())) { 258897798225d9c48bd3424757059318ed1eb3207deChristopher Tate if (localLOGV) { 259897798225d9c48bd3424757059318ed1eb3207deChristopher Tate Slog.v(TAG, "timezone changed: " + current + ", new=" + zone.getID()); 260897798225d9c48bd3424757059318ed1eb3207deChristopher Tate } 261897798225d9c48bd3424757059318ed1eb3207deChristopher Tate timeZoneWasChanged = true; 262897798225d9c48bd3424757059318ed1eb3207deChristopher Tate SystemProperties.set(TIMEZONE_PROPERTY, zone.getID()); 263897798225d9c48bd3424757059318ed1eb3207deChristopher Tate } 264897798225d9c48bd3424757059318ed1eb3207deChristopher Tate 265897798225d9c48bd3424757059318ed1eb3207deChristopher Tate // Update the kernel timezone information 266897798225d9c48bd3424757059318ed1eb3207deChristopher Tate // Kernel tracks time offsets as 'minutes west of GMT' 267897798225d9c48bd3424757059318ed1eb3207deChristopher Tate int gmtOffset = zone.getOffset(System.currentTimeMillis()); 268897798225d9c48bd3424757059318ed1eb3207deChristopher Tate setKernelTimezone(mDescriptor, -(gmtOffset / 60000)); 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 271897798225d9c48bd3424757059318ed1eb3207deChristopher Tate TimeZone.setDefault(null); 272897798225d9c48bd3424757059318ed1eb3207deChristopher Tate 273897798225d9c48bd3424757059318ed1eb3207deChristopher Tate if (timeZoneWasChanged) { 274897798225d9c48bd3424757059318ed1eb3207deChristopher Tate Intent intent = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 275897798225d9c48bd3424757059318ed1eb3207deChristopher Tate intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 276897798225d9c48bd3424757059318ed1eb3207deChristopher Tate intent.putExtra("time-zone", zone.getID()); 277897798225d9c48bd3424757059318ed1eb3207deChristopher Tate mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 278897798225d9c48bd3424757059318ed1eb3207deChristopher Tate } 279897798225d9c48bd3424757059318ed1eb3207deChristopher Tate } finally { 280897798225d9c48bd3424757059318ed1eb3207deChristopher Tate Binder.restoreCallingIdentity(oldId); 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void remove(PendingIntent operation) { 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (operation == null) { 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(operation); 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeLocked(PendingIntent operation) { 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mRtcWakeupAlarms, operation); 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mRtcAlarms, operation); 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mElapsedRealtimeWakeupAlarms, operation); 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mElapsedRealtimeAlarms, operation); 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void removeLocked(ArrayList<Alarm> alarmList, 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PendingIntent operation) { 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarmList.size() <= 0) { 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // iterator over the list removing any it where the intent match 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Iterator<Alarm> it = alarmList.iterator(); 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (it.hasNext()) { 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm alarm = it.next(); 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.operation.equals(operation)) { 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project it.remove(); 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 31680a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeLocked(String packageName) { 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mRtcWakeupAlarms, packageName); 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mRtcAlarms, packageName); 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mElapsedRealtimeWakeupAlarms, packageName); 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mElapsedRealtimeAlarms, packageName); 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void removeLocked(ArrayList<Alarm> alarmList, 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String packageName) { 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarmList.size() <= 0) { 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // iterator over the list removing any it where the intent match 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Iterator<Alarm> it = alarmList.iterator(); 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (it.hasNext()) { 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm alarm = it.next(); 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.operation.getTargetPackage().equals(packageName)) { 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project it.remove(); 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 34080a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn 34180a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn public void removeUserLocked(int userHandle) { 34280a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn removeUserLocked(mRtcWakeupAlarms, userHandle); 34380a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn removeUserLocked(mRtcAlarms, userHandle); 34480a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn removeUserLocked(mElapsedRealtimeWakeupAlarms, userHandle); 34580a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn removeUserLocked(mElapsedRealtimeAlarms, userHandle); 34680a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn } 34780a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn 34880a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn private void removeUserLocked(ArrayList<Alarm> alarmList, int userHandle) { 34980a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn if (alarmList.size() <= 0) { 35080a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn return; 35180a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn } 35280a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn 35380a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn // iterator over the list removing any it where the intent match 35480a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn Iterator<Alarm> it = alarmList.iterator(); 35580a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn 35680a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn while (it.hasNext()) { 35780a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn Alarm alarm = it.next(); 3588832c18d8b63367929c2d394c9c508f56003d400Dianne Hackborn if (UserHandle.getUserId(alarm.operation.getCreatorUid()) == userHandle) { 35980a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn it.remove(); 36080a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn } 36180a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn } 36280a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn } 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn public boolean lookForPackageLocked(String packageName) { 36521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return lookForPackageLocked(mRtcWakeupAlarms, packageName) 36621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn || lookForPackageLocked(mRtcAlarms, packageName) 36721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn || lookForPackageLocked(mElapsedRealtimeWakeupAlarms, packageName) 36821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn || lookForPackageLocked(mElapsedRealtimeAlarms, packageName); 36921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 37021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 37121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn private boolean lookForPackageLocked(ArrayList<Alarm> alarmList, String packageName) { 37221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn for (int i=alarmList.size()-1; i>=0; i--) { 37321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (alarmList.get(i).operation.getTargetPackage().equals(packageName)) { 37421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return true; 37521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 37621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 37721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return false; 37821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 37921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ArrayList<Alarm> getAlarmList(int type) { 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (type) { 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case AlarmManager.RTC_WAKEUP: return mRtcWakeupAlarms; 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case AlarmManager.RTC: return mRtcAlarms; 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case AlarmManager.ELAPSED_REALTIME_WAKEUP: return mElapsedRealtimeWakeupAlarms; 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case AlarmManager.ELAPSED_REALTIME: return mElapsedRealtimeAlarms; 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int addAlarmLocked(Alarm alarm) { 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Alarm> alarmList = getAlarmList(alarm.type); 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index = Collections.binarySearch(alarmList, alarm, mIncreasingTimeOrder); 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (index < 0) { 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index = 0 - index - 1; 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3988a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, "Adding alarm " + alarm + " at " + index); 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarmList.add(index, alarm); 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (localLOGV) { 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Display the list of alarms for this alarm type 4038a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "alarms: " + alarmList.size() + " type: " + alarm.type); 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int position = 0; 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Alarm a : alarmList) { 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Time time = new Time(); 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project time.set(a.when); 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String timeStr = time.format("%b %d %I:%M:%S %p"); 4098a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, position + ": " + timeStr 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " " + a.operation.getTargetPackage()); 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project position += 1; 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return index; 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long timeToNextAlarm() { 41911c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown long nextAlarm = Long.MAX_VALUE; 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=AlarmManager.RTC_WAKEUP; 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i<=AlarmManager.ELAPSED_REALTIME; i++) { 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Alarm> alarmList = getAlarmList(i); 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarmList.size() > 0) { 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm a = alarmList.get(0); 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (a.when < nextAlarm) { 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nextAlarm = a.when; 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return nextAlarm; 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void setLocked(Alarm alarm) 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDescriptor != -1) 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 43911c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown // The kernel never triggers alarms with negative wakeup times 44011c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown // so we ensure they are positive. 44111c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown long alarmSeconds, alarmNanoseconds; 44211c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown if (alarm.when < 0) { 44311c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown alarmSeconds = 0; 44411c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown alarmNanoseconds = 0; 44511c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown } else { 44611c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown alarmSeconds = alarm.when / 1000; 44711c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown alarmNanoseconds = (alarm.when % 1000) * 1000 * 1000; 44811c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown } 44911c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown 45011c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown set(mDescriptor, alarm.type, alarmSeconds, alarmNanoseconds); 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message msg = Message.obtain(); 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.what = ALARM_EVENT; 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.removeMessages(ALARM_EVENT); 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.sendMessageAtTime(msg, alarm.when); 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED) { 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println("Permission Denial: can't dump AlarmManager from from pid=" 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Binder.getCallingPid() 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ", uid=" + Binder.getCallingUid()); 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println("Current Alarm Manager state:"); 4741d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn if (mRtcWakeupAlarms.size() > 0 || mRtcAlarms.size() > 0) { 475043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn final long now = System.currentTimeMillis(); 476043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" "); 4781d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" Realtime wakeup (now="); 479043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn pw.print(sdf.format(new Date(now))); pw.println("):"); 4801d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn if (mRtcWakeupAlarms.size() > 0) { 481043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn dumpAlarmList(pw, mRtcWakeupAlarms, " ", "RTC_WAKEUP", now); 4821d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn } 4831d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn if (mRtcAlarms.size() > 0) { 484043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn dumpAlarmList(pw, mRtcAlarms, " ", "RTC", now); 4851d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn } 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4871d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn if (mElapsedRealtimeWakeupAlarms.size() > 0 || mElapsedRealtimeAlarms.size() > 0) { 488043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn final long now = SystemClock.elapsedRealtime(); 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" "); 4901d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" Elapsed realtime wakeup (now="); 491043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn TimeUtils.formatDuration(now, pw); pw.println("):"); 4921d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn if (mElapsedRealtimeWakeupAlarms.size() > 0) { 493043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn dumpAlarmList(pw, mElapsedRealtimeWakeupAlarms, " ", "ELAPSED_WAKEUP", now); 4941d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn } 4951d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn if (mElapsedRealtimeAlarms.size() > 0) { 496043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn dumpAlarmList(pw, mElapsedRealtimeAlarms, " ", "ELAPSED", now); 4971d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn } 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" "); 5011d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" Broadcast ref count: "); pw.println(mBroadcastRefCount); 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" "); 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Alarm Stats:"); 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Map.Entry<String, BroadcastStats> be : mBroadcastStats.entrySet()) { 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BroadcastStats bs = be.getValue(); 5071d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" "); pw.println(be.getKey()); 5081d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" "); pw.print(bs.aggregateTime); 5091d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print("ms running, "); pw.print(bs.numWakeup); 5101d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.println(" wakeups"); 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Map.Entry<Intent.FilterComparison, FilterStats> fe 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : bs.filterStats.entrySet()) { 5131d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" "); pw.print(fe.getValue().count); 5141d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" alarms: "); 51521c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn pw.println(fe.getKey().getIntent().toShortString( 51621c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn false, true, false, true)); 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 522043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn private static final void dumpAlarmList(PrintWriter pw, ArrayList<Alarm> list, 523043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn String prefix, String label, long now) { 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=list.size()-1; i>=0; i--) { 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm a = list.get(i); 5261d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(prefix); pw.print(label); pw.print(" #"); pw.print(i); 5271d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(": "); pw.println(a); 528043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn a.dump(pw, prefix + " ", now); 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native int init(); 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void close(int fd); 53411c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown private native void set(int fd, int type, long seconds, long nanoseconds); 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native int waitForAlarm(int fd); 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native int setKernelTimezone(int fd, int minuteswest); 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void triggerAlarmsLocked(ArrayList<Alarm> alarmList, 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Alarm> triggerList, 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long now) 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Iterator<Alarm> it = alarmList.iterator(); 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Alarm> repeats = new ArrayList<Alarm>(); 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (it.hasNext()) 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm alarm = it.next(); 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5498a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, "Checking active alarm when=" + alarm.when + " " + alarm); 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.when > now) { 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // don't fire alarms in the future 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the alarm is late, then print a warning message. 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note that this can happen if the user creates a new event on 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the Calendar app with a reminder that is in the past. In that 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // case, the reminder alarm will fire immediately. 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (localLOGV && now - alarm.when > LATE_ALARM_THRESHOLD) { 5618a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "alarm is late! alarm time: " + alarm.when 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " now: " + now + " delay (in seconds): " 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + (now - alarm.when) / 1000); 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Recurring alarms may have passed several alarm intervals while the 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // phone was asleep or off, so pass a trigger count when sending them. 5688a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, "Alarm triggering: " + alarm); 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.count = 1; 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.repeatInterval > 0) { 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this adjustment will be zero if we're late by 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // less than one full repeat interval 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.count += (now - alarm.when) / alarm.repeatInterval; 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerList.add(alarm); 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // remove the alarm from the list 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project it.remove(); 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if it repeats queue it up to be read-added to the list 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.repeatInterval > 0) { 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project repeats.add(alarm); 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reset any repeating alarms. 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project it = repeats.iterator(); 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (it.hasNext()) { 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm alarm = it.next(); 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.when += alarm.count * alarm.repeatInterval; 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addAlarmLocked(alarm); 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarmList.size() > 0) { 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setLocked(alarmList.get(0)); 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This Comparator sorts Alarms into increasing time order. 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static class IncreasingTimeOrder implements Comparator<Alarm> { 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int compare(Alarm a1, Alarm a2) { 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long when1 = a1.when; 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long when2 = a2.when; 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (when1 - when2 > 0) { 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 1; 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (when1 - when2 < 0) { 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static class Alarm { 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int type; 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int count; 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long when; 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long repeatInterval; 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PendingIntent operation; 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Alarm() { 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project when = 0; 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project repeatInterval = 0; 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project operation = null; 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6321d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn StringBuilder sb = new StringBuilder(128); 6331d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn sb.append("Alarm{"); 6341d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn sb.append(Integer.toHexString(System.identityHashCode(this))); 6351d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn sb.append(" type "); 6361d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn sb.append(type); 6371d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn sb.append(" "); 6381d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn sb.append(operation.getTargetPackage()); 6391d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn sb.append('}'); 6401d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn return sb.toString(); 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 643043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn public void dump(PrintWriter pw, String prefix, long now) { 6441d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(prefix); pw.print("type="); pw.print(type); 645043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn pw.print(" when="); TimeUtils.formatDuration(when, now, pw); 6461d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" repeatInterval="); pw.print(repeatInterval); 6471d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" count="); pw.println(count); 6481d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(prefix); pw.print("operation="); pw.println(operation); 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class AlarmThread extends Thread 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AlarmThread() 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super("AlarmManager"); 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void run() 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (true) 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int result = waitForAlarm(mDescriptor); 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Alarm> triggerList = new ArrayList<Alarm>(); 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((result & TIME_CHANGED_MASK) != 0) { 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project remove(mTimeTickSender); 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mClockReceiver.scheduleTimeTickEvent(); 6701c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn Intent intent = new Intent(Intent.ACTION_TIME_CHANGED); 67189ba6750e5310c4da51786bd7eb559a43cab3982Dianne Hackborn intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING 67289ba6750e5310c4da51786bd7eb559a43cab3982Dianne Hackborn | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 6735ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long nowRTC = System.currentTimeMillis(); 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long nowELAPSED = SystemClock.elapsedRealtime(); 6798a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v( 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TAG, "Checking for alarms... rtc=" + nowRTC 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ", elapsed=" + nowELAPSED); 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((result & RTC_WAKEUP_MASK) != 0) 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mRtcWakeupAlarms, triggerList, nowRTC); 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((result & RTC_MASK) != 0) 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mRtcAlarms, triggerList, nowRTC); 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((result & ELAPSED_REALTIME_WAKEUP_MASK) != 0) 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mElapsedRealtimeWakeupAlarms, triggerList, nowELAPSED); 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((result & ELAPSED_REALTIME_MASK) != 0) 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mElapsedRealtimeAlarms, triggerList, nowELAPSED); 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // now trigger the alarms 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Iterator<Alarm> it = triggerList.iterator(); 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (it.hasNext()) { 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm alarm = it.next(); 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 7008a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, "sending alarm " + alarm); 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.operation.send(mContext, 0, 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBackgroundIntent.putExtra( 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent.EXTRA_ALARM_COUNT, alarm.count), 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mResultReceiver, mHandler); 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 706c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate // we have an active broadcast so stay awake. 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBroadcastRefCount == 0) { 708c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate setWakelockWorkSource(alarm.operation); 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWakeLock.acquire(); 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 711c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate mInFlight.add(alarm.operation); 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBroadcastRefCount++; 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BroadcastStats bs = getStatsLocked(alarm.operation); 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bs.nesting == 0) { 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bs.startTime = nowELAPSED; 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bs.nesting++; 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.type == AlarmManager.ELAPSED_REALTIME_WAKEUP 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || alarm.type == AlarmManager.RTC_WAKEUP) { 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bs.numWakeup++; 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ActivityManagerNative.noteWakeupAlarm( 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.operation); 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (PendingIntent.CanceledException e) { 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.repeatInterval > 0) { 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This IntentSender is no longer valid, but this 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // is a repeating alarm, so toss the hoser. 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project remove(alarm.operation); 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RuntimeException e) { 7338a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Failure sending alarm.", e); 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 740c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate 741c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate void setWakelockWorkSource(PendingIntent pi) { 742c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate try { 743c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate final int uid = ActivityManagerNative.getDefault() 744c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate .getUidForIntentSender(pi.getTarget()); 745c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate if (uid >= 0) { 746c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate mWakeLock.setWorkSource(new WorkSource(uid)); 747c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate return; 748c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate } 749c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate } catch (Exception e) { 750c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate } 751c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate 752c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate // Something went wrong; fall back to attributing the lock to the OS 753c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate mWakeLock.setWorkSource(null); 754c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate } 755c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class AlarmHandler extends Handler { 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int ALARM_EVENT = 1; 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int MINUTE_CHANGE_EVENT = 2; 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int DATE_CHANGE_EVENT = 3; 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AlarmHandler() { 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void handleMessage(Message msg) { 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (msg.what == ALARM_EVENT) { 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Alarm> triggerList = new ArrayList<Alarm>(); 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long nowRTC = System.currentTimeMillis(); 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mRtcWakeupAlarms, triggerList, nowRTC); 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mRtcAlarms, triggerList, nowRTC); 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mElapsedRealtimeWakeupAlarms, triggerList, nowRTC); 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mElapsedRealtimeAlarms, triggerList, nowRTC); 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // now trigger the alarms without the lock held 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Iterator<Alarm> it = triggerList.iterator(); 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (it.hasNext()) 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm alarm = it.next(); 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.operation.send(); 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (PendingIntent.CanceledException e) { 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.repeatInterval > 0) { 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This IntentSender is no longer valid, but this 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // is a repeating alarm, so toss the hoser. 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project remove(alarm.operation); 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class ClockReceiver extends BroadcastReceiver { 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ClockReceiver() { 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IntentFilter filter = new IntentFilter(); 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project filter.addAction(Intent.ACTION_TIME_TICK); 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project filter.addAction(Intent.ACTION_DATE_CHANGED); 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.registerReceiver(this, filter); 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onReceive(Context context, Intent intent) { 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (intent.getAction().equals(Intent.ACTION_TIME_TICK)) { 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scheduleTimeTickEvent(); 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (intent.getAction().equals(Intent.ACTION_DATE_CHANGED)) { 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Since the kernel does not keep track of DST, we need to 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reset the TZ information at the beginning of each day 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // based off of the current Zone gmt offset + userspace tracked 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // daylight savings information. 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TimeZone zone = TimeZone.getTimeZone(SystemProperties.get(TIMEZONE_PROPERTY)); 812c84cc4f183cb18f299bed237235fa64e013d0fcaLavettacn Xiao int gmtOffset = zone.getOffset(System.currentTimeMillis()); 813c84cc4f183cb18f299bed237235fa64e013d0fcaLavettacn Xiao setKernelTimezone(mDescriptor, -(gmtOffset / 60000)); 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scheduleDateChangedEvent(); 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void scheduleTimeTickEvent() { 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Calendar calendar = Calendar.getInstance(); 82051608a53040cd4bc3694dac2bf67dc18a4b5b235Paul Westbrook final long currentTime = System.currentTimeMillis(); 82151608a53040cd4bc3694dac2bf67dc18a4b5b235Paul Westbrook calendar.setTimeInMillis(currentTime); 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.add(Calendar.MINUTE, 1); 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.set(Calendar.SECOND, 0); 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.set(Calendar.MILLISECOND, 0); 82551608a53040cd4bc3694dac2bf67dc18a4b5b235Paul Westbrook 82651608a53040cd4bc3694dac2bf67dc18a4b5b235Paul Westbrook // Schedule this event for the amount of time that it would take to get to 82751608a53040cd4bc3694dac2bf67dc18a4b5b235Paul Westbrook // the top of the next minute. 82851608a53040cd4bc3694dac2bf67dc18a4b5b235Paul Westbrook final long tickEventDelay = calendar.getTimeInMillis() - currentTime; 82951608a53040cd4bc3694dac2bf67dc18a4b5b235Paul Westbrook 83051608a53040cd4bc3694dac2bf67dc18a4b5b235Paul Westbrook set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + tickEventDelay, 83151608a53040cd4bc3694dac2bf67dc18a4b5b235Paul Westbrook mTimeTickSender); 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void scheduleDateChangedEvent() { 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Calendar calendar = Calendar.getInstance(); 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.setTimeInMillis(System.currentTimeMillis()); 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.set(Calendar.HOUR, 0); 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.set(Calendar.MINUTE, 0); 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.set(Calendar.SECOND, 0); 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.set(Calendar.MILLISECOND, 0); 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.add(Calendar.DAY_OF_MONTH, 1); 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set(AlarmManager.RTC, calendar.getTimeInMillis(), mDateChangeSender); 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class UninstallReceiver extends BroadcastReceiver { 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public UninstallReceiver() { 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IntentFilter filter = new IntentFilter(); 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project filter.addAction(Intent.ACTION_PACKAGE_REMOVED); 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project filter.addAction(Intent.ACTION_PACKAGE_RESTARTED); 85221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn filter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project filter.addDataScheme("package"); 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.registerReceiver(this, filter); 85508675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu // Register for events related to sdcard installation. 85608675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu IntentFilter sdFilter = new IntentFilter(); 857b56ae20b22fd7283df32072a431ab6d4965f3c1bSuchi Amalapurapu sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); 85880a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn sdFilter.addAction(Intent.ACTION_USER_STOPPED); 85908675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu mContext.registerReceiver(this, sdFilter); 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onReceive(Context context, Intent intent) { 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 86508675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu String action = intent.getAction(); 86608675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu String pkgList[] = null; 86721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (Intent.ACTION_QUERY_PACKAGE_RESTART.equals(action)) { 86821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn pkgList = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 86921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn for (String packageName : pkgList) { 87021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (lookForPackageLocked(packageName)) { 87121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn setResultCode(Activity.RESULT_OK); 87221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return; 87321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 87421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 87521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return; 87621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) { 87708675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 87880a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn } else if (Intent.ACTION_USER_STOPPED.equals(action)) { 87980a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 88080a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn if (userHandle >= 0) { 88180a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn removeUserLocked(userHandle); 88280a4af2bbc6af42ae605e454bf89558e564f5244Dianne Hackborn } 88308675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } else { 884409578fcb1d8ecfee0ae07b1a34a6e6cb184a0ceDianne Hackborn if (Intent.ACTION_PACKAGE_REMOVED.equals(action) 885409578fcb1d8ecfee0ae07b1a34a6e6cb184a0ceDianne Hackborn && intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 886409578fcb1d8ecfee0ae07b1a34a6e6cb184a0ceDianne Hackborn // This package is being updated; don't kill its alarms. 887409578fcb1d8ecfee0ae07b1a34a6e6cb184a0ceDianne Hackborn return; 888409578fcb1d8ecfee0ae07b1a34a6e6cb184a0ceDianne Hackborn } 88908675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu Uri data = intent.getData(); 89008675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (data != null) { 89108675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu String pkg = data.getSchemeSpecificPart(); 89208675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (pkg != null) { 89308675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu pkgList = new String[]{pkg}; 89408675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 89508675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 89608675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 89708675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (pkgList != null && (pkgList.length > 0)) { 89808675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu for (String pkg : pkgList) { 89908675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu removeLocked(pkg); 90008675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu mBroadcastStats.remove(pkg); 90108675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final BroadcastStats getStatsLocked(PendingIntent pi) { 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String pkg = pi.getTargetPackage(); 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BroadcastStats bs = mBroadcastStats.get(pkg); 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bs == null) { 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bs = new BroadcastStats(); 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBroadcastStats.put(pkg, bs); 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return bs; 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class ResultReceiver implements PendingIntent.OnFinished { 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onSendFinished(PendingIntent pi, Intent intent, int resultCode, 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String resultData, Bundle resultExtras) { 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BroadcastStats bs = getStatsLocked(pi); 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bs != null) { 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bs.nesting--; 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bs.nesting <= 0) { 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bs.nesting = 0; 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bs.aggregateTime += SystemClock.elapsedRealtime() 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project - bs.startTime; 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent.FilterComparison fc = new Intent.FilterComparison(intent); 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FilterStats fs = bs.filterStats.get(fc); 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fs == null) { 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fs = new FilterStats(); 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bs.filterStats.put(fc, fs); 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fs.count++; 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 937c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate mInFlight.removeFirst(); 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBroadcastRefCount--; 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBroadcastRefCount == 0) { 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWakeLock.release(); 941c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate } else { 942c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate // the next of our alarms is now in flight. reattribute the wakelock. 943c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate final PendingIntent nowInFlight = mInFlight.peekFirst(); 944c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate if (nowInFlight != null) { 945c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate setWakelockWorkSource(nowInFlight); 946c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate } else { 947c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate // should never happen 948c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate Slog.e(TAG, "Alarm wakelock still held but sent queue empty"); 949c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate mWakeLock.setWorkSource(null); 950c4a07d1caa9befd4fa8165ff05fa5e92480d8e27Christopher Tate } 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 956