AI 143789: am: CL 143776 am: CL 143622 Correctly startListening() for widget updates when first boot completes.
During the first boot upgrade, LauncherProvider will deleteHost() to clear out any old appWidgetId bindings. During the first boot, Launcher calls AppWidgetHost.startListening() to watch for widget updates. It also calls loadUserItems(), which loads data from LauncherProvider, triggering the database creation and deleteHost() call. Because deleteHost() removes any existing callbacks, any future widget updates are dropped on the floor. (This can currently be solved by rebooting, because there isn't an upgrade on subsequent boots.) This bug was particularly evident on vfpioneer-userdebug builds, as there aren't any configuration changes that cause Launcher to be destroyed and recreated. (When destroyed and recreated, we startListening() again, and LauncherProvider doesn't call deleteHost().) To handle this special case, Launcher creates a ContentObserver pointing at a specific URI, which the LauncherProvider notifies when the AppWidgetHost is reset through deleteHost(), allowing Launcher to correctly startListening() again. Original author: jsharkey Merged from: //branches/cupcake/... Original author: android-build Merged from: //branches/donutburger/... Automated import of CL 143789
This commit is contained in:
parent
577ef46489
commit
9dc115efc0
|
@ -168,6 +168,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
|
||||||
|
|
||||||
private final BroadcastReceiver mApplicationsReceiver = new ApplicationsIntentReceiver();
|
private final BroadcastReceiver mApplicationsReceiver = new ApplicationsIntentReceiver();
|
||||||
private final ContentObserver mObserver = new FavoritesChangeObserver();
|
private final ContentObserver mObserver = new FavoritesChangeObserver();
|
||||||
|
private final ContentObserver mAppWidgetResetObserver = new AppWidgetResetObserver();
|
||||||
|
|
||||||
private LayoutInflater mInflater;
|
private LayoutInflater mInflater;
|
||||||
|
|
||||||
|
@ -826,6 +827,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
|
||||||
sModel.abortLoaders();
|
sModel.abortLoaders();
|
||||||
|
|
||||||
getContentResolver().unregisterContentObserver(mObserver);
|
getContentResolver().unregisterContentObserver(mObserver);
|
||||||
|
getContentResolver().unregisterContentObserver(mAppWidgetResetObserver);
|
||||||
unregisterReceiver(mApplicationsReceiver);
|
unregisterReceiver(mApplicationsReceiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1156,6 +1158,7 @@ public final class Launcher extends Activity implements View.OnClickListener, On
|
||||||
private void registerContentObservers() {
|
private void registerContentObservers() {
|
||||||
ContentResolver resolver = getContentResolver();
|
ContentResolver resolver = getContentResolver();
|
||||||
resolver.registerContentObserver(LauncherSettings.Favorites.CONTENT_URI, true, mObserver);
|
resolver.registerContentObserver(LauncherSettings.Favorites.CONTENT_URI, true, mObserver);
|
||||||
|
resolver.registerContentObserver(LauncherProvider.CONTENT_APPWIDGET_RESET_URI, true, mAppWidgetResetObserver);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1221,6 +1224,16 @@ public final class Launcher extends Activity implements View.OnClickListener, On
|
||||||
sModel.loadUserItems(false, this, false, false);
|
sModel.loadUserItems(false, this, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When reset, we handle by calling {@link AppWidgetHost#startListening()}
|
||||||
|
* to make sure our callbacks are set correctly.
|
||||||
|
*/
|
||||||
|
private void onAppWidgetReset() {
|
||||||
|
if (mAppWidgetHost != null) {
|
||||||
|
mAppWidgetHost.startListening();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void onDesktopItemsLoaded() {
|
void onDesktopItemsLoaded() {
|
||||||
if (mDestroyed) return;
|
if (mDestroyed) return;
|
||||||
bindDesktopItems();
|
bindDesktopItems();
|
||||||
|
@ -1877,6 +1890,21 @@ public final class Launcher extends Activity implements View.OnClickListener, On
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receives notifications when the {@link AppWidgetHost} has been reset,
|
||||||
|
* usually only when the {@link LauncherProvider} database is first created.
|
||||||
|
*/
|
||||||
|
private class AppWidgetResetObserver extends ContentObserver {
|
||||||
|
public AppWidgetResetObserver() {
|
||||||
|
super(new Handler());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onChange(boolean selfChange) {
|
||||||
|
onAppWidgetReset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Receives intents from other applications to change the wallpaper.
|
* Receives intents from other applications to change the wallpaper.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -65,6 +65,14 @@ public class LauncherProvider extends ContentProvider {
|
||||||
static final String TABLE_FAVORITES = "favorites";
|
static final String TABLE_FAVORITES = "favorites";
|
||||||
static final String PARAMETER_NOTIFY = "notify";
|
static final String PARAMETER_NOTIFY = "notify";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link Uri} triggered at any registered {@link ContentObserver} when
|
||||||
|
* {@link AppWidgetHost#deleteHost()} is called during database creation.
|
||||||
|
* Use this to recall {@link AppWidgetHost#startListening()} if needed.
|
||||||
|
*/
|
||||||
|
static final Uri CONTENT_APPWIDGET_RESET_URI =
|
||||||
|
Uri.parse("content://" + AUTHORITY + "/appWidgetReset");
|
||||||
|
|
||||||
private SQLiteOpenHelper mOpenHelper;
|
private SQLiteOpenHelper mOpenHelper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -176,6 +184,17 @@ public class LauncherProvider extends ContentProvider {
|
||||||
mAppWidgetHost = new AppWidgetHost(context, Launcher.APPWIDGET_HOST_ID);
|
mAppWidgetHost = new AppWidgetHost(context, Launcher.APPWIDGET_HOST_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send notification that we've deleted the {@link AppWidgetHost},
|
||||||
|
* probably as part of the initial database creation. The receiver may
|
||||||
|
* want to re-call {@link AppWidgetHost#startListening()} to ensure
|
||||||
|
* callbacks are correctly set.
|
||||||
|
*/
|
||||||
|
private void sendAppWidgetResetNotify() {
|
||||||
|
final ContentResolver resolver = mContext.getContentResolver();
|
||||||
|
resolver.notifyChange(CONTENT_APPWIDGET_RESET_URI, null);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(SQLiteDatabase db) {
|
public void onCreate(SQLiteDatabase db) {
|
||||||
if (LOGD) Log.d(LOG_TAG, "creating new launcher database");
|
if (LOGD) Log.d(LOG_TAG, "creating new launcher database");
|
||||||
|
@ -204,6 +223,7 @@ public class LauncherProvider extends ContentProvider {
|
||||||
// Database was just created, so wipe any previous widgets
|
// Database was just created, so wipe any previous widgets
|
||||||
if (mAppWidgetHost != null) {
|
if (mAppWidgetHost != null) {
|
||||||
mAppWidgetHost.deleteHost();
|
mAppWidgetHost.deleteHost();
|
||||||
|
sendAppWidgetResetNotify();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!convertDatabase(db)) {
|
if (!convertDatabase(db)) {
|
||||||
|
|
Loading…
Reference in New Issue