--- /dev/null
+/*
+ * 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";
+}
// 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) {
mAddDropPosition = null;
}
- void addAppWidgetFromDrop(ComponentName appWidgetProvider, int screen, int[] position) {
+ void addAppWidgetFromDrop(PendingAddWidgetInfo info, int screen, int[] position) {
resetAddInfo();
mAddScreen = screen;
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() {
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) {
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 {
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;
/**
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) {
package com.android.launcher2;
import android.content.ComponentName;
+import android.os.Parcelable;
/**
* We pass this object with a drag from the customization tray
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
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;
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++;
+ }
}
}
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();
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);