Home | History | Annotate | Download | only in deskclock
      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.controller.Controller;
     27 import com.android.deskclock.data.DataModel;
     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
     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         DataModel.getDataModel().updateGlobalIntentId();
     62 
     63         // Updates stopwatch and timer data after a device reboot so they are as accurate as
     64         // possible.
     65         if (ACTION_BOOT_COMPLETED.equals(action)) {
     66             DataModel.getDataModel().updateAfterReboot();
     67             // Stopwatch and timer data need to be updated on time change so the reboot
     68             // functionality works as expected.
     69         } else if (Intent.ACTION_TIME_CHANGED.equals(action)) {
     70             DataModel.getDataModel().updateAfterTimeSet();
     71         }
     72 
     73         // Update shortcuts so they exist for the user.
     74         if (Intent.ACTION_BOOT_COMPLETED.equals(action)
     75                 || Intent.ACTION_LOCALE_CHANGED.equals(action)) {
     76             Controller.getController().updateShortcuts();
     77         }
     78 
     79         // Notifications are canceled by the system on application upgrade. This broadcast signals
     80         // that the new app is free to rebuild the notifications using the existing data.
     81         // Additionally on new app installs, make sure to enable shortcuts immediately as opposed
     82         // to waiting for system reboot.
     83         if (Intent.ACTION_MY_PACKAGE_REPLACED.equals(action)) {
     84             DataModel.getDataModel().updateAllNotifications();
     85             Controller.getController().updateShortcuts();
     86         }
     87 
     88         AsyncHandler.post(new Runnable() {
     89             @Override
     90             public void run() {
     91                 try {
     92                     // Process restored data if any exists
     93                     if (!DeskClockBackupAgent.processRestoredData(context)) {
     94                         // Update all the alarm instances on time change event
     95                         AlarmStateManager.fixAlarmInstances(context);
     96                     }
     97                 } finally {
     98                     result.finish();
     99                     wl.release();
    100                     LogUtils.v("AlarmInitReceiver finished");
    101                 }
    102             }
    103         });
    104     }
    105 }
    106