From 04a324afb7309fcf65cfa45420616a094031f20f Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Fri, 20 Jan 2017 21:08:59 -0800 Subject: Adding WidgetAddFlowHandler to handle widget addition and configuration. This will allow us to override the implementation and provide custom logic for widget addition. Bug: 33584624 Change-Id: I310bf39e301c7e1c8de4f62456594535e2fe5bbc --- src/com/android/launcher3/Launcher.java | 82 ++++++---------- .../android/launcher3/LauncherAppWidgetInfo.java | 2 +- .../android/launcher3/util/PendingRequestArgs.java | 29 ++---- .../launcher3/widget/PendingAddWidgetInfo.java | 4 + .../launcher3/widget/WidgetAddFlowHandler.java | 108 +++++++++++++++++++++ 5 files changed, 149 insertions(+), 76 deletions(-) create mode 100644 src/com/android/launcher3/widget/WidgetAddFlowHandler.java diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 9245f187c..8d8a70c0f 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -123,6 +123,7 @@ import com.android.launcher3.util.Thunk; import com.android.launcher3.util.ViewOnDrawExecutor; import com.android.launcher3.widget.PendingAddShortcutInfo; import com.android.launcher3.widget.PendingAddWidgetInfo; +import com.android.launcher3.widget.WidgetAddFlowHandler; import com.android.launcher3.widget.WidgetHostViewLoader; import com.android.launcher3.widget.WidgetsContainerView; @@ -683,8 +684,9 @@ public class Launcher extends BaseActivity // 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, widgetInfo); + if (provider != null) { + new WidgetAddFlowHandler(provider) + .startConfigActivity(this, widgetInfo, REQUEST_RECONFIGURE_APPWIDGET); } } break; @@ -731,7 +733,7 @@ public class Launcher extends BaseActivity } else if (resultCode == RESULT_OK) { addAppWidgetImpl( appWidgetId, requestArgs, null, - requestArgs.getWidgetProvider(this), + requestArgs.getWidgetHandler(), ON_ACTIVITY_RESULT_ANIMATION_DELAY); } return; @@ -890,7 +892,7 @@ public class Launcher extends BaseActivity if (resultCode == RESULT_OK) { animationType = Workspace.COMPLETE_TWO_STAGE_WIDGET_DROP_ANIMATION; final AppWidgetHostView layout = mAppWidgetHost.createView(this, appWidgetId, - requestArgs.getWidgetProvider(this)); + requestArgs.getWidgetHandler().getProviderInfo(this)); boundWidget = layout; onCompleteRunnable = new Runnable() { @Override @@ -1983,7 +1985,7 @@ public class Launcher extends BaseActivity } } - private void setWaitingForResult(PendingRequestArgs args) { + public void setWaitingForResult(PendingRequestArgs args) { boolean isLocked = isWorkspaceLocked(); mPendingRequestArgs = args; if (isLocked != isWorkspaceLocked()) { @@ -1998,24 +2000,18 @@ public class Launcher extends BaseActivity } void addAppWidgetFromDropImpl(int appWidgetId, ItemInfo info, AppWidgetHostView boundWidget, - LauncherAppWidgetProviderInfo appWidgetInfo) { + WidgetAddFlowHandler addFlowHandler) { if (LOGD) { Log.d(TAG, "Adding widget from drop"); } - addAppWidgetImpl(appWidgetId, info, boundWidget, appWidgetInfo, 0); + addAppWidgetImpl(appWidgetId, info, boundWidget, addFlowHandler, 0); } void addAppWidgetImpl(int appWidgetId, ItemInfo info, - AppWidgetHostView boundWidget, LauncherAppWidgetProviderInfo appWidgetInfo, - int delay) { - if (appWidgetInfo.configure != null) { - setWaitingForResult(PendingRequestArgs.forWidgetInfo(appWidgetId, appWidgetInfo, info)); - - // Launch over to configure widget, if needed - mAppWidgetManager.startConfigActivity(appWidgetInfo, appWidgetId, this, - mAppWidgetHost, REQUEST_CREATE_APPWIDGET); - } else { - // Otherwise just add it + AppWidgetHostView boundWidget, WidgetAddFlowHandler addFlowHandler, int delay) { + if (!addFlowHandler.startConfigActivity(this, appWidgetId, info, REQUEST_CREATE_APPWIDGET)) { + // If the configuration flow was not started, add the widget + Runnable onComplete = new Runnable() { @Override public void run() { @@ -2024,7 +2020,7 @@ public class Launcher extends BaseActivity null); } }; - completeAddAppWidget(appWidgetId, info, boundWidget, appWidgetInfo); + completeAddAppWidget(appWidgetId, info, boundWidget, addFlowHandler.getProviderInfo(this)); mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, delay, false); } } @@ -2076,6 +2072,7 @@ public class Launcher extends BaseActivity private void addAppWidgetFromDrop(PendingAddWidgetInfo info) { AppWidgetHostView hostView = info.boundWidget; int appWidgetId; + WidgetAddFlowHandler addFlowHandler = info.getHander(); if (hostView != null) { // In the case where we've prebound the widget, we remove it from the DragLayer if (LOGD) { @@ -2084,7 +2081,7 @@ public class Launcher extends BaseActivity getDragLayer().removeView(hostView); appWidgetId = hostView.getAppWidgetId(); - addAppWidgetFromDropImpl(appWidgetId, info, hostView, info.info); + addAppWidgetFromDropImpl(appWidgetId, info, hostView, addFlowHandler); // Clear the boundWidget so that it doesn't get destroyed. info.boundWidget = null; @@ -2097,17 +2094,9 @@ public class Launcher extends BaseActivity boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed( appWidgetId, info.info, options); if (success) { - addAppWidgetFromDropImpl(appWidgetId, info, null, info.info); + addAppWidgetFromDropImpl(appWidgetId, info, null, addFlowHandler); } else { - setWaitingForResult(PendingRequestArgs.forWidgetInfo(appWidgetId, info.info, info)); - Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND); - intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); - intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName); - intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE, - info.info.getUser()); - // TODO: we need to make sure that this accounts for the options bundle. - // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options); - startActivityForResult(intent, REQUEST_BIND_APPWIDGET); + addFlowHandler.startBindFlow(this, appWidgetId, info, REQUEST_BIND_APPWIDGET); } } } @@ -2323,30 +2312,22 @@ public class Launcher extends BaseActivity final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag(); if (v.isReadyForClickSetup()) { + LauncherAppWidgetProviderInfo appWidgetInfo = + mAppWidgetManager.findProvider(info.providerName, info.user); + if (appWidgetInfo == null) { + return; + } + WidgetAddFlowHandler addFlowHandler = new WidgetAddFlowHandler(appWidgetInfo); + 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) { - setWaitingForResult(PendingRequestArgs - .forWidgetInfo(info.appWidgetId, appWidgetInfo, info)); - - Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND); - intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, info.appWidgetId); - intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, appWidgetInfo.provider); - intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE, - appWidgetInfo.getUser()); - startActivityForResult(intent, REQUEST_BIND_PENDING_APPWIDGET); - } + addFlowHandler.startBindFlow(this, info.appWidgetId, info, + REQUEST_BIND_PENDING_APPWIDGET); } else { - LauncherAppWidgetProviderInfo appWidgetInfo = - mAppWidgetManager.getLauncherAppWidgetInfo(info.appWidgetId); - if (appWidgetInfo != null) { - startRestoredWidgetReconfigActivity(appWidgetInfo, info); - } + addFlowHandler.startConfigActivity(this, info, REQUEST_RECONFIGURE_APPWIDGET); } } else { final String packageName = info.providerName.getPackageName(); @@ -2354,13 +2335,6 @@ public class Launcher extends BaseActivity } } - private void startRestoredWidgetReconfigActivity( - LauncherAppWidgetProviderInfo provider, LauncherAppWidgetInfo info) { - setWaitingForResult(PendingRequestArgs.forWidgetInfo(info.appWidgetId, provider, info)); - 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. diff --git a/src/com/android/launcher3/LauncherAppWidgetInfo.java b/src/com/android/launcher3/LauncherAppWidgetInfo.java index b68a64b63..285a93cd7 100644 --- a/src/com/android/launcher3/LauncherAppWidgetInfo.java +++ b/src/com/android/launcher3/LauncherAppWidgetInfo.java @@ -76,7 +76,7 @@ public class LauncherAppWidgetInfo extends ItemInfo { * Identifier for this widget when talking with * {@link android.appwidget.AppWidgetManager} for updates. */ - int appWidgetId = NO_ID; + public int appWidgetId = NO_ID; public ComponentName providerName; diff --git a/src/com/android/launcher3/util/PendingRequestArgs.java b/src/com/android/launcher3/util/PendingRequestArgs.java index 9452fbd05..538e1df5b 100644 --- a/src/com/android/launcher3/util/PendingRequestArgs.java +++ b/src/com/android/launcher3/util/PendingRequestArgs.java @@ -15,15 +15,13 @@ */ package com.android.launcher3.util; -import android.appwidget.AppWidgetProviderInfo; import android.content.ContentValues; -import android.content.Context; import android.content.Intent; import android.os.Parcel; import android.os.Parcelable; import com.android.launcher3.ItemInfo; -import com.android.launcher3.LauncherAppWidgetProviderInfo; +import com.android.launcher3.widget.WidgetAddFlowHandler; /** * Utility class to store information regarding a pending request made by launcher. This information @@ -58,12 +56,7 @@ public class PendingRequestArgs extends ItemInfo implements Parcelable { mArg1 = parcel.readInt(); mObjectType = parcel.readInt(); - if (parcel.readInt() != 0) { - mObject = (mObjectType == TYPE_INTENT ? Intent.CREATOR : AppWidgetProviderInfo.CREATOR) - .createFromParcel(parcel); - } else { - mObject = null; - } + mObject = parcel.readParcelable(null); } @Override @@ -79,18 +72,11 @@ public class PendingRequestArgs extends ItemInfo implements Parcelable { dest.writeInt(mArg1); dest.writeInt(mObjectType); - if (mObject != null) { - dest.writeInt(1); - mObject.writeToParcel(dest, flags); - } else { - dest.writeInt(0); - } + dest.writeParcelable(mObject, flags); } - public LauncherAppWidgetProviderInfo getWidgetProvider(Context context) { - return mObjectType == TYPE_APP_WIDGET ? - LauncherAppWidgetProviderInfo.fromProviderInfo( - context, (AppWidgetProviderInfo) mObject) : null; + public WidgetAddFlowHandler getWidgetHandler() { + return mObjectType == TYPE_APP_WIDGET ? (WidgetAddFlowHandler) mObject : null; } public int getWidgetId() { @@ -106,8 +92,9 @@ public class PendingRequestArgs extends ItemInfo implements Parcelable { } public static PendingRequestArgs forWidgetInfo( - int appWidgetId, AppWidgetProviderInfo widgetInfo, ItemInfo info) { - PendingRequestArgs args = new PendingRequestArgs(appWidgetId, TYPE_APP_WIDGET, widgetInfo); + int appWidgetId, WidgetAddFlowHandler widgetHandler, ItemInfo info) { + PendingRequestArgs args = + new PendingRequestArgs(appWidgetId, TYPE_APP_WIDGET, widgetHandler); args.copyFrom(info); return args; } diff --git a/src/com/android/launcher3/widget/PendingAddWidgetInfo.java b/src/com/android/launcher3/widget/PendingAddWidgetInfo.java index 7968684f9..23e2f9225 100644 --- a/src/com/android/launcher3/widget/PendingAddWidgetInfo.java +++ b/src/com/android/launcher3/widget/PendingAddWidgetInfo.java @@ -51,4 +51,8 @@ public class PendingAddWidgetInfo extends PendingAddItemInfo { minSpanX = i.minSpanX; minSpanY = i.minSpanY; } + + public WidgetAddFlowHandler getHander() { + return new WidgetAddFlowHandler(info); + } } diff --git a/src/com/android/launcher3/widget/WidgetAddFlowHandler.java b/src/com/android/launcher3/widget/WidgetAddFlowHandler.java new file mode 100644 index 000000000..f44e56c00 --- /dev/null +++ b/src/com/android/launcher3/widget/WidgetAddFlowHandler.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2017 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.launcher3.widget; + +import android.appwidget.AppWidgetManager; +import android.appwidget.AppWidgetProviderInfo; +import android.content.Context; +import android.content.Intent; +import android.os.Parcel; +import android.os.Parcelable; + +import com.android.launcher3.ItemInfo; +import com.android.launcher3.Launcher; +import com.android.launcher3.LauncherAppWidgetInfo; +import com.android.launcher3.LauncherAppWidgetProviderInfo; +import com.android.launcher3.compat.AppWidgetManagerCompat; +import com.android.launcher3.util.PendingRequestArgs; + +/** + * Utility class to handle app widget add flow. + */ +public class WidgetAddFlowHandler implements Parcelable { + + private final AppWidgetProviderInfo mProviderInfo; + + public WidgetAddFlowHandler(AppWidgetProviderInfo providerInfo) { + mProviderInfo = providerInfo; + } + + private WidgetAddFlowHandler(Parcel parcel) { + mProviderInfo = AppWidgetProviderInfo.CREATOR.createFromParcel(parcel); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + mProviderInfo.writeToParcel(parcel, i); + } + + public void startBindFlow(Launcher launcher, int appWidgetId, ItemInfo info, int requestCode) { + launcher.setWaitingForResult(PendingRequestArgs.forWidgetInfo(appWidgetId, this, info)); + + Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND); + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, mProviderInfo.provider); + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE, + mProviderInfo.getProfile()); + // TODO: we need to make sure that this accounts for the options bundle. + // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options); + launcher.startActivityForResult(intent, requestCode); + } + + /** + * @see #startConfigActivity(Launcher, int, ItemInfo, int) + */ + public boolean startConfigActivity(Launcher launcher, LauncherAppWidgetInfo info, + int requestCode) { + return startConfigActivity(launcher, info.appWidgetId, info, requestCode); + } + + /** + * Starts the widget configuration flow if needed. + * @return true if the configuration flow was started, false otherwise. + */ + public boolean startConfigActivity(Launcher launcher, int appWidgetId, ItemInfo info, + int requestCode) { + if (mProviderInfo.configure == null) { + return false; + } + launcher.setWaitingForResult(PendingRequestArgs.forWidgetInfo(appWidgetId, this, info)); + + AppWidgetManagerCompat.getInstance(launcher).startConfigActivity( + mProviderInfo, appWidgetId, launcher, launcher.getAppWidgetHost(), requestCode); + return true; + } + + public LauncherAppWidgetProviderInfo getProviderInfo(Context context) { + return LauncherAppWidgetProviderInfo.fromProviderInfo(context, mProviderInfo); + } + + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + public WidgetAddFlowHandler createFromParcel(Parcel source) { + return new WidgetAddFlowHandler(source); + } + + public WidgetAddFlowHandler[] newArray(int size) { + return new WidgetAddFlowHandler[size]; + } + }; +} -- cgit v1.2.3