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