1 /*
2  * Copyright (C) 2007 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  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.deskclock;
18 
19 import android.annotation.SuppressLint;
20 import android.content.BroadcastReceiver;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.os.PowerManager.WakeLock;
24 
25 import com.android.deskclock.alarms.AlarmStateManager;
26 import com.android.deskclock.data.DataModel;
27 import com.android.deskclock.events.Events;
28 
29 public class AlarmInitReceiver extends BroadcastReceiver {
30 
31     /**
32      * When running on N devices, we're interested in the boot completed event that is sent while
33      * the user is still locked, so that we can schedule alarms.
34      */
35     @SuppressLint("InlinedApi")
36     private static final String ACTION_BOOT_COMPLETED = Utils.isNOrLater()
37             ? Intent.ACTION_LOCKED_BOOT_COMPLETED : Intent.ACTION_BOOT_COMPLETED;
38 
39     /**
40      * This receiver handles a variety of actions:
41      *
42      * <ul>
43      *     <li>Clean up backup data that was recently restored to this device on
44      *     ACTION_COMPLETE_RESTORE.</li>
45      *     <li>Reset timers and stopwatch on ACTION_BOOT_COMPLETED</li>
46      *     <li>Fix alarm states on ACTION_BOOT_COMPLETED, TIME_SET, TIMEZONE_CHANGED,
47      *     and LOCALE_CHANGED</li>
48      *     <li>Rebuild notifications on MY_PACKAGE_REPLACED</li>
49      * </ul>
50      */
51     @Override
onReceive(final Context context, Intent intent)52     public void onReceive(final Context context, Intent intent) {
53         final String action = intent.getAction();
54         LogUtils.i("AlarmInitReceiver " + action);
55 
56         final PendingResult result = goAsync();
57         final WakeLock wl = AlarmAlertWakeLock.createPartialWakeLock(context);
58         wl.acquire();
59 
60         // We need to increment the global id out of the async task to prevent race conditions
61         AlarmStateManager.updateGlobalIntentId(context);
62 
63         // Clear stopwatch data and reset timers because they rely on elapsed real-time values
64         // which are meaningless after a device reboot.
65         if (ACTION_BOOT_COMPLETED.equals(action)) {
66             DataModel.getDataModel().clearLaps();
67             DataModel.getDataModel().resetStopwatch();
68             Events.sendStopwatchEvent(R.string.action_reset, R.string.label_reboot);
69             DataModel.getDataModel().resetTimers(R.string.label_reboot);
70         }
71 
72         // Notifications are canceled by the system on application upgrade. This broadcast signals
73         // that the new app is free to rebuild the notifications using the existing data.
74         if (Intent.ACTION_MY_PACKAGE_REPLACED.equals(action)) {
75             DataModel.getDataModel().updateAllNotifications();
76         }
77 
78         AsyncHandler.post(new Runnable() {
79             @Override
80             public void run() {
81                 try {
82                     // Process restored data if any exists
83                     if (!DeskClockBackupAgent.processRestoredData(context)) {
84                         // Update all the alarm instances on time change event
85                         AlarmStateManager.fixAlarmInstances(context);
86                     }
87                 } finally {
88                     result.finish();
89                     wl.release();
90                     LogUtils.v("AlarmInitReceiver finished");
91                 }
92             }
93         });
94     }
95 }
96