AlarmManagerService.java revision c84cc4f183cb18f299bed237235fa64e013d0fca
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; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextUtils; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.format.Time; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.EventLog; 408a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog; 41043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackbornimport android.util.TimeUtils; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.PrintWriter; 45043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackbornimport java.text.SimpleDateFormat; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Calendar; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Collections; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Comparator; 501f7b4134db07acbb429cd770441ff460fa6f4b1bMike Lockwoodimport java.util.Date; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.HashMap; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Iterator; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Map; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.TimeZone; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass AlarmManagerService extends IAlarmManager.Stub { 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The threshold for how long an alarm can be late before we print a 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // warning message. The time duration is in milliseconds. 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final long LATE_ALARM_THRESHOLD = 10 * 1000; 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int RTC_WAKEUP_MASK = 1 << AlarmManager.RTC_WAKEUP; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int RTC_MASK = 1 << AlarmManager.RTC; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int ELAPSED_REALTIME_WAKEUP_MASK = 1 << AlarmManager.ELAPSED_REALTIME_WAKEUP; 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int ELAPSED_REALTIME_MASK = 1 << AlarmManager.ELAPSED_REALTIME; 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int TIME_CHANGED_MASK = 1 << 16; 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "AlarmManager"; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String ClockReceiver_TAG = "ClockReceiver"; 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final boolean localLOGV = false; 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int ALARM_EVENT = 1; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TIMEZONE_PROPERTY = "persist.sys.timezone"; 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final Intent mBackgroundIntent 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = new Intent().addFlags(Intent.FLAG_FROM_BACKGROUND); 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Context mContext; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Object mLock = new Object(); 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final ArrayList<Alarm> mRtcWakeupAlarms = new ArrayList<Alarm>(); 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final ArrayList<Alarm> mRtcAlarms = new ArrayList<Alarm>(); 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final ArrayList<Alarm> mElapsedRealtimeWakeupAlarms = new ArrayList<Alarm>(); 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final ArrayList<Alarm> mElapsedRealtimeAlarms = new ArrayList<Alarm>(); 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final IncreasingTimeOrder mIncreasingTimeOrder = new IncreasingTimeOrder(); 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // slots corresponding with the inexact-repeat interval buckets, 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // ordered from shortest to longest 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final long sInexactSlotIntervals[] = { 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AlarmManager.INTERVAL_FIFTEEN_MINUTES, 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AlarmManager.INTERVAL_HALF_HOUR, 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AlarmManager.INTERVAL_HOUR, 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AlarmManager.INTERVAL_HALF_DAY, 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AlarmManager.INTERVAL_DAY 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mInexactDeliveryTimes[] = { 0, 0, 0, 0, 0}; 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mDescriptor; 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mBroadcastRefCount = 0; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private PowerManager.WakeLock mWakeLock; 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final AlarmThread mWaitThread = new AlarmThread(); 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final AlarmHandler mHandler = new AlarmHandler(); 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ClockReceiver mClockReceiver; 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private UninstallReceiver mUninstallReceiver; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final ResultReceiver mResultReceiver = new ResultReceiver(); 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final PendingIntent mTimeTickSender; 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final PendingIntent mDateChangeSender; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final class FilterStats { 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int count; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final class BroadcastStats { 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long aggregateTime; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int numWakeup; 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long startTime; 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int nesting; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project HashMap<Intent.FilterComparison, FilterStats> filterStats 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = new HashMap<Intent.FilterComparison, FilterStats>(); 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final HashMap<String, BroadcastStats> mBroadcastStats 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = new HashMap<String, BroadcastStats>(); 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AlarmManagerService(Context context) { 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDescriptor = init(); 12764ba8e4038ade025da5e02f882219432d6bf1016Robert CH Chou 12864ba8e4038ade025da5e02f882219432d6bf1016Robert CH Chou // We have to set current TimeZone info to kernel 12964ba8e4038ade025da5e02f882219432d6bf1016Robert CH Chou // because kernel doesn't keep this after reboot 13064ba8e4038ade025da5e02f882219432d6bf1016Robert CH Chou String tz = SystemProperties.get(TIMEZONE_PROPERTY); 13164ba8e4038ade025da5e02f882219432d6bf1016Robert CH Chou if (tz != null) { 13264ba8e4038ade025da5e02f882219432d6bf1016Robert CH Chou setTimeZone(tz); 13364ba8e4038ade025da5e02f882219432d6bf1016Robert CH Chou } 13464ba8e4038ade025da5e02f882219432d6bf1016Robert CH Chou 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTimeTickSender = PendingIntent.getBroadcast(context, 0, 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new Intent(Intent.ACTION_TIME_TICK).addFlags( 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent.FLAG_RECEIVER_REGISTERED_ONLY), 0); 1411c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn Intent intent = new Intent(Intent.ACTION_DATE_CHANGED); 1421c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 1431c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn mDateChangeSender = PendingIntent.getBroadcast(context, 0, intent, 0); 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // now that we have initied the driver schedule the alarm 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mClockReceiver= new ClockReceiver(); 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mClockReceiver.scheduleTimeTickEvent(); 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mClockReceiver.scheduleDateChangedEvent(); 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUninstallReceiver = new UninstallReceiver(); 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDescriptor != -1) { 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWaitThread.start(); 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1548a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Failed to open alarm driver. Falling back to a handler."); 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() throws Throwable { 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(mDescriptor); 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.finalize(); 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void set(int type, long triggerAtTime, PendingIntent operation) { 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setRepeating(type, triggerAtTime, 0, operation); 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setRepeating(int type, long triggerAtTime, long interval, 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PendingIntent operation) { 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (operation == null) { 1738a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "set/setRepeating ignored because there is no intent"); 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm alarm = new Alarm(); 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.type = type; 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.when = triggerAtTime; 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.repeatInterval = interval; 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.operation = operation; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remove this alarm if already scheduled. 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(operation); 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1868a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, "set: " + alarm); 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index = addAlarmLocked(alarm); 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (index == 0) { 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setLocked(alarm); 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setInexactRepeating(int type, long triggerAtTime, long interval, 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PendingIntent operation) { 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (operation == null) { 1988a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "setInexactRepeating ignored because there is no intent"); 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // find the slot in the delivery-times array that we will use 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int intervalSlot; 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (intervalSlot = 0; intervalSlot < sInexactSlotIntervals.length; intervalSlot++) { 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sInexactSlotIntervals[intervalSlot] == interval) { 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Non-bucket intervals just fall back to the less-efficient 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // unbucketed recurring alarm implementation 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (intervalSlot >= sInexactSlotIntervals.length) { 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setRepeating(type, triggerAtTime, interval, operation); 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Align bucketed alarm deliveries by trying to match 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the shortest-interval bucket already scheduled 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long bucketTime = 0; 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int slot = 0; slot < mInexactDeliveryTimes.length; slot++) { 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mInexactDeliveryTimes[slot] > 0) { 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bucketTime = mInexactDeliveryTimes[slot]; 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bucketTime == 0) { 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If nothing is scheduled yet, just start at the requested time 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bucketTime = triggerAtTime; 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Align the new alarm with the existing bucketed sequence. To achieve 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // alignment, we slide the start time around by min{interval, slot interval} 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long adjustment = (interval <= sInexactSlotIntervals[intervalSlot]) 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ? interval : sInexactSlotIntervals[intervalSlot]; 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The bucket may have started in the past; adjust 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (bucketTime < triggerAtTime) { 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bucketTime += adjustment; 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Or the bucket may be set to start more than an interval beyond 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // our requested trigger time; pull it back to meet our needs 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (bucketTime > triggerAtTime + adjustment) { 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bucketTime -= adjustment; 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remember where this bucket started (reducing the amount of later 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // fixup required) and set the alarm with the new, bucketed start time. 2508a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, "setInexactRepeating: interval=" + interval 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " bucketTime=" + bucketTime); 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mInexactDeliveryTimes[intervalSlot] = bucketTime; 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setRepeating(type, bucketTime, interval, operation); 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25697e44947282b3918ee0bed2d16b33b983f882580Dan Egnor public void setTime(long millis) { 25797e44947282b3918ee0bed2d16b33b983f882580Dan Egnor mContext.enforceCallingOrSelfPermission( 25897e44947282b3918ee0bed2d16b33b983f882580Dan Egnor "android.permission.SET_TIME", 25997e44947282b3918ee0bed2d16b33b983f882580Dan Egnor "setTime"); 26097e44947282b3918ee0bed2d16b33b983f882580Dan Egnor 26197e44947282b3918ee0bed2d16b33b983f882580Dan Egnor SystemClock.setCurrentTimeMillis(millis); 26297e44947282b3918ee0bed2d16b33b983f882580Dan Egnor } 26397e44947282b3918ee0bed2d16b33b983f882580Dan Egnor 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTimeZone(String tz) { 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.enforceCallingOrSelfPermission( 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.permission.SET_TIME_ZONE", 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "setTimeZone"); 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (TextUtils.isEmpty(tz)) return; 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TimeZone zone = TimeZone.getTimeZone(tz); 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Prevent reentrant calls from stepping on each other when writing 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the time zone property 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean timeZoneWasChanged = false; 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String current = SystemProperties.get(TIMEZONE_PROPERTY); 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (current == null || !current.equals(zone.getID())) { 2778a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, "timezone changed: " + current + ", new=" + zone.getID()); 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project timeZoneWasChanged = true; 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SystemProperties.set(TIMEZONE_PROPERTY, zone.getID()); 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Update the kernel timezone information 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Kernel tracks time offsets as 'minutes west of GMT' 284c84cc4f183cb18f299bed237235fa64e013d0fcaLavettacn Xiao int gmtOffset = zone.getOffset(System.currentTimeMillis()); 2851f7b4134db07acbb429cd770441ff460fa6f4b1bMike Lockwood setKernelTimezone(mDescriptor, -(gmtOffset / 60000)); 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TimeZone.setDefault(null); 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (timeZoneWasChanged) { 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(Intent.ACTION_TIMEZONE_CHANGED); 2921c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra("time-zone", zone.getID()); 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void remove(PendingIntent operation) { 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (operation == null) { 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(operation); 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeLocked(PendingIntent operation) { 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mRtcWakeupAlarms, operation); 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mRtcAlarms, operation); 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mElapsedRealtimeWakeupAlarms, operation); 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mElapsedRealtimeAlarms, operation); 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void removeLocked(ArrayList<Alarm> alarmList, 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PendingIntent operation) { 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarmList.size() <= 0) { 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // iterator over the list removing any it where the intent match 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Iterator<Alarm> it = alarmList.iterator(); 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (it.hasNext()) { 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm alarm = it.next(); 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.operation.equals(operation)) { 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project it.remove(); 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeLocked(String packageName) { 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mRtcWakeupAlarms, packageName); 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mRtcAlarms, packageName); 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mElapsedRealtimeWakeupAlarms, packageName); 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeLocked(mElapsedRealtimeAlarms, packageName); 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void removeLocked(ArrayList<Alarm> alarmList, 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String packageName) { 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarmList.size() <= 0) { 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // iterator over the list removing any it where the intent match 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Iterator<Alarm> it = alarmList.iterator(); 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (it.hasNext()) { 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm alarm = it.next(); 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.operation.getTargetPackage().equals(packageName)) { 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project it.remove(); 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 35521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn public boolean lookForPackageLocked(String packageName) { 35621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return lookForPackageLocked(mRtcWakeupAlarms, packageName) 35721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn || lookForPackageLocked(mRtcAlarms, packageName) 35821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn || lookForPackageLocked(mElapsedRealtimeWakeupAlarms, packageName) 35921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn || lookForPackageLocked(mElapsedRealtimeAlarms, packageName); 36021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 36121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 36221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn private boolean lookForPackageLocked(ArrayList<Alarm> alarmList, String packageName) { 36321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn for (int i=alarmList.size()-1; i>=0; i--) { 36421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (alarmList.get(i).operation.getTargetPackage().equals(packageName)) { 36521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return true; 36621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 36721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 36821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return false; 36921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 37021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ArrayList<Alarm> getAlarmList(int type) { 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (type) { 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case AlarmManager.RTC_WAKEUP: return mRtcWakeupAlarms; 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case AlarmManager.RTC: return mRtcAlarms; 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case AlarmManager.ELAPSED_REALTIME_WAKEUP: return mElapsedRealtimeWakeupAlarms; 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case AlarmManager.ELAPSED_REALTIME: return mElapsedRealtimeAlarms; 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int addAlarmLocked(Alarm alarm) { 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Alarm> alarmList = getAlarmList(alarm.type); 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index = Collections.binarySearch(alarmList, alarm, mIncreasingTimeOrder); 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (index < 0) { 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index = 0 - index - 1; 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3898a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, "Adding alarm " + alarm + " at " + index); 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarmList.add(index, alarm); 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (localLOGV) { 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Display the list of alarms for this alarm type 3948a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "alarms: " + alarmList.size() + " type: " + alarm.type); 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int position = 0; 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Alarm a : alarmList) { 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Time time = new Time(); 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project time.set(a.when); 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String timeStr = time.format("%b %d %I:%M:%S %p"); 4008a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, position + ": " + timeStr 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " " + a.operation.getTargetPackage()); 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project position += 1; 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return index; 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long timeToNextAlarm() { 41011c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown long nextAlarm = Long.MAX_VALUE; 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=AlarmManager.RTC_WAKEUP; 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i<=AlarmManager.ELAPSED_REALTIME; i++) { 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Alarm> alarmList = getAlarmList(i); 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarmList.size() > 0) { 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm a = alarmList.get(0); 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (a.when < nextAlarm) { 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nextAlarm = a.when; 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return nextAlarm; 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void setLocked(Alarm alarm) 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDescriptor != -1) 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 43011c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown // The kernel never triggers alarms with negative wakeup times 43111c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown // so we ensure they are positive. 43211c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown long alarmSeconds, alarmNanoseconds; 43311c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown if (alarm.when < 0) { 43411c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown alarmSeconds = 0; 43511c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown alarmNanoseconds = 0; 43611c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown } else { 43711c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown alarmSeconds = alarm.when / 1000; 43811c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown alarmNanoseconds = (alarm.when % 1000) * 1000 * 1000; 43911c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown } 44011c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown 44111c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown set(mDescriptor, alarm.type, alarmSeconds, alarmNanoseconds); 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message msg = Message.obtain(); 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.what = ALARM_EVENT; 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.removeMessages(ALARM_EVENT); 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.sendMessageAtTime(msg, alarm.when); 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED) { 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println("Permission Denial: can't dump AlarmManager from from pid=" 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Binder.getCallingPid() 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ", uid=" + Binder.getCallingUid()); 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println("Current Alarm Manager state:"); 4651d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn if (mRtcWakeupAlarms.size() > 0 || mRtcAlarms.size() > 0) { 466043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn final long now = System.currentTimeMillis(); 467043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" "); 4691d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" Realtime wakeup (now="); 470043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn pw.print(sdf.format(new Date(now))); pw.println("):"); 4711d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn if (mRtcWakeupAlarms.size() > 0) { 472043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn dumpAlarmList(pw, mRtcWakeupAlarms, " ", "RTC_WAKEUP", now); 4731d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn } 4741d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn if (mRtcAlarms.size() > 0) { 475043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn dumpAlarmList(pw, mRtcAlarms, " ", "RTC", now); 4761d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn } 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4781d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn if (mElapsedRealtimeWakeupAlarms.size() > 0 || mElapsedRealtimeAlarms.size() > 0) { 479043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn final long now = SystemClock.elapsedRealtime(); 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" "); 4811d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" Elapsed realtime wakeup (now="); 482043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn TimeUtils.formatDuration(now, pw); pw.println("):"); 4831d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn if (mElapsedRealtimeWakeupAlarms.size() > 0) { 484043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn dumpAlarmList(pw, mElapsedRealtimeWakeupAlarms, " ", "ELAPSED_WAKEUP", now); 4851d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn } 4861d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn if (mElapsedRealtimeAlarms.size() > 0) { 487043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn dumpAlarmList(pw, mElapsedRealtimeAlarms, " ", "ELAPSED", now); 4881d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn } 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" "); 4921d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" Broadcast ref count: "); pw.println(mBroadcastRefCount); 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" "); 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Alarm Stats:"); 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Map.Entry<String, BroadcastStats> be : mBroadcastStats.entrySet()) { 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BroadcastStats bs = be.getValue(); 4981d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" "); pw.println(be.getKey()); 4991d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" "); pw.print(bs.aggregateTime); 5001d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print("ms running, "); pw.print(bs.numWakeup); 5011d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.println(" wakeups"); 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Map.Entry<Intent.FilterComparison, FilterStats> fe 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : bs.filterStats.entrySet()) { 5041d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" "); pw.print(fe.getValue().count); 5051d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" alarms: "); 5061d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.println(fe.getKey().getIntent().toShortString(true, false)); 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 512043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn private static final void dumpAlarmList(PrintWriter pw, ArrayList<Alarm> list, 513043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn String prefix, String label, long now) { 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=list.size()-1; i>=0; i--) { 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm a = list.get(i); 5161d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(prefix); pw.print(label); pw.print(" #"); pw.print(i); 5171d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(": "); pw.println(a); 518043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn a.dump(pw, prefix + " ", now); 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native int init(); 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void close(int fd); 52411c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown private native void set(int fd, int type, long seconds, long nanoseconds); 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native int waitForAlarm(int fd); 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native int setKernelTimezone(int fd, int minuteswest); 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void triggerAlarmsLocked(ArrayList<Alarm> alarmList, 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Alarm> triggerList, 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long now) 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Iterator<Alarm> it = alarmList.iterator(); 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Alarm> repeats = new ArrayList<Alarm>(); 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (it.hasNext()) 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm alarm = it.next(); 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5398a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, "Checking active alarm when=" + alarm.when + " " + alarm); 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.when > now) { 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // don't fire alarms in the future 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the alarm is late, then print a warning message. 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note that this can happen if the user creates a new event on 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the Calendar app with a reminder that is in the past. In that 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // case, the reminder alarm will fire immediately. 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (localLOGV && now - alarm.when > LATE_ALARM_THRESHOLD) { 5518a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "alarm is late! alarm time: " + alarm.when 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " now: " + now + " delay (in seconds): " 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + (now - alarm.when) / 1000); 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Recurring alarms may have passed several alarm intervals while the 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // phone was asleep or off, so pass a trigger count when sending them. 5588a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, "Alarm triggering: " + alarm); 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.count = 1; 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.repeatInterval > 0) { 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this adjustment will be zero if we're late by 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // less than one full repeat interval 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.count += (now - alarm.when) / alarm.repeatInterval; 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerList.add(alarm); 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // remove the alarm from the list 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project it.remove(); 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if it repeats queue it up to be read-added to the list 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.repeatInterval > 0) { 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project repeats.add(alarm); 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reset any repeating alarms. 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project it = repeats.iterator(); 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (it.hasNext()) { 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm alarm = it.next(); 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.when += alarm.count * alarm.repeatInterval; 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addAlarmLocked(alarm); 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarmList.size() > 0) { 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setLocked(alarmList.get(0)); 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This Comparator sorts Alarms into increasing time order. 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static class IncreasingTimeOrder implements Comparator<Alarm> { 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int compare(Alarm a1, Alarm a2) { 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long when1 = a1.when; 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long when2 = a2.when; 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (when1 - when2 > 0) { 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 1; 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (when1 - when2 < 0) { 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static class Alarm { 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int type; 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int count; 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long when; 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long repeatInterval; 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PendingIntent operation; 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Alarm() { 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project when = 0; 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project repeatInterval = 0; 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project operation = null; 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6221d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn StringBuilder sb = new StringBuilder(128); 6231d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn sb.append("Alarm{"); 6241d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn sb.append(Integer.toHexString(System.identityHashCode(this))); 6251d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn sb.append(" type "); 6261d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn sb.append(type); 6271d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn sb.append(" "); 6281d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn sb.append(operation.getTargetPackage()); 6291d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn sb.append('}'); 6301d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn return sb.toString(); 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 633043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn public void dump(PrintWriter pw, String prefix, long now) { 6341d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(prefix); pw.print("type="); pw.print(type); 635043fcd9847a804bc6394728e5785aecc495e6347Dianne Hackborn pw.print(" when="); TimeUtils.formatDuration(when, now, pw); 6361d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" repeatInterval="); pw.print(repeatInterval); 6371d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(" count="); pw.println(count); 6381d442e0d990b581357f33f5463c7c5cb49b551e8Dianne Hackborn pw.print(prefix); pw.print("operation="); pw.println(operation); 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class AlarmThread extends Thread 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AlarmThread() 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super("AlarmManager"); 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void run() 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (true) 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int result = waitForAlarm(mDescriptor); 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Alarm> triggerList = new ArrayList<Alarm>(); 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((result & TIME_CHANGED_MASK) != 0) { 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project remove(mTimeTickSender); 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mClockReceiver.scheduleTimeTickEvent(); 6601c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn Intent intent = new Intent(Intent.ACTION_TIME_CHANGED); 6611c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 6621c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn mContext.sendBroadcast(intent); 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long nowRTC = System.currentTimeMillis(); 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long nowELAPSED = SystemClock.elapsedRealtime(); 6688a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v( 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TAG, "Checking for alarms... rtc=" + nowRTC 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ", elapsed=" + nowELAPSED); 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((result & RTC_WAKEUP_MASK) != 0) 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mRtcWakeupAlarms, triggerList, nowRTC); 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((result & RTC_MASK) != 0) 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mRtcAlarms, triggerList, nowRTC); 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((result & ELAPSED_REALTIME_WAKEUP_MASK) != 0) 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mElapsedRealtimeWakeupAlarms, triggerList, nowELAPSED); 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((result & ELAPSED_REALTIME_MASK) != 0) 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mElapsedRealtimeAlarms, triggerList, nowELAPSED); 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // now trigger the alarms 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Iterator<Alarm> it = triggerList.iterator(); 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (it.hasNext()) { 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm alarm = it.next(); 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 6898a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (localLOGV) Slog.v(TAG, "sending alarm " + alarm); 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.operation.send(mContext, 0, 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBackgroundIntent.putExtra( 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent.EXTRA_ALARM_COUNT, alarm.count), 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mResultReceiver, mHandler); 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we have an active broadcast so stay awake. 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBroadcastRefCount == 0) { 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWakeLock.acquire(); 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBroadcastRefCount++; 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BroadcastStats bs = getStatsLocked(alarm.operation); 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bs.nesting == 0) { 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bs.startTime = nowELAPSED; 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bs.nesting++; 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.type == AlarmManager.ELAPSED_REALTIME_WAKEUP 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || alarm.type == AlarmManager.RTC_WAKEUP) { 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bs.numWakeup++; 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ActivityManagerNative.noteWakeupAlarm( 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.operation); 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (PendingIntent.CanceledException e) { 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.repeatInterval > 0) { 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This IntentSender is no longer valid, but this 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // is a repeating alarm, so toss the hoser. 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project remove(alarm.operation); 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RuntimeException e) { 7208a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Failure sending alarm.", e); 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class AlarmHandler extends Handler { 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int ALARM_EVENT = 1; 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int MINUTE_CHANGE_EVENT = 2; 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int DATE_CHANGE_EVENT = 3; 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AlarmHandler() { 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void handleMessage(Message msg) { 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (msg.what == ALARM_EVENT) { 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Alarm> triggerList = new ArrayList<Alarm>(); 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long nowRTC = System.currentTimeMillis(); 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mRtcWakeupAlarms, triggerList, nowRTC); 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mRtcAlarms, triggerList, nowRTC); 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mElapsedRealtimeWakeupAlarms, triggerList, nowRTC); 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project triggerAlarmsLocked(mElapsedRealtimeAlarms, triggerList, nowRTC); 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // now trigger the alarms without the lock held 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Iterator<Alarm> it = triggerList.iterator(); 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (it.hasNext()) 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Alarm alarm = it.next(); 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alarm.operation.send(); 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (PendingIntent.CanceledException e) { 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alarm.repeatInterval > 0) { 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This IntentSender is no longer valid, but this 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // is a repeating alarm, so toss the hoser. 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project remove(alarm.operation); 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class ClockReceiver extends BroadcastReceiver { 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ClockReceiver() { 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IntentFilter filter = new IntentFilter(); 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project filter.addAction(Intent.ACTION_TIME_TICK); 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project filter.addAction(Intent.ACTION_DATE_CHANGED); 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.registerReceiver(this, filter); 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onReceive(Context context, Intent intent) { 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (intent.getAction().equals(Intent.ACTION_TIME_TICK)) { 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scheduleTimeTickEvent(); 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (intent.getAction().equals(Intent.ACTION_DATE_CHANGED)) { 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Since the kernel does not keep track of DST, we need to 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reset the TZ information at the beginning of each day 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // based off of the current Zone gmt offset + userspace tracked 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // daylight savings information. 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TimeZone zone = TimeZone.getTimeZone(SystemProperties.get(TIMEZONE_PROPERTY)); 784c84cc4f183cb18f299bed237235fa64e013d0fcaLavettacn Xiao int gmtOffset = zone.getOffset(System.currentTimeMillis()); 785c84cc4f183cb18f299bed237235fa64e013d0fcaLavettacn Xiao setKernelTimezone(mDescriptor, -(gmtOffset / 60000)); 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scheduleDateChangedEvent(); 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void scheduleTimeTickEvent() { 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Calendar calendar = Calendar.getInstance(); 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.setTimeInMillis(System.currentTimeMillis()); 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.add(Calendar.MINUTE, 1); 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.set(Calendar.SECOND, 0); 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.set(Calendar.MILLISECOND, 0); 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set(AlarmManager.RTC, calendar.getTimeInMillis(), mTimeTickSender); 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void scheduleDateChangedEvent() { 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Calendar calendar = Calendar.getInstance(); 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.setTimeInMillis(System.currentTimeMillis()); 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.set(Calendar.HOUR, 0); 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.set(Calendar.MINUTE, 0); 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.set(Calendar.SECOND, 0); 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.set(Calendar.MILLISECOND, 0); 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project calendar.add(Calendar.DAY_OF_MONTH, 1); 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set(AlarmManager.RTC, calendar.getTimeInMillis(), mDateChangeSender); 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class UninstallReceiver extends BroadcastReceiver { 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public UninstallReceiver() { 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IntentFilter filter = new IntentFilter(); 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project filter.addAction(Intent.ACTION_PACKAGE_REMOVED); 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project filter.addAction(Intent.ACTION_PACKAGE_RESTARTED); 81821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn filter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project filter.addDataScheme("package"); 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.registerReceiver(this, filter); 82108675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu // Register for events related to sdcard installation. 82208675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu IntentFilter sdFilter = new IntentFilter(); 823b56ae20b22fd7283df32072a431ab6d4965f3c1bSuchi Amalapurapu sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); 82408675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu mContext.registerReceiver(this, sdFilter); 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onReceive(Context context, Intent intent) { 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 83008675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu String action = intent.getAction(); 83108675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu String pkgList[] = null; 83221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (Intent.ACTION_QUERY_PACKAGE_RESTART.equals(action)) { 83321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn pkgList = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 83421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn for (String packageName : pkgList) { 83521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (lookForPackageLocked(packageName)) { 83621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn setResultCode(Activity.RESULT_OK); 83721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return; 83821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 83921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 84021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return; 84121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) { 84208675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 84308675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } else { 844409578fcb1d8ecfee0ae07b1a34a6e6cb184a0ceDianne Hackborn if (Intent.ACTION_PACKAGE_REMOVED.equals(action) 845409578fcb1d8ecfee0ae07b1a34a6e6cb184a0ceDianne Hackborn && intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 846409578fcb1d8ecfee0ae07b1a34a6e6cb184a0ceDianne Hackborn // This package is being updated; don't kill its alarms. 847409578fcb1d8ecfee0ae07b1a34a6e6cb184a0ceDianne Hackborn return; 848409578fcb1d8ecfee0ae07b1a34a6e6cb184a0ceDianne Hackborn } 84908675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu Uri data = intent.getData(); 85008675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (data != null) { 85108675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu String pkg = data.getSchemeSpecificPart(); 85208675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (pkg != null) { 85308675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu pkgList = new String[]{pkg}; 85408675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 85508675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 85608675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 85708675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (pkgList != null && (pkgList.length > 0)) { 85808675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu for (String pkg : pkgList) { 85908675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu removeLocked(pkg); 86008675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu mBroadcastStats.remove(pkg); 86108675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final BroadcastStats getStatsLocked(PendingIntent pi) { 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String pkg = pi.getTargetPackage(); 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BroadcastStats bs = mBroadcastStats.get(pkg); 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bs == null) { 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bs = new BroadcastStats(); 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBroadcastStats.put(pkg, bs); 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return bs; 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class ResultReceiver implements PendingIntent.OnFinished { 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onSendFinished(PendingIntent pi, Intent intent, int resultCode, 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String resultData, Bundle resultExtras) { 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLock) { 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BroadcastStats bs = getStatsLocked(pi); 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bs != null) { 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bs.nesting--; 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bs.nesting <= 0) { 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bs.nesting = 0; 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bs.aggregateTime += SystemClock.elapsedRealtime() 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project - bs.startTime; 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent.FilterComparison fc = new Intent.FilterComparison(intent); 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FilterStats fs = bs.filterStats.get(fc); 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fs == null) { 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fs = new FilterStats(); 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bs.filterStats.put(fc, fs); 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fs.count++; 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBroadcastRefCount--; 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBroadcastRefCount == 0) { 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWakeLock.release(); 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 905