OSDN Git Service

Adding initial support for dropping widgets with custom configuration data.
authorWinson Chung <winsonc@google.com>
Thu, 28 Oct 2010 21:14:18 +0000 (14:14 -0700)
committerWinson Chung <winsonc@google.com>
Thu, 28 Oct 2010 23:08:46 +0000 (16:08 -0700)
Change-Id: I4a7ba51783b27e544e9a21882bc7cd582b3b43e0

src/com/android/launcher2/InstallWidgetReceiver.java [new file with mode: 0644]
src/com/android/launcher2/Launcher.java
src/com/android/launcher2/LauncherModel.java
src/com/android/launcher2/PendingAddItemInfo.java
src/com/android/launcher2/Workspace.java

diff --git a/src/com/android/launcher2/InstallWidgetReceiver.java b/src/com/android/launcher2/InstallWidgetReceiver.java
new file mode 100644 (file)
index 0000000..e6a9a69
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2010 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.launcher2;
+
+
+/**
+ * We will likely flesh this out later, to handle allow external apps to place widgets, but for now,
+ * we just want to expose the action around for checking elsewhere.
+ */
+public class InstallWidgetReceiver {
+    public static final String ACTION_INSTALL_WIDGET =
+            "com.android.launcher.action.INSTALL_WIDGET";
+
+    // 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 =
+        "com.android.launcher.extra.widget.CONFIGURATION_DATA";
+}
index 961acfe..71978fa 100644 (file)
@@ -1083,8 +1083,10 @@ public final class Launcher extends Activity
         // For now, we don't save the coordinate where we dropped the icon because we're not
         // supporting spring-loaded mini-screens; however, leaving the ability to directly place
         // a widget on the home screen in case we want to add it in the future
-        final int[] touchXY = null;
-        //final int[] touchXY = mAddDropPosition;
+        int[] touchXY = null;
+        if (mAddDropPosition[0] > -1 && mAddDropPosition[1] > -1) {
+            touchXY = mAddDropPosition;
+        }
         boolean findNearestVacantAreaFailed = false;
         boolean foundCellSpan = false;
         if (touchXY != null) {
@@ -1429,7 +1431,7 @@ public final class Launcher extends Activity
         mAddDropPosition = null;
     }
 
-    void addAppWidgetFromDrop(ComponentName appWidgetProvider, int screen, int[] position) {
+    void addAppWidgetFromDrop(PendingAddWidgetInfo info, int screen, int[] position) {
         resetAddInfo();
         mAddScreen = screen;
 
@@ -1437,8 +1439,8 @@ public final class Launcher extends Activity
         mAddDropPosition = position;
 
         int appWidgetId = getAppWidgetHost().allocateAppWidgetId();
-        AppWidgetManager.getInstance(this).bindAppWidgetId(appWidgetId, appWidgetProvider);
-        addAppWidgetImpl(appWidgetId);
+        AppWidgetManager.getInstance(this).bindAppWidgetId(appWidgetId, info.componentName);
+        addAppWidgetImpl(appWidgetId, info);
     }
 
     private void manageApps() {
@@ -1450,10 +1452,10 @@ public final class Launcher extends Activity
         int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
         // TODO: Is this log message meaningful?
         if (LOGD) Log.d(TAG, "dumping extras content=" + data.getExtras());
-        addAppWidgetImpl(appWidgetId);
+        addAppWidgetImpl(appWidgetId, null);
     }
 
-    void addAppWidgetImpl(int appWidgetId) {
+    void addAppWidgetImpl(int appWidgetId, PendingAddWidgetInfo info) {
         AppWidgetProviderInfo appWidget = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
 
         if (appWidget.configure != null) {
@@ -1461,6 +1463,10 @@ public final class Launcher extends Activity
             Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
             intent.setComponent(appWidget.configure);
             intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
+            if (info != null) {
+                intent.putExtra(InstallWidgetReceiver.EXTRA_APPWIDGET_CONFIGURATION_DATA,
+                        info.configurationData);
+            }
 
             startActivityForResultSafely(intent, REQUEST_CREATE_APPWIDGET);
         } else {
index 179a5d5..aa259aa 100644 (file)
@@ -52,16 +52,6 @@ import android.os.RemoteException;
 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.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-
 import com.android.launcher.R;
 
 /**
@@ -1527,8 +1517,34 @@ public class LauncherModel extends BroadcastReceiver {
     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.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT) != null) &&
-                (data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME) != null);
+                (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,
+            ComponentName component) {
+        List<AppWidgetProviderInfo> widgets =
+            AppWidgetManager.getInstance(context).getInstalledProviders();
+        for (AppWidgetProviderInfo info : widgets) {
+            if (info.provider.equals(component)) {
+                return info;
+            }
+        }
+        return null;
     }
 
     ShortcutInfo infoFromShortcutIntent(Context context, Intent data, Bitmap fallbackIcon) {
index 904f512..b7a76f4 100644 (file)
@@ -17,6 +17,7 @@
 package com.android.launcher2;
 
 import android.content.ComponentName;
+import android.os.Parcelable;
 
 /**
  * We pass this object with a drag from the customization tray
@@ -31,4 +32,8 @@ class PendingAddItemInfo extends ItemInfo {
 class PendingAddWidgetInfo extends PendingAddItemInfo {
     int minWidth;
     int minHeight;
+
+    // Any configuration data that we want to pass to a configuration activity when
+    // starting up a widget
+    Parcelable configurationData;
 }
\ No newline at end of file
index 239f6de..e37907c 100644 (file)
@@ -39,7 +39,6 @@ import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
-import android.graphics.Color;
 import android.graphics.Matrix;
 import android.graphics.Paint;
 import android.graphics.Rect;
@@ -1281,11 +1280,30 @@ public class Workspace extends SmoothPagedView
             final int itemCount = data.getItemCount();
             for (int i = 0; i < itemCount; ++i) {
                 final Intent intent = data.getItem(i).getIntent();
-                if (intent != null && model.validateShortcutIntent(intent)) {
-                    ShortcutInfo info = model.infoFromShortcutIntent(mContext, intent, data.
-                            getIcon());
-                    onDropExternal(x, y, info, layout);
-                    newDropCount++;
+                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;
+                    }
+
+                    if (info != null) {
+                        onDropExternal(x, y, info, layout);
+                        newDropCount++;
+                    }
                 }
             }
 
@@ -1552,7 +1570,7 @@ public class Workspace extends SmoothPagedView
         ItemInfo info = (ItemInfo) dragInfo;
 
         if (cl.findCellForSpan(mTempEstimate, info.spanX, info.spanY)) {
-            onDropExternal(0, 0, dragInfo, cl, false);
+            onDropExternal(-1, -1, dragInfo, cl, false);
             return true;
         }
         mLauncher.showOutOfSpaceMessage();
@@ -1574,7 +1592,7 @@ public class Workspace extends SmoothPagedView
             touchXY[1] = y;
             switch (info.itemType) {
                 case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
-                    mLauncher.addAppWidgetFromDrop(info.componentName, screen, touchXY);
+                    mLauncher.addAppWidgetFromDrop((PendingAddWidgetInfo) info, screen, touchXY);
                     break;
                 case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
                     mLauncher.addLiveFolderFromDrop(info.componentName, screen, touchXY);