15fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project/* 25fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 35fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project * 45fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 55fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project * you may not use this file except in compliance with the License. 65fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project * You may obtain a copy of the License at 75fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project * 85fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 95fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project * 105fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 115fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 125fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project * See the License for the specific language governing permissions and 145fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project * limitations under the License. 155fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project */ 165fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project 17fa954248b41b567dfa2ddd7bd063d3936a51758eDaniel Sandlerpackage com.android.deskclock; 185fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project 19db9dff0ab3d3295cffdde9b9364ddb413f14ed9eJeff Sharkeyimport android.annotation.SuppressLint; 20de5f183f54b5d10bc8cbebb977c7c8ab391ad3f5Isaac Katzenelsonimport android.content.BroadcastReceiver; 215fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Projectimport android.content.Context; 225fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Projectimport android.content.Intent; 23df77f79bbf931894d91cd0d8334f204ff67e903aPatrick Scottimport android.os.PowerManager.WakeLock; 24de5f183f54b5d10bc8cbebb977c7c8ab391ad3f5Isaac Katzenelson 25ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowskiimport com.android.deskclock.alarms.AlarmStateManager; 2624a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieuximport com.android.deskclock.data.DataModel; 276d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieuximport com.android.deskclock.events.Events; 285fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project 295fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Projectpublic class AlarmInitReceiver extends BroadcastReceiver { 30079dc3af583995b1fcbd84534f73feaf10adb596Justin Klaassen 31079dc3af583995b1fcbd84534f73feaf10adb596Justin Klaassen /** 32079dc3af583995b1fcbd84534f73feaf10adb596Justin Klaassen * When running on N devices, we're interested in the boot completed event that is sent while 33079dc3af583995b1fcbd84534f73feaf10adb596Justin Klaassen * the user is still locked, so that we can schedule alarms. 34079dc3af583995b1fcbd84534f73feaf10adb596Justin Klaassen */ 35079dc3af583995b1fcbd84534f73feaf10adb596Justin Klaassen @SuppressLint("InlinedApi") 36079dc3af583995b1fcbd84534f73feaf10adb596Justin Klaassen private static final String ACTION_BOOT_COMPLETED = Utils.isNOrLater() 37079dc3af583995b1fcbd84534f73feaf10adb596Justin Klaassen ? Intent.ACTION_LOCKED_BOOT_COMPLETED : Intent.ACTION_BOOT_COMPLETED; 38079dc3af583995b1fcbd84534f73feaf10adb596Justin Klaassen 395fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project /** 4032e2e0440cc4219dfe200bcf025508b740ec7cb1James Lemieux * This receiver handles a variety of actions: 4132e2e0440cc4219dfe200bcf025508b740ec7cb1James Lemieux * 4232e2e0440cc4219dfe200bcf025508b740ec7cb1James Lemieux * <ul> 4332e2e0440cc4219dfe200bcf025508b740ec7cb1James Lemieux * <li>Clean up backup data that was recently restored to this device on 4432e2e0440cc4219dfe200bcf025508b740ec7cb1James Lemieux * ACTION_COMPLETE_RESTORE.</li> 456d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux * <li>Reset timers and stopwatch on ACTION_BOOT_COMPLETED</li> 4632e2e0440cc4219dfe200bcf025508b740ec7cb1James Lemieux * <li>Fix alarm states on ACTION_BOOT_COMPLETED, TIME_SET, TIMEZONE_CHANGED, 4732e2e0440cc4219dfe200bcf025508b740ec7cb1James Lemieux * and LOCALE_CHANGED</li> 48ac1506f175631e2b2f52ff9142cbdc6c725ef447James Lemieux * <li>Rebuild notifications on MY_PACKAGE_REPLACED</li> 4932e2e0440cc4219dfe200bcf025508b740ec7cb1James Lemieux * </ul> 505fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project */ 515fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project @Override 52df77f79bbf931894d91cd0d8334f204ff67e903aPatrick Scott public void onReceive(final Context context, Intent intent) { 53df77f79bbf931894d91cd0d8334f204ff67e903aPatrick Scott final String action = intent.getAction(); 5419abdb148ee0716b10b04df8ab02b4c780fab3eaAnnie Chin LogUtils.i("AlarmInitReceiver " + action); 555fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project 56df77f79bbf931894d91cd0d8334f204ff67e903aPatrick Scott final PendingResult result = goAsync(); 57df77f79bbf931894d91cd0d8334f204ff67e903aPatrick Scott final WakeLock wl = AlarmAlertWakeLock.createPartialWakeLock(context); 58df77f79bbf931894d91cd0d8334f204ff67e903aPatrick Scott wl.acquire(); 5925b9df53e993ee775c4733e61b8fef2aa358ef70Paul Sliwowski 6032e2e0440cc4219dfe200bcf025508b740ec7cb1James Lemieux // We need to increment the global id out of the async task to prevent race conditions 61b4aacfb276d66f2bf02691e56d0d20fe6bab31a4Budi Kusmiantoro AlarmStateManager.updateGlobalIntentId(context); 6232e2e0440cc4219dfe200bcf025508b740ec7cb1James Lemieux 636d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux // Clear stopwatch data and reset timers because they rely on elapsed real-time values 646d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux // which are meaningless after a device reboot. 65079dc3af583995b1fcbd84534f73feaf10adb596Justin Klaassen if (ACTION_BOOT_COMPLETED.equals(action)) { 6624a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux DataModel.getDataModel().clearLaps(); 6724a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux DataModel.getDataModel().resetStopwatch(); 686d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux Events.sendStopwatchEvent(R.string.action_reset, R.string.label_reboot); 696d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux DataModel.getDataModel().resetTimers(R.string.label_reboot); 7024a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux } 7124a54fc16fdf95ee3f76ab99978c3401473dc516James Lemieux 72ac1506f175631e2b2f52ff9142cbdc6c725ef447James Lemieux // Notifications are canceled by the system on application upgrade. This broadcast signals 73ac1506f175631e2b2f52ff9142cbdc6c725ef447James Lemieux // that the new app is free to rebuild the notifications using the existing data. 74ac1506f175631e2b2f52ff9142cbdc6c725ef447James Lemieux if (Intent.ACTION_MY_PACKAGE_REPLACED.equals(action)) { 75ac1506f175631e2b2f52ff9142cbdc6c725ef447James Lemieux DataModel.getDataModel().updateAllNotifications(); 76ac1506f175631e2b2f52ff9142cbdc6c725ef447James Lemieux } 77ac1506f175631e2b2f52ff9142cbdc6c725ef447James Lemieux 78df77f79bbf931894d91cd0d8334f204ff67e903aPatrick Scott AsyncHandler.post(new Runnable() { 796d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux @Override 806d603b7c62bb38d763a681a8bf20fadb1442e833James Lemieux public void run() { 8132e2e0440cc4219dfe200bcf025508b740ec7cb1James Lemieux try { 8232e2e0440cc4219dfe200bcf025508b740ec7cb1James Lemieux // Process restored data if any exists 8332e2e0440cc4219dfe200bcf025508b740ec7cb1James Lemieux if (!DeskClockBackupAgent.processRestoredData(context)) { 8432e2e0440cc4219dfe200bcf025508b740ec7cb1James Lemieux // Update all the alarm instances on time change event 8532e2e0440cc4219dfe200bcf025508b740ec7cb1James Lemieux AlarmStateManager.fixAlarmInstances(context); 8632e2e0440cc4219dfe200bcf025508b740ec7cb1James Lemieux } 8732e2e0440cc4219dfe200bcf025508b740ec7cb1James Lemieux } finally { 8832e2e0440cc4219dfe200bcf025508b740ec7cb1James Lemieux result.finish(); 8932e2e0440cc4219dfe200bcf025508b740ec7cb1James Lemieux wl.release(); 9032e2e0440cc4219dfe200bcf025508b740ec7cb1James Lemieux LogUtils.v("AlarmInitReceiver finished"); 9132e2e0440cc4219dfe200bcf025508b740ec7cb1James Lemieux } 92df77f79bbf931894d91cd0d8334f204ff67e903aPatrick Scott } 93df77f79bbf931894d91cd0d8334f204ff67e903aPatrick Scott }); 945fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project } 95db9dff0ab3d3295cffdde9b9364ddb413f14ed9eJeff Sharkey} 96