diff options
author | Jeff Hamilton <jham@android.com> | 2010-05-25 22:13:01 -0500 |
---|---|---|
committer | Jeff Hamilton <jham@android.com> | 2010-05-26 18:02:13 -0500 |
commit | 7109133e650b0b1a69690bda620e64893c027d95 (patch) | |
tree | 35651ddcd7bc91ea03bd326bb96840d8ba2aee22 | |
parent | 758a7562d72b0a6ed336beac508eedf7b369fa20 (diff) | |
download | android_packages_providers_ContactsProvider-7109133e650b0b1a69690bda620e64893c027d95.tar.gz android_packages_providers_ContactsProvider-7109133e650b0b1a69690bda620e64893c027d95.tar.bz2 android_packages_providers_ContactsProvider-7109133e650b0b1a69690bda620e64893c027d95.zip |
Add a PRE_BOOT_COMPLETED receiver.
It runs the first time after an OTA and either creates
the database or runs the upgrade path on it. This may
take a significatn amount of time so it's done before
the boot animation completes.
Bug: 2713849
Change-Id: I07f2c22a1462e6923cb7b060d561e7fb41a6e82d
-rw-r--r-- | Android.mk | 2 | ||||
-rw-r--r-- | AndroidManifest.xml | 10 | ||||
-rw-r--r-- | src/com/android/providers/contacts/ContactsDatabaseHelper.java | 2 | ||||
-rw-r--r-- | src/com/android/providers/contacts/ContactsUpgradeReceiver.java | 82 | ||||
-rw-r--r-- | src/com/android/providers/contacts/EventLogTags.logtags | 5 |
5 files changed, 100 insertions, 1 deletions
@@ -5,6 +5,8 @@ LOCAL_MODULE_TAGS := optional # Only compile source java files in this apk. LOCAL_SRC_FILES := $(call all-java-files-under, src) +LOCAL_SRC_FILES += \ + src/com/android/providers/contacts/EventLogTags.logtags LOCAL_JAVA_LIBRARIES := ext diff --git a/AndroidManifest.xml b/AndroidManifest.xml index f940130d..7ccfccef 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -48,5 +48,15 @@ android:multiprocess="false" android:readPermission="android.permission.READ_CONTACTS" android:writePermission="android.permission.WRITE_CONTACTS" /> + + <!-- Handles database upgrades after OTAs, then disables itself --> + <receiver android:name="ContactsUpgradeReceiver"> + <!-- This broadcast is sent after the core system has finished + booting, before the home app is launched or BOOT_COMPLETED + is sent. --> + <intent-filter> + <action android:name="android.intent.action.PRE_BOOT_COMPLETED"/> + </intent-filter> + </receiver> </application> </manifest> diff --git a/src/com/android/providers/contacts/ContactsDatabaseHelper.java b/src/com/android/providers/contacts/ContactsDatabaseHelper.java index 6a5015f6..0ac8a900 100644 --- a/src/com/android/providers/contacts/ContactsDatabaseHelper.java +++ b/src/com/android/providers/contacts/ContactsDatabaseHelper.java @@ -73,7 +73,7 @@ import java.util.Locale; /* package */ class ContactsDatabaseHelper extends SQLiteOpenHelper { private static final String TAG = "ContactsDatabaseHelper"; - private static final int DATABASE_VERSION = 309; + static final int DATABASE_VERSION = 309; private static final String DATABASE_NAME = "contacts2.db"; private static final String DATABASE_PRESENCE = "presence_db"; diff --git a/src/com/android/providers/contacts/ContactsUpgradeReceiver.java b/src/com/android/providers/contacts/ContactsUpgradeReceiver.java new file mode 100644 index 00000000..24fd0d26 --- /dev/null +++ b/src/com/android/providers/contacts/ContactsUpgradeReceiver.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.providers.contacts; + +import android.content.BroadcastReceiver; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.util.Log; + +/** + * This will be launched during system boot, after the core system has + * been brought up but before any non-persistent processes have been + * started. It is launched in a special state, with no content provider + * or custom application class associated with the process running. + * + * It's job is to prime the contacts database. Either create it + * if it doesn't exist, or open it and force any necessary upgrades. + * All of this heavy lifting happens before the boot animation ends. + */ +public class ContactsUpgradeReceiver extends BroadcastReceiver { + static final String TAG = "ContactsUpgradeReceiver"; + static final String PREF_DB_VERSION = "db_version"; + + @Override + public void onReceive(Context context, Intent intent) { + // We are now running with the system up, but no apps started, + // so can do whatever cleanup after an upgrade that we want. + + try { + long startTime = System.currentTimeMillis(); + + // Lookup the last known database version + SharedPreferences prefs = context.getSharedPreferences(TAG, Context.MODE_PRIVATE); + int prefVersion = prefs.getInt(PREF_DB_VERSION, 0); + + // If the version is old go ahead and attempt to create or upgrade the database. + if (prefVersion != ContactsDatabaseHelper.DATABASE_VERSION) { + // Store the current version so this receiver isn't run again until the database + // version number changes. This is intentionally done even before the upgrade path + // is attempted to be conservative. If the upgrade fails for some reason and we + // crash and burn we don't want to get into a loop doing so. + prefs.edit().putInt(PREF_DB_VERSION, ContactsDatabaseHelper.DATABASE_VERSION).commit(); + + // Ask for a reference to the database to force the helper to either + // create the database or open it up, performing any necessary upgrades + // in the process. + Log.i(TAG, "Creating or opening contacts database"); + ContactsDatabaseHelper helper = ContactsDatabaseHelper.getInstance(context); + helper.getWritableDatabase(); + helper.close(); + + // Log the total time taken for the receiver to perform the operation + EventLogTags.writeContactsUpgradeReceiver(System.currentTimeMillis() - startTime); + } + } catch (Throwable t) { + // Something has gone terribly wrong. Disable this receiver for good so we can't + // possibly end up in a reboot loop. + Log.wtf(TAG, "Error during upgrade attempt. Disabling receiver.", t); + context.getPackageManager().setComponentEnabledSetting( + new ComponentName(context, getClass()), + PackageManager.COMPONENT_ENABLED_STATE_DISABLED, + PackageManager.DONT_KILL_APP); + } + } +} diff --git a/src/com/android/providers/contacts/EventLogTags.logtags b/src/com/android/providers/contacts/EventLogTags.logtags new file mode 100644 index 00000000..823b5170 --- /dev/null +++ b/src/com/android/providers/contacts/EventLogTags.logtags @@ -0,0 +1,5 @@ +# See system/core/logcat/event.logtags for a description of the format of this file. + +option java_package com.android.providers.contacts; + +4100 contacts_upgrade_receiver (time|2|3) |