summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSunny Goyal <sunnygoyal@google.com>2016-05-27 00:44:56 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2016-05-27 00:44:57 +0000
commit3c4b03dd01b89a4d4beba6a866ae3bb9093e101e (patch)
tree34ea43c08ac6d67fa7a2c508a64588cda7466d57
parent5c93eac3ae163a5a3d866db24d9b853caa9b9f88 (diff)
parentd478c83fd6abebe6ce3f066d392a28f8ba9be100 (diff)
downloadandroid_packages_apps_Trebuchet-3c4b03dd01b89a4d4beba6a866ae3bb9093e101e.tar.gz
android_packages_apps_Trebuchet-3c4b03dd01b89a4d4beba6a866ae3bb9093e101e.tar.bz2
android_packages_apps_Trebuchet-3c4b03dd01b89a4d4beba6a866ae3bb9093e101e.zip
Merge "Showing a permission dialog when a restored widget is not yet bound, and launcher does not has the permission to bind the widget" into ub-launcher3-calgary
-rw-r--r--src/com/android/launcher3/Launcher.java131
-rw-r--r--src/com/android/launcher3/LauncherAppWidgetInfo.java11
-rw-r--r--src/com/android/launcher3/PendingAppWidgetHostView.java14
3 files changed, 103 insertions, 53 deletions
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index ec09cf149..13e451a27 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -158,6 +158,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_BIND_PENDING_APPWIDGET = 14;
private static final int REQUEST_RECONFIGURE_APPWIDGET = 12;
private static final int REQUEST_PERMISSION_CALL_PHONE = 13;
@@ -688,8 +689,22 @@ public class Launcher extends Activity
completeAddAppWidget(args.appWidgetId, args.container, screenId, null, null);
break;
case REQUEST_RECONFIGURE_APPWIDGET:
- completeRestoreAppWidget(args.appWidgetId);
+ completeRestoreAppWidget(args.appWidgetId, LauncherAppWidgetInfo.RESTORE_COMPLETED);
break;
+ case REQUEST_BIND_PENDING_APPWIDGET: {
+ int widgetId = args.appWidgetId;
+ LauncherAppWidgetInfo info =
+ completeRestoreAppWidget(widgetId, LauncherAppWidgetInfo.FLAG_UI_NOT_READY);
+ if (info != null) {
+ // Since the view was just bound, also launch the configure activity if needed
+ LauncherAppWidgetProviderInfo provider = mAppWidgetManager
+ .getLauncherAppWidgetInfo(widgetId);
+ if (provider != null && provider.configure != null) {
+ startRestoredWidgetReconfigActivity(provider, info);
+ }
+ }
+ 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
@@ -804,7 +819,8 @@ public class Launcher extends Activity
return;
}
- if (requestCode == REQUEST_RECONFIGURE_APPWIDGET) {
+ if (requestCode == REQUEST_RECONFIGURE_APPWIDGET
+ || requestCode == REQUEST_BIND_PENDING_APPWIDGET) {
if (resultCode == RESULT_OK) {
// Update the widget view.
PendingAddArguments args = preparePendingAddArgs(requestCode, data,
@@ -2380,7 +2396,7 @@ public class Launcher extends Activity
*/
private void deleteWidgetInfo(final LauncherAppWidgetInfo widgetInfo) {
final LauncherAppWidgetHost appWidgetHost = getAppWidgetHost();
- if (appWidgetHost != null && !widgetInfo.isCustomWidget() && widgetInfo.isWidgetIdValid()) {
+ if (appWidgetHost != null && !widgetInfo.isCustomWidget() && widgetInfo.isWidgetIdAllocated()) {
// Deleting an app widget ID is a void call but writes to disk before returning
// to the caller...
new AsyncTask<Void, Void, Void>() {
@@ -2526,16 +2542,31 @@ public class Launcher extends Activity
final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag();
if (v.isReadyForClickSetup()) {
- int widgetId = info.appWidgetId;
- LauncherAppWidgetProviderInfo appWidgetInfo =
- mAppWidgetManager.getLauncherAppWidgetInfo(widgetId);
- if (appWidgetInfo != null) {
- mPendingAddWidgetInfo = appWidgetInfo;
- mPendingAddInfo.copyFrom(info);
- mPendingAddWidgetId = widgetId;
-
- AppWidgetManagerCompat.getInstance(this).startConfigActivity(appWidgetInfo,
- info.appWidgetId, this, mAppWidgetHost, REQUEST_RECONFIGURE_APPWIDGET);
+ if (info.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_ID_NOT_VALID)) {
+ if (!info.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_ID_ALLOCATED)) {
+ // This should not happen, as we make sure that an Id is allocated during bind.
+ return;
+ }
+ LauncherAppWidgetProviderInfo appWidgetInfo =
+ mAppWidgetManager.findProvider(info.providerName, info.user);
+ if (appWidgetInfo != null) {
+ mPendingAddWidgetId = info.appWidgetId;
+ mPendingAddInfo.copyFrom(info);
+ mPendingAddWidgetInfo = appWidgetInfo;
+
+ Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
+ intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mPendingAddWidgetId);
+ intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, appWidgetInfo.provider);
+ mAppWidgetManager.getUser(mPendingAddWidgetInfo)
+ .addToIntent(intent, AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE);
+ startActivityForResult(intent, REQUEST_BIND_PENDING_APPWIDGET);
+ }
+ } else {
+ LauncherAppWidgetProviderInfo appWidgetInfo =
+ mAppWidgetManager.getLauncherAppWidgetInfo(info.appWidgetId);
+ if (appWidgetInfo != null) {
+ startRestoredWidgetReconfigActivity(appWidgetInfo, info);
+ }
}
} else if (info.installProgress < 0) {
// The install has not been queued
@@ -2553,6 +2584,15 @@ public class Launcher extends Activity
}
}
+ private void startRestoredWidgetReconfigActivity(
+ LauncherAppWidgetProviderInfo provider, LauncherAppWidgetInfo info) {
+ mPendingAddWidgetInfo = provider;
+ mPendingAddInfo.copyFrom(info);
+ mPendingAddWidgetId = info.appWidgetId;
+ mAppWidgetManager.startConfigActivity(provider,
+ info.appWidgetId, this, mAppWidgetHost, REQUEST_RECONFIGURE_APPWIDGET);
+ }
+
/**
* Event handler for the "grid" button that appears on the home screen, which
* enters all apps mode.
@@ -3919,41 +3959,33 @@ public class Launcher extends Activity
// If we do not have a valid id, try to bind an id.
if (item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_ID_NOT_VALID)) {
- // 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(this, appWidgetInfo);
- pendingInfo.spanX = item.spanX;
- pendingInfo.spanY = item.spanY;
- pendingInfo.minSpanX = item.minSpanX;
- pendingInfo.minSpanY = item.minSpanY;
- Bundle options = WidgetHostViewLoader.getDefaultOptionsForWidget(this, pendingInfo);
-
- int newWidgetId = mAppWidgetHost.allocateAppWidgetId();
- boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(
- newWidgetId, appWidgetInfo, options);
-
- // 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");
+ if (!item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_ID_ALLOCATED)) {
+ // Id has not been allocated yet. Allocate a new id.
+ item.appWidgetId = mAppWidgetHost.allocateAppWidgetId();
+ item.restoreStatus |= LauncherAppWidgetInfo.FLAG_ID_ALLOCATED;
+
+ // Also try to bind the widget. If the bind fails, the user will be shown
+ // a click to setup UI, which will ask for the bind permission.
+ PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(this, appWidgetInfo);
+ pendingInfo.spanX = item.spanX;
+ pendingInfo.spanY = item.spanY;
+ pendingInfo.minSpanX = item.minSpanX;
+ pendingInfo.minSpanY = item.minSpanY;
+ Bundle options = WidgetHostViewLoader.getDefaultOptionsForWidget(this, pendingInfo);
+ boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(
+ item.appWidgetId, appWidgetInfo, options);
+
+ // Bind succeeded
+ if (success) {
+ // 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.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);
+ LauncherModel.updateItemInDatabase(this, item);
+ }
} else if (item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_UI_NOT_READY)
&& (appWidgetInfo.configure == null)) {
// The widget was marked as UI not ready, but there is no configure activity to
@@ -4001,18 +4033,19 @@ public class Launcher extends Activity
*
* @param appWidgetId The app widget id
*/
- private void completeRestoreAppWidget(final int appWidgetId) {
+ private LauncherAppWidgetInfo completeRestoreAppWidget(int appWidgetId, int finalRestoreFlag) {
LauncherAppWidgetHostView view = mWorkspace.getWidgetForAppWidgetId(appWidgetId);
if ((view == null) || !(view instanceof PendingAppWidgetHostView)) {
Log.e(TAG, "Widget update called, when the widget no longer exists.");
- return;
+ return null;
}
LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) view.getTag();
- info.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;
+ info.restoreStatus = finalRestoreFlag;
mWorkspace.reinflateWidgetsIfNecessary();
LauncherModel.updateItemInDatabase(this, info);
+ return info;
}
public void onPageBoundSynchronously(int page) {
diff --git a/src/com/android/launcher3/LauncherAppWidgetInfo.java b/src/com/android/launcher3/LauncherAppWidgetInfo.java
index 42d646820..4c8fedf5e 100644
--- a/src/com/android/launcher3/LauncherAppWidgetInfo.java
+++ b/src/com/android/launcher3/LauncherAppWidgetInfo.java
@@ -51,6 +51,12 @@ public class LauncherAppWidgetInfo extends ItemInfo {
public static final int FLAG_RESTORE_STARTED = 8;
/**
+ * Indicates that the widget has been allocated an Id. The id is still not valid, as it has
+ * not been bound yet.
+ */
+ public static final int FLAG_ID_ALLOCATED = 16;
+
+ /**
* Indicates that the widget hasn't been instantiated yet.
*/
static final int NO_ID = -1;
@@ -127,8 +133,9 @@ public class LauncherAppWidgetInfo extends ItemInfo {
return "AppWidget(id=" + Integer.toString(appWidgetId) + ")";
}
- public final boolean isWidgetIdValid() {
- return (restoreStatus & FLAG_ID_NOT_VALID) == 0;
+ public final boolean isWidgetIdAllocated() {
+ return (restoreStatus & FLAG_ID_NOT_VALID) == 0 ||
+ (restoreStatus & FLAG_ID_ALLOCATED) == FLAG_ID_ALLOCATED;
}
public final boolean hasRestoreFlag(int flag) {
diff --git a/src/com/android/launcher3/PendingAppWidgetHostView.java b/src/com/android/launcher3/PendingAppWidgetHostView.java
index 1c0290417..a455026fa 100644
--- a/src/com/android/launcher3/PendingAppWidgetHostView.java
+++ b/src/com/android/launcher3/PendingAppWidgetHostView.java
@@ -189,9 +189,19 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView implemen
}
}
+ /**
+ * A pending widget is ready for setup after the provider is installed and
+ * 1) Widget id is not valid: the widget id is not yet bound to the provider, probably
+ * because the launcher doesn't have appropriate permissions.
+ * Note that we would still have an allocated id as that does not
+ * require any permissions and can be done during view inflation.
+ * 2) UI is not ready: the id is valid and the bound. But the widget has a configure activity
+ * which needs to be called once.
+ */
public boolean isReadyForClickSetup() {
- return (mInfo.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0
- && (mInfo.restoreStatus & LauncherAppWidgetInfo.FLAG_UI_NOT_READY) != 0;
+ return !mInfo.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY)
+ && (mInfo.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_UI_NOT_READY)
+ || mInfo.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_ID_NOT_VALID));
}
private void updateDrawableBounds() {