Merge "Adding support to restore widgets even for jelly beans." into ub-now-porkchop
This commit is contained in:
@@ -65,7 +65,6 @@ import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.StrictMode;
|
||||
import android.os.SystemClock;
|
||||
import android.provider.Settings;
|
||||
import android.speech.RecognizerIntent;
|
||||
import android.text.Selection;
|
||||
import android.text.SpannableStringBuilder;
|
||||
@@ -155,6 +154,7 @@ public class Launcher extends Activity
|
||||
private static final int REQUEST_PICK_WALLPAPER = 10;
|
||||
|
||||
private static final int REQUEST_BIND_APPWIDGET = 11;
|
||||
private static final int REQUEST_RECONFIGURE_APPWIDGET = 12;
|
||||
|
||||
/**
|
||||
* IntentStarter uses request codes starting with this. This must be greater than all activity
|
||||
@@ -754,6 +754,9 @@ public class Launcher extends Activity
|
||||
case REQUEST_CREATE_APPWIDGET:
|
||||
completeAddAppWidget(args.appWidgetId, args.container, screenId, null, null);
|
||||
break;
|
||||
case REQUEST_RECONFIGURE_APPWIDGET:
|
||||
completeRestoreAppWidget(args.appWidgetId);
|
||||
break;
|
||||
}
|
||||
// Before adding this resetAddInfo(), after a shortcut was added to a workspace screen,
|
||||
// if you turned the screen off and then back while in All Apps, Launcher would not
|
||||
@@ -856,6 +859,21 @@ public class Launcher extends Activity
|
||||
return;
|
||||
}
|
||||
|
||||
if (requestCode == REQUEST_RECONFIGURE_APPWIDGET) {
|
||||
if (resultCode == RESULT_OK) {
|
||||
// Update the widget view.
|
||||
PendingAddArguments args = preparePendingAddArgs(requestCode, data,
|
||||
pendingAddWidgetId, mPendingAddInfo);
|
||||
if (workspaceLocked) {
|
||||
sPendingAddItem = args;
|
||||
} else {
|
||||
completeAdd(args);
|
||||
}
|
||||
}
|
||||
// Leave the widget in the pending state if the user canceled the configure.
|
||||
return;
|
||||
}
|
||||
|
||||
// The pattern used here is that a user PICKs a specific application,
|
||||
// which, depending on the target, might need to CREATE the actual target.
|
||||
|
||||
@@ -2448,6 +2466,10 @@ public class Launcher extends Activity
|
||||
}
|
||||
} else if (v == mAllAppsButton) {
|
||||
onClickAllAppsButton(v);
|
||||
} else if (tag instanceof LauncherAppWidgetInfo) {
|
||||
if (v instanceof PendingAppWidgetHostView) {
|
||||
onClickPendingWidget((PendingAppWidgetHostView) v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2455,6 +2477,27 @@ public class Launcher extends Activity
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Event handler for the app widget view which has not fully restored.
|
||||
*/
|
||||
public void onClickPendingWidget(PendingAppWidgetHostView v) {
|
||||
if (v.isReadyForClickSetup()) {
|
||||
LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag();
|
||||
int widgetId = info.appWidgetId;
|
||||
AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);
|
||||
if (appWidgetInfo != null) {
|
||||
mPendingAddWidgetInfo = appWidgetInfo;
|
||||
mPendingAddInfo.copyFrom(info);
|
||||
mPendingAddWidgetId = widgetId;
|
||||
|
||||
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
|
||||
intent.setComponent(appWidgetInfo.configure);
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, info.appWidgetId);
|
||||
Utilities.startActivityForResultSafely(this, intent, REQUEST_RECONFIGURE_APPWIDGET);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Event handler for the search button
|
||||
*
|
||||
@@ -4334,7 +4377,64 @@ public class Launcher extends Activity
|
||||
}
|
||||
final Workspace workspace = mWorkspace;
|
||||
|
||||
final AppWidgetProviderInfo appWidgetInfo;
|
||||
AppWidgetProviderInfo appWidgetInfo;
|
||||
if (((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0) &&
|
||||
((item.restoreStatus & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) != 0)) {
|
||||
|
||||
appWidgetInfo = mModel.findAppWidgetProviderInfoWithComponent(this, item.providerName);
|
||||
if (appWidgetInfo == null) {
|
||||
if (DEBUG_WIDGETS) {
|
||||
Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId
|
||||
+ " belongs to component " + item.providerName
|
||||
+ ", as the povider is null");
|
||||
}
|
||||
LauncherModel.deleteItemFromDatabase(this, item);
|
||||
return;
|
||||
}
|
||||
// Note: This assumes that the id remap broadcast is received before this step.
|
||||
// If that is not the case, the id remap will be ignored and user may see the
|
||||
// click to setup view.
|
||||
PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(appWidgetInfo, null, null);
|
||||
pendingInfo.spanX = item.spanX;
|
||||
pendingInfo.spanY = item.spanY;
|
||||
pendingInfo.minSpanX = item.minSpanX;
|
||||
pendingInfo.minSpanY = item.minSpanY;
|
||||
Bundle options =
|
||||
AppsCustomizePagedView.getDefaultOptionsForWidget(this, pendingInfo);
|
||||
|
||||
boolean success = false;
|
||||
int newWidgetId = mAppWidgetHost.allocateAppWidgetId();
|
||||
if (options != null) {
|
||||
success = mAppWidgetManager.bindAppWidgetIdIfAllowed(newWidgetId,
|
||||
appWidgetInfo.provider, options);
|
||||
} else {
|
||||
success = mAppWidgetManager.bindAppWidgetIdIfAllowed(newWidgetId,
|
||||
appWidgetInfo.provider);
|
||||
}
|
||||
|
||||
// TODO consider showing a permission dialog when the widget is clicked.
|
||||
if (!success) {
|
||||
mAppWidgetHost.deleteAppWidgetId(newWidgetId);
|
||||
if (DEBUG_WIDGETS) {
|
||||
Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId
|
||||
+ " belongs to component " + item.providerName
|
||||
+ ", as the launcher is unable to bing a new widget id");
|
||||
}
|
||||
LauncherModel.deleteItemFromDatabase(this, item);
|
||||
return;
|
||||
}
|
||||
|
||||
item.appWidgetId = newWidgetId;
|
||||
|
||||
// If the widget has a configure activity, it is still needs to set it up, otherwise
|
||||
// the widget is ready to go.
|
||||
item.restoreStatus = (appWidgetInfo.configure == null)
|
||||
? LauncherAppWidgetInfo.RESTORE_COMPLETED
|
||||
: LauncherAppWidgetInfo.FLAG_UI_NOT_READY;
|
||||
|
||||
LauncherModel.updateItemInDatabase(this, item);
|
||||
}
|
||||
|
||||
if (item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {
|
||||
final int appWidgetId = item.appWidgetId;
|
||||
appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
|
||||
@@ -4345,8 +4445,9 @@ public class Launcher extends Activity
|
||||
item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);
|
||||
} else {
|
||||
appWidgetInfo = null;
|
||||
item.hostView = new LauncherAppWidgetHostView(this, false);
|
||||
item.hostView = new PendingAppWidgetHostView(this, item.restoreStatus);
|
||||
item.hostView.updateAppWidget(null);
|
||||
item.hostView.setOnClickListener(this);
|
||||
}
|
||||
|
||||
item.hostView.setTag(item);
|
||||
@@ -4364,6 +4465,29 @@ public class Launcher extends Activity
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores a pending widget.
|
||||
*
|
||||
* @param appWidgetId The app widget id
|
||||
* @param cellInfo The position on screen where to create the widget.
|
||||
*/
|
||||
private void completeRestoreAppWidget(final int appWidgetId) {
|
||||
LauncherAppWidgetHostView view = mWorkspace.getWidgetForAppWidgetId(appWidgetId);
|
||||
if ((view == null) || !(view instanceof PendingAppWidgetHostView)) {
|
||||
Log.e(TAG, "Widget update called, when the widget no longer exists.");
|
||||
return;
|
||||
}
|
||||
|
||||
PendingAppWidgetHostView pendingView = (PendingAppWidgetHostView) view;
|
||||
pendingView.setStatus(LauncherAppWidgetInfo.RESTORE_COMPLETED);
|
||||
|
||||
LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) pendingView.getTag();
|
||||
info.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;
|
||||
|
||||
mWorkspace.reinflateWidgetsIfNecessary();
|
||||
LauncherModel.updateItemInDatabase(this, info);
|
||||
}
|
||||
|
||||
public void onPageBoundSynchronously(int page) {
|
||||
mSynchronouslyBoundPages.add(page);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user