Initial changes to allow resolution of arbitrary clip data to widgets that support them.

Change-Id: Id5dfa8436a5bf6eb7bd300ec603911a9d3698de3
diff --git a/src/com/android/launcher2/CustomizePagedView.java b/src/com/android/launcher2/CustomizePagedView.java
index 28de388..4cce81e 100644
--- a/src/com/android/launcher2/CustomizePagedView.java
+++ b/src/com/android/launcher2/CustomizePagedView.java
@@ -581,12 +581,8 @@
         final int count = list.size();
         layout.removeAllViews();
         for (int i = 0; i < count; ++i) {
-            AppWidgetProviderInfo info = (AppWidgetProviderInfo) list.get(i);
-            PendingAddWidgetInfo createItemInfo = new PendingAddWidgetInfo();
-            createItemInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET;
-            createItemInfo.componentName = info.provider;
-            createItemInfo.minWidth = info.minWidth;
-            createItemInfo.minHeight = info.minHeight;
+            final AppWidgetProviderInfo info = (AppWidgetProviderInfo) list.get(i);
+            final PendingAddWidgetInfo createItemInfo = new PendingAddWidgetInfo(info, null, null);
 
             LinearLayout l = (LinearLayout) mInflater.inflate(
                     R.layout.customize_paged_view_widget, layout, false);
diff --git a/src/com/android/launcher2/InstallShortcutReceiver.java b/src/com/android/launcher2/InstallShortcutReceiver.java
index 8d72531..ac50f66 100644
--- a/src/com/android/launcher2/InstallShortcutReceiver.java
+++ b/src/com/android/launcher2/InstallShortcutReceiver.java
@@ -29,6 +29,10 @@
     public static final String ACTION_INSTALL_SHORTCUT =
             "com.android.launcher.action.INSTALL_SHORTCUT";
 
+    // A mime-type representing shortcut data
+    public static final String SHORTCUT_MIMETYPE =
+            "com.android.launcher/shortcut";
+
     private final int[] mCoordinates = new int[2];
 
     public void onReceive(Context context, Intent data) {
diff --git a/src/com/android/launcher2/InstallWidgetReceiver.java b/src/com/android/launcher2/InstallWidgetReceiver.java
index e6a9a69..970c6a5 100644
--- a/src/com/android/launcher2/InstallWidgetReceiver.java
+++ b/src/com/android/launcher2/InstallWidgetReceiver.java
@@ -16,6 +16,25 @@
 
 package com.android.launcher2;
 
+import java.util.List;
+
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.ClipData;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.database.DataSetObserver;
+import android.graphics.drawable.Drawable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.ListAdapter;
+import android.widget.TextView;
+
+import com.android.launcher.R;
+
 
 /**
  * We will likely flesh this out later, to handle allow external apps to place widgets, but for now,
@@ -24,11 +43,153 @@
 public class InstallWidgetReceiver {
     public static final String ACTION_INSTALL_WIDGET =
             "com.android.launcher.action.INSTALL_WIDGET";
+    public static final String ACTION_SUPPORTS_CLIPDATA_MIMETYPE =
+            "com.android.launcher.action.SUPPORTS_CLIPDATA_MIMETYPE";
 
     // Currently not exposed.  Put into Intent when we want to make it public.
     // TEMP: Should we call this "EXTRA_APPWIDGET_PROVIDER"?
     public static final String EXTRA_APPWIDGET_COMPONENT =
         "com.android.launcher.extra.widget.COMPONENT";
+    public static final String EXTRA_APPWIDGET_CONFIGURATION_DATA_MIME_TYPE =
+        "com.android.launcher.extra.widget.CONFIGURATION_DATA_MIME_TYPE";
     public static final String EXTRA_APPWIDGET_CONFIGURATION_DATA =
         "com.android.launcher.extra.widget.CONFIGURATION_DATA";
+
+    /**
+     * A simple data class that contains per-item information that the adapter below can reference.
+     */
+    public static class WidgetMimeTypeHandlerData {
+        public ResolveInfo resolveInfo;
+        public AppWidgetProviderInfo widgetInfo;
+
+        public WidgetMimeTypeHandlerData(ResolveInfo rInfo, AppWidgetProviderInfo wInfo) {
+            resolveInfo = rInfo;
+            widgetInfo = wInfo;
+        }
+    }
+
+    /**
+     * The ListAdapter which presents all the valid widgets that can be created for a given drop.
+     */
+    public static class WidgetListAdapter implements ListAdapter, DialogInterface.OnClickListener {
+        private LayoutInflater mInflater;
+        private Launcher mLauncher;
+        private String mMimeType;
+        private ClipData mClipData;
+        private List<WidgetMimeTypeHandlerData> mActivities;
+        private CellLayout mTargetLayout;
+        private int mTargetLayoutScreen;
+        private int[] mTargetLayoutPos;
+
+        public WidgetListAdapter(Launcher l, String mimeType, ClipData data,
+                List<WidgetMimeTypeHandlerData> list, CellLayout target,
+                int targetScreen, int[] targetPos) {
+            mLauncher = l;
+            mMimeType = mimeType;
+            mClipData = data;
+            mActivities = list;
+            mTargetLayout = target;
+            mTargetLayoutScreen = targetScreen;
+            mTargetLayoutPos = targetPos;
+        }
+
+        @Override
+        public void registerDataSetObserver(DataSetObserver observer) {
+        }
+
+        @Override
+        public void unregisterDataSetObserver(DataSetObserver observer) {
+        }
+
+        @Override
+        public int getCount() {
+            return mActivities.size();
+        }
+
+        @Override
+        public Object getItem(int position) {
+            return null;
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return position;
+        }
+
+        @Override
+        public boolean hasStableIds() {
+            return true;
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            final Context context = parent.getContext();
+            final PackageManager packageManager = context.getPackageManager();
+
+            // Lazy-create inflater
+            if (mInflater == null) {
+                mInflater = LayoutInflater.from(context);
+            }
+
+            // Use the convert-view where possible
+            if (convertView == null) {
+                convertView = mInflater.inflate(R.layout.external_widget_drop_list_item, parent,
+                        false);
+            }
+
+            final WidgetMimeTypeHandlerData data = mActivities.get(position);
+            final ResolveInfo resolveInfo = data.resolveInfo;
+            final AppWidgetProviderInfo widgetInfo = data.widgetInfo;
+
+            // Set the icon
+            Drawable d = resolveInfo.loadIcon(packageManager);
+            ImageView i = (ImageView) convertView.findViewById(R.id.provider_icon);
+            i.setImageDrawable(d);
+
+            // Set the text
+            final CharSequence component = resolveInfo.loadLabel(packageManager);
+            final int[] widgetSpan = new int[2];
+            mTargetLayout.rectToCell(widgetInfo.minWidth, widgetInfo.minHeight, widgetSpan);
+            TextView t = (TextView) convertView.findViewById(R.id.provider);
+            t.setText(context.getString(R.string.external_drop_widget_pick_format,
+                    component, widgetSpan[0], widgetSpan[1]));
+
+            return convertView;
+        }
+
+        @Override
+        public int getItemViewType(int position) {
+            return 0;
+        }
+
+        @Override
+        public int getViewTypeCount() {
+            return 1;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return mActivities.isEmpty();
+        }
+
+        @Override
+        public boolean areAllItemsEnabled() {
+            return false;
+        }
+
+        @Override
+        public boolean isEnabled(int position) {
+            return true;
+        }
+
+        @Override
+        public void onClick(DialogInterface dialog, int which) {
+            final LauncherModel model = mLauncher.getModel();
+            final AppWidgetProviderInfo widgetInfo = mActivities.get(which).widgetInfo;
+
+            final PendingAddWidgetInfo createInfo = new PendingAddWidgetInfo(widgetInfo, mMimeType,
+                    mClipData);
+            mLauncher.addAppWidgetFromDrop(createInfo, mTargetLayoutScreen, mTargetLayoutPos);
+        }
+    }
 }
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 0ac42dd..549303d 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -17,8 +17,13 @@
 
 package com.android.launcher2;
 
-import com.android.common.Search;
-import com.android.launcher.R;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
 
 import android.animation.Animator;
 import android.animation.AnimatorSet;
@@ -35,17 +40,19 @@
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.ActivityNotFoundException;
 import android.content.BroadcastReceiver;
+import android.content.ClipData;
+import android.content.ClipDescription;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.Intent.ShortcutIconResource;
+import android.content.IntentFilter;
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
@@ -78,9 +85,9 @@
 import android.view.MenuItem;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.View.OnLongClickListener;
 import android.view.ViewGroup;
 import android.view.WindowManager;
-import android.view.View.OnLongClickListener;
 import android.view.animation.AccelerateInterpolator;
 import android.view.animation.DecelerateInterpolator;
 import android.view.inputmethod.InputMethodManager;
@@ -89,18 +96,13 @@
 import android.widget.LinearLayout;
 import android.widget.PopupWindow;
 import android.widget.TabHost;
-import android.widget.TextView;
-import android.widget.Toast;
 import android.widget.TabHost.OnTabChangeListener;
 import android.widget.TabHost.TabContentFactory;
+import android.widget.TextView;
+import android.widget.Toast;
 
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
+import com.android.common.Search;
+import com.android.launcher.R;
 
 /**
  * Default launcher application.
@@ -1461,8 +1463,33 @@
             intent.setComponent(appWidget.configure);
             intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
             if (info != null) {
-                intent.putExtra(InstallWidgetReceiver.EXTRA_APPWIDGET_CONFIGURATION_DATA,
-                        info.configurationData);
+                if (info.mimeType != null && !info.mimeType.isEmpty()) {
+                    intent.putExtra(
+                            InstallWidgetReceiver.EXTRA_APPWIDGET_CONFIGURATION_DATA_MIME_TYPE,
+                            info.mimeType);
+
+                    final String mimeType = info.mimeType;
+                    final ClipData clipData = (ClipData) info.configurationData;
+                    final ClipDescription clipDesc = clipData.getDescription();
+                    for (int i = 0; i < clipDesc.getMimeTypeCount(); ++i) {
+                        if (clipDesc.getMimeType(i).equals(mimeType)) {
+                            final ClipData.Item item = clipData.getItem(i);
+                            final CharSequence stringData = item.getText();
+                            final Uri uriData = item.getUri();
+                            final Intent intentData = item.getIntent();
+                            final String key =
+                                InstallWidgetReceiver.EXTRA_APPWIDGET_CONFIGURATION_DATA;
+                            if (uriData != null) {
+                                intent.putExtra(key, uriData);
+                            } else if (intentData != null) {
+                                intent.putExtra(key, intentData);
+                            } else if (stringData != null) {
+                                intent.putExtra(key, stringData);
+                            }
+                            break;
+                        }
+                    }
+                }
             }
 
             startActivityForResultSafely(intent, REQUEST_CREATE_APPWIDGET);
diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java
index 423a9d1..713268a 100644
--- a/src/com/android/launcher2/LauncherModel.java
+++ b/src/com/android/launcher2/LauncherModel.java
@@ -16,7 +16,14 @@
 
 package com.android.launcher2;
 
-import com.android.launcher.R;
+import java.lang.ref.WeakReference;
+import java.net.URISyntaxException;
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
 
 import android.appwidget.AppWidgetManager;
 import android.appwidget.AppWidgetProviderInfo;
@@ -45,14 +52,8 @@
 import android.os.SystemClock;
 import android.util.Log;
 
-import java.lang.ref.WeakReference;
-import java.net.URISyntaxException;
-import java.text.Collator;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
+import com.android.launcher.R;
+import com.android.launcher2.InstallWidgetReceiver.WidgetMimeTypeHandlerData;
 
 /**
  * Maintains in-memory state of the Launcher. It is expected that there should be only one
@@ -1529,28 +1530,6 @@
     }
 
     /**
-     * Ensures that a given shortcut intent actually has all the fields that we need to create a
-     * proper ShortcutInfo.
-     */
-    boolean validateShortcutIntent(Intent data) {
-        // We don't require Intent.EXTRA_SHORTCUT_ICON, since we can pull a default fallback icon
-        return InstallShortcutReceiver.ACTION_INSTALL_SHORTCUT.equals(data.getAction()) &&
-                (data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME) != null) &&
-                (data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT) != null);
-    }
-
-    /**
-     * Ensures that a given widget intent actually has all the fields that we need to create a
-     * proper widget.
-     */
-    boolean validateWidgetIntent(Intent data) {
-        // We don't require Intent.EXTRA_APPWIDGET_CONFIGURATION_DATA, since that will just be
-        // forwarded onto the widget's configuration activity if it exists
-        return InstallWidgetReceiver.ACTION_INSTALL_WIDGET.equals(data.getAction()) &&
-                (data.getStringExtra(InstallWidgetReceiver.EXTRA_APPWIDGET_COMPONENT) != null);
-    }
-
-    /**
      * Attempts to find an AppWidgetProviderInfo that matches the given component.
      */
     AppWidgetProviderInfo findAppWidgetProviderInfoWithComponent(Context context,
@@ -1565,6 +1544,44 @@
         return null;
     }
 
+    /**
+     * Returns a list of all the widgets that can handle configuration with a particular mimeType.
+     */
+    List<WidgetMimeTypeHandlerData> resolveWidgetsForMimeType(Context context, String mimeType) {
+        final PackageManager packageManager = context.getPackageManager();
+        final List<WidgetMimeTypeHandlerData> supportedConfigurationActivities =
+            new ArrayList<WidgetMimeTypeHandlerData>();
+
+        final Intent supportsIntent =
+            new Intent(InstallWidgetReceiver.ACTION_SUPPORTS_CLIPDATA_MIMETYPE);
+        supportsIntent.setType(mimeType);
+
+        // Create a set of widget configuration components that we can test against
+        final List<AppWidgetProviderInfo> widgets =
+            AppWidgetManager.getInstance(context).getInstalledProviders();
+        final HashMap<ComponentName, AppWidgetProviderInfo> configurationComponentToWidget =
+            new HashMap<ComponentName, AppWidgetProviderInfo>();
+        for (AppWidgetProviderInfo info : widgets) {
+            configurationComponentToWidget.put(info.configure, info);
+        }
+
+        // Run through each of the intents that can handle this type of clip data, and cross
+        // reference them with the components that are actual configuration components
+        final List<ResolveInfo> activities = packageManager.queryIntentActivities(supportsIntent,
+                PackageManager.MATCH_DEFAULT_ONLY);
+        for (ResolveInfo info : activities) {
+            final ActivityInfo activityInfo = info.activityInfo;
+            final ComponentName infoComponent = new ComponentName(activityInfo.packageName,
+                    activityInfo.name);
+            if (configurationComponentToWidget.containsKey(infoComponent)) {
+                supportedConfigurationActivities.add(
+                        new InstallWidgetReceiver.WidgetMimeTypeHandlerData(info,
+                                configurationComponentToWidget.get(infoComponent)));
+            }
+        }
+        return supportedConfigurationActivities;
+    }
+
     ShortcutInfo infoFromShortcutIntent(Context context, Intent data, Bitmap fallbackIcon) {
         Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
         String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
diff --git a/src/com/android/launcher2/PendingAddItemInfo.java b/src/com/android/launcher2/PendingAddItemInfo.java
index b7a76f4..7b564e0 100644
--- a/src/com/android/launcher2/PendingAddItemInfo.java
+++ b/src/com/android/launcher2/PendingAddItemInfo.java
@@ -16,6 +16,7 @@
 
 package com.android.launcher2;
 
+import android.appwidget.AppWidgetProviderInfo;
 import android.content.ComponentName;
 import android.os.Parcelable;
 
@@ -35,5 +36,17 @@
 
     // Any configuration data that we want to pass to a configuration activity when
     // starting up a widget
+    String mimeType;
     Parcelable configurationData;
+
+    public PendingAddWidgetInfo(AppWidgetProviderInfo i, String dataMimeType, Parcelable data) {
+        itemType = LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET;
+        componentName = i.provider;
+        minWidth = i.minWidth;
+        minHeight = i.minHeight;
+        if (dataMimeType != null && data != null) {
+            mimeType = dataMimeType;
+            configurationData = data;
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index ddf441a..4679c64 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -16,17 +16,20 @@
 
 package com.android.launcher2;
 
-import com.android.launcher.R;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
 
 import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.animation.PropertyValuesHolder;
 import android.animation.TimeInterpolator;
 import android.animation.ValueAnimator;
-import android.animation.Animator.AnimatorListener;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.app.AlertDialog;
 import android.app.WallpaperManager;
 import android.appwidget.AppWidgetManager;
 import android.appwidget.AppWidgetProviderInfo;
@@ -59,8 +62,8 @@
 import android.widget.TextView;
 import android.widget.Toast;
 
-import java.util.ArrayList;
-import java.util.HashSet;
+import com.android.launcher.R;
+import com.android.launcher2.InstallWidgetReceiver.WidgetMimeTypeHandlerData;
 
 /**
  * The workspace is a wide area with a wallpaper and a finite number of pages.
@@ -1371,6 +1374,7 @@
      */
     @Override
     public boolean onDragEvent(DragEvent event) {
+        final ClipDescription desc = event.getClipDescription();
         final CellLayout layout = (CellLayout) getChildAt(mCurrentPage);
         final int[] pos = new int[2];
         layout.getLocationOnScreen(pos);
@@ -1387,23 +1391,19 @@
                 return false;
             }
 
-            ClipDescription desc = event.getClipDescription();
-            if (desc.filterMimeTypes(ClipDescription.MIMETYPE_TEXT_INTENT) != null) {
-                // Create the drag outline
-                // We need to add extra padding to the bitmap to make room for the glow effect
-                final Canvas canvas = new Canvas();
-                final int bitmapPadding = HolographicOutlineHelper.OUTER_BLUR_RADIUS;
-                mDragOutline = createExternalDragOutline(canvas, bitmapPadding);
+            // Create the drag outline
+            // We need to add extra padding to the bitmap to make room for the glow effect
+            final Canvas canvas = new Canvas();
+            final int bitmapPadding = HolographicOutlineHelper.OUTER_BLUR_RADIUS;
+            mDragOutline = createExternalDragOutline(canvas, bitmapPadding);
 
-                // Show the current page outlines to indicate that we can accept this drop
-                showOutlines();
-                layout.setHover(true);
-                layout.onDragEnter();
-                layout.visualizeDropLocation(null, mDragOutline, x, y, 1, 1);
+            // Show the current page outlines to indicate that we can accept this drop
+            showOutlines();
+            layout.setHover(true);
+            layout.onDragEnter();
+            layout.visualizeDropLocation(null, mDragOutline, x, y, 1, 1);
 
-                return true;
-            }
-            break;
+            return true;
         case DragEvent.ACTION_DRAG_LOCATION:
             // Visualize the drop location
             layout.visualizeDropLocation(null, mDragOutline, x, y, 1, 1);
@@ -1420,39 +1420,58 @@
             int newDropCount = 0;
             final LauncherModel model = mLauncher.getModel();
             final ClipData data = event.getClipData();
-            final int itemCount = data.getItemCount();
-            for (int i = 0; i < itemCount; ++i) {
-                final Intent intent = data.getItem(i).getIntent();
-                if (intent != null) {
-                    Object info = null;
-                    if (model.validateShortcutIntent(intent)) {
-                        info = model.infoFromShortcutIntent(mContext, intent, data.getIcon());
-                    } else if (model.validateWidgetIntent(intent)) {
-                        final ComponentName component = ComponentName.unflattenFromString(
-                            intent.getStringExtra(InstallWidgetReceiver.EXTRA_APPWIDGET_COMPONENT));
-                        final AppWidgetProviderInfo appInfo =
-                            model.findAppWidgetProviderInfoWithComponent(mContext, component);
 
-                        PendingAddWidgetInfo createInfo = new PendingAddWidgetInfo();
-                        createInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET;
-                        createInfo.componentName = appInfo.provider;
-                        createInfo.minWidth = appInfo.minWidth;
-                        createInfo.minHeight = appInfo.minHeight;
-                        createInfo.configurationData = intent.getParcelableExtra(
-                                InstallWidgetReceiver.EXTRA_APPWIDGET_CONFIGURATION_DATA);
-                        info = createInfo;
-                    }
+            // We assume that the mime types are ordered in descending importance of
+            // representation. So we enumerate the list of mime types and alert the
+            // user if any widgets can handle the drop.  Only the most preferred
+            // representation will be handled.
+            pos[0] = x;
+            pos[1] = y;
+            final int mimeTypeCount = desc.getMimeTypeCount();
+            for (int j = 0; j < mimeTypeCount; ++j) {
+                final String mimeType = desc.getMimeType(j);
 
-                    if (info != null) {
-                        onDropExternal(x, y, info, layout);
-                        newDropCount++;
+                if (mimeType.equals(InstallShortcutReceiver.SHORTCUT_MIMETYPE)) {
+                    final Intent intent = data.getItem(j).getIntent();
+                    Object info = model.infoFromShortcutIntent(mContext, intent, data.getIcon());
+                    onDropExternal(x, y, info, layout);
+                } else {
+                    final List<WidgetMimeTypeHandlerData> widgets =
+                        model.resolveWidgetsForMimeType(mContext, mimeType);
+                    final int numWidgets = widgets.size();
+
+                    if (numWidgets == 0) {
+                        continue;
+                    } else if (numWidgets == 1) {
+                        // If there is only one item, then go ahead and add and configure
+                        // that widget
+                        final AppWidgetProviderInfo widgetInfo = widgets.get(0).widgetInfo;
+                        final PendingAddWidgetInfo createInfo =
+                                new PendingAddWidgetInfo(widgetInfo, mimeType, data);
+                        mLauncher.addAppWidgetFromDrop(createInfo, mCurrentPage, pos);
+                    } else if (numWidgets > 1) {
+                        // Show the widget picker dialog if there is more than one widget
+                        // that can handle this data type
+                        final InstallWidgetReceiver.WidgetListAdapter adapter =
+                            new InstallWidgetReceiver.WidgetListAdapter(mLauncher, mimeType,
+                                    data, widgets, layout, mCurrentPage, pos);
+                        final AlertDialog.Builder builder =
+                            new AlertDialog.Builder(mContext);
+                        builder.setAdapter(adapter, adapter);
+                        builder.setCancelable(true);
+                        builder.setTitle(mContext.getString(
+                                R.string.external_drop_widget_pick_title));
+                        builder.setIcon(R.drawable.ic_no_applications);
+                        builder.show();
                     }
                 }
+                newDropCount++;
+                break;
             }
 
             // Show error message if we couldn't accept any of the items
             if (newDropCount <= 0) {
-                Toast.makeText(mContext, "Only Shortcut Intents accepted.",
+                Toast.makeText(mContext, mContext.getString(R.string.external_drop_widget_error),
                         Toast.LENGTH_SHORT).show();
             }