1/*
2** Copyright 2006, The Android Open Source Project
3**
4** Licensed under the Apache License, Version 2.0 (the "License");
5** you may not use this file except in compliance with the License.
6** You may obtain a copy of the License at
7**
8**     http://www.apache.org/licenses/LICENSE-2.0
9**
10** Unless required by applicable law or agreed to in writing, software
11** distributed under the License is distributed on an "AS IS" BASIS,
12** See the License for the specific language governing permissions and
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** limitations under the License.
15*/
16
17package com.android.providers.calendar;
18
19import android.content.BroadcastReceiver;
20import android.content.ContentResolver;
21import android.content.Context;
22import android.content.Intent;
23import android.os.PowerManager;
24import android.util.Log;
25
26import java.util.concurrent.ExecutorService;
27import java.util.concurrent.Executors;
28
29/**
30 * This IntentReceiver executes when the boot completes and ensures that
31 * the Calendar provider has started and then initializes the alarm
32 * scheduler for the Calendar provider.  This needs to be done after
33 * the boot completes because the alarm manager may not have been started
34 * yet.
35 */
36public class CalendarReceiver extends BroadcastReceiver {
37    private static final String TAG = "CalendarReceiver";
38    static final String SCHEDULE = "com.android.providers.calendar.SCHEDULE_ALARM";
39
40    private final ExecutorService executor = Executors.newCachedThreadPool();
41    private PowerManager.WakeLock mWakeLock;
42
43    @Override
44    public void onReceive(Context context, Intent intent) {
45        if (mWakeLock == null) {
46            PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
47            mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "CalendarReceiver_Provider");
48            mWakeLock.setReferenceCounted(true);
49        }
50        mWakeLock.acquire();
51
52        final String action = intent.getAction();
53        final ContentResolver cr = context.getContentResolver();
54        final PendingResult result = goAsync();
55        executor.submit(new Runnable() {
56            @Override
57            public void run() {
58                if (action.equals(SCHEDULE)) {
59                    cr.update(CalendarAlarmManager.SCHEDULE_ALARM_URI, null /* values */,
60                          null /* where */, null /* selectionArgs */);
61                } else if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
62                    removeScheduledAlarms(cr);
63                }
64                result.finish();
65                mWakeLock.release();
66            }
67        });
68    }
69
70    /*
71     * Remove alarms from the CalendarAlerts table that have been marked
72     * as "scheduled" but not fired yet.  We do this because the
73     * AlarmManagerService loses all information about alarms when the
74     * power turns off but we store the information in a database table
75     * that persists across reboots. See the documentation for
76     * scheduleNextAlarmLocked() for more information.
77     *
78     * We don't expect this to be called more than once.  If it were, we would have to
79     * worry about serializing the use of the service.
80     */
81    private void removeScheduledAlarms(ContentResolver resolver) {
82        if (Log.isLoggable(TAG, Log.DEBUG)) {
83            Log.d(TAG, "Removing scheduled alarms");
84        }
85        resolver.update(CalendarAlarmManager.SCHEDULE_ALARM_REMOVE_URI, null /* values */,
86                null /* where */, null /* selectionArgs */);
87    }
88}
89