summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AndroidManifest-common.xml8
-rw-r--r--res/drawable/bg_drag_box.xml25
-rw-r--r--res/layout/add_item_confirmation_activity.xml55
-rw-r--r--res/values/strings.xml4
-rw-r--r--src/com/android/launcher3/BaseActivity.java42
-rw-r--r--src/com/android/launcher3/InstallShortcutReceiver.java4
-rw-r--r--src/com/android/launcher3/InvariantDeviceProfile.java6
-rw-r--r--src/com/android/launcher3/Launcher.java18
-rw-r--r--src/com/android/launcher3/WidgetPreviewLoader.java8
-rw-r--r--src/com/android/launcher3/compat/PinItemRequestCompat.java83
-rw-r--r--src/com/android/launcher3/dragndrop/AddItemActivity.java207
-rw-r--r--src/com/android/launcher3/model/AddWorkspaceItemsTask.java7
-rw-r--r--src/com/android/launcher3/widget/WidgetCell.java12
13 files changed, 451 insertions, 28 deletions
diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml
index bbe1f4a88..974b0df45 100644
--- a/AndroidManifest-common.xml
+++ b/AndroidManifest-common.xml
@@ -79,5 +79,13 @@
<meta-data android:name="android.nfc.disable_beam_default"
android:value="true" />
+ <activity android:name="com.android.launcher3.dragndrop.AddItemActivity"
+ android:theme="@android:style/Theme.DeviceDefault.Light.Dialog.Alert"
+ android:label="@string/action_add_to_workspace" >
+ <intent-filter>
+ <action android:name="android.content.pm.action.CONFIRM_PIN_ITEM" />
+ </intent-filter>
+ </activity>
+
</application>
</manifest>
diff --git a/res/drawable/bg_drag_box.xml b/res/drawable/bg_drag_box.xml
new file mode 100644
index 000000000..49b3b8618
--- /dev/null
+++ b/res/drawable/bg_drag_box.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle" >
+ <stroke android:color="?android:attr/colorAccent"
+ android:dashGap="2dp"
+ android:dashWidth="4dp"
+ android:width="1dp" />
+</shape>
diff --git a/res/layout/add_item_confirmation_activity.xml b/res/layout/add_item_confirmation_activity.xml
new file mode 100644
index 000000000..46d34447d
--- /dev/null
+++ b/res/layout/add_item_confirmation_activity.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <TextView
+ android:padding="16dp"
+ android:text="@string/add_item_request_drag_hint"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="100dp"
+ android:layout_margin="10dp"
+ android:gravity="center"
+ android:id="@+id/drag_target"
+ android:background="@drawable/bg_drag_box" />
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="?android:attr/buttonBarStyle"
+ android:gravity="end" >
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@android:string/cancel"
+ android:onClick="onCancelClick"
+ style="?android:attr/buttonBarButtonStyle" />
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/place_automatically"
+ android:onClick="onPlaceAutomaticallyClick"
+ style="?android:attr/buttonBarButtonStyle" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a9c970d6d..f1de62378 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -52,6 +52,10 @@
<string name="widget_dims_format">%1$d \u00d7 %2$d</string>
<!-- Accessibility spoken message format for the dimensions of a widget in the drawer -->
<string name="widget_accessible_dims_format">%1$d wide by %2$d high</string>
+ <!-- Message to tell the user to press and hold a widget/icon to add it -->
+ <string name="add_item_request_drag_hint" translatable="false">Touch &amp; hold to place on home screen</string>
+ <!-- Button label to automatically add icon on home screen [CHAR_LIMIT=50] -->
+ <string name="place_automatically" translatable="false">Place automatically</string>
<!-- All Apps -->
<!-- Search bar text in the apps view. [CHAR_LIMIT=50] -->
diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java
new file mode 100644
index 000000000..9f4f1f9c4
--- /dev/null
+++ b/src/com/android/launcher3/BaseActivity.java
@@ -0,0 +1,42 @@
+/*
+ * 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;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.view.View.AccessibilityDelegate;
+
+public abstract class BaseActivity extends Activity {
+
+ protected DeviceProfile mDeviceProfile;
+
+ public DeviceProfile getDeviceProfile() {
+ return mDeviceProfile;
+ }
+
+ public AccessibilityDelegate getAccessibilityDelegate() {
+ return null;
+ }
+
+ public static BaseActivity fromContext(Context context) {
+ if (context instanceof BaseActivity) {
+ return (BaseActivity) context;
+ }
+ return ((BaseActivity) ((ContextWrapper) context).getBaseContext());
+ }
+}
diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java
index a35469e0c..96d6b895c 100644
--- a/src/com/android/launcher3/InstallShortcutReceiver.java
+++ b/src/com/android/launcher3/InstallShortcutReceiver.java
@@ -498,7 +498,9 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
DeepShortcutManager sm = DeepShortcutManager.getInstance(context);
List<ShortcutInfoCompat> si = sm.queryForFullDetails(
decoder.launcherIntent.getPackage(),
- Arrays.asList(ShortcutInfoCompat.EXTRA_SHORTCUT_ID), decoder.user);
+ Arrays.asList(decoder.launcherIntent.getStringExtra(
+ ShortcutInfoCompat.EXTRA_SHORTCUT_ID)),
+ decoder.user);
if (si.isEmpty()) {
return null;
} else {
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 1b0e5b371..e3c6965f7 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -18,6 +18,7 @@ package com.android.launcher3;
import android.annotation.TargetApi;
import android.content.Context;
+import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.graphics.Point;
@@ -326,6 +327,11 @@ public class InvariantDeviceProfile {
return rank == getAllAppsButtonRank();
}
+ public DeviceProfile getDeviceProfile(Context context) {
+ return context.getResources().getConfiguration().orientation
+ == Configuration.ORIENTATION_LANDSCAPE ? landscapeProfile : portraitProfile;
+ }
+
private float weight(float x0, float y0, float x1, float y1, float pow) {
float d = dist(x0, y0, x1, y1);
if (Float.compare(d, 0f) == 0) {
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index fc112f380..13534b97b 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -22,7 +22,6 @@ import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
-import android.app.Activity;
import android.app.ActivityOptions;
import android.app.AlertDialog;
import android.app.SearchManager;
@@ -42,7 +41,6 @@ import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
-import android.content.res.Configuration;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Point;
import android.graphics.Rect;
@@ -136,7 +134,7 @@ import java.util.List;
/**
* Default launcher application.
*/
-public class Launcher extends Activity
+public class Launcher extends BaseActivity
implements LauncherExterns, View.OnClickListener, OnLongClickListener,
LauncherModel.Callbacks, View.OnTouchListener, LauncherProviderChangeListener,
AccessibilityManager.AccessibilityStateChangeListener {
@@ -194,7 +192,7 @@ public class Launcher extends Activity
private boolean mIsSafeModeEnabled;
- static final int APPWIDGET_HOST_ID = 1024;
+ public static final int APPWIDGET_HOST_ID = 1024;
public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 500;
private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;
private static final int ACTIVITY_START_DELAY = 1000;
@@ -273,8 +271,6 @@ public class Launcher extends Activity
// it from the context.
private SharedPreferences mSharedPrefs;
- private DeviceProfile mDeviceProfile;
-
private boolean mMoveToDefaultScreenFromNewIntent;
// This is set to the view that launched the activity that navigated the user away from
@@ -359,11 +355,7 @@ public class Launcher extends Activity
LauncherAppState app = LauncherAppState.getInstance(this);
// Load configuration-specific DeviceProfile
- mDeviceProfile =
- getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE
- ? app.getInvariantDeviceProfile().landscapeProfile
- : app.getInvariantDeviceProfile().portraitProfile;
-
+ mDeviceProfile = app.getInvariantDeviceProfile().getDeviceProfile(this);
if (Utilities.ATLEAST_NOUGAT && isInMultiWindowMode()) {
Display display = getWindowManager().getDefaultDisplay();
Point mwSize = new Point();
@@ -1657,10 +1649,6 @@ public class Launcher extends Activity
return mSharedPrefs;
}
- public DeviceProfile getDeviceProfile() {
- return mDeviceProfile;
- }
-
@Override
protected void onNewIntent(Intent intent) {
long startTime = 0;
diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java
index 0f62b31c1..83c978e95 100644
--- a/src/com/android/launcher3/WidgetPreviewLoader.java
+++ b/src/com/android/launcher3/WidgetPreviewLoader.java
@@ -272,7 +272,7 @@ public class WidgetPreviewLoader {
return null;
}
- private Bitmap generatePreview(Launcher launcher, WidgetItem item, Bitmap recycle,
+ private Bitmap generatePreview(BaseActivity launcher, WidgetItem item, Bitmap recycle,
int previewWidth, int previewHeight) {
if (item.widgetInfo != null) {
return generateWidgetPreview(launcher, item.widgetInfo,
@@ -294,7 +294,7 @@ public class WidgetPreviewLoader {
* @param preScaledWidthOut return the width of the returned bitmap
* @return
*/
- public Bitmap generateWidgetPreview(Launcher launcher, LauncherAppWidgetProviderInfo info,
+ public Bitmap generateWidgetPreview(BaseActivity launcher, LauncherAppWidgetProviderInfo info,
int maxPreviewWidth, Bitmap preview, int[] preScaledWidthOut) {
// Load the preview image if possible
if (maxPreviewWidth < 0) maxPreviewWidth = Integer.MAX_VALUE;
@@ -415,7 +415,7 @@ public class WidgetPreviewLoader {
}
private Bitmap generateShortcutPreview(
- Launcher launcher, ActivityInfo info, int maxWidth, int maxHeight, Bitmap preview) {
+ BaseActivity launcher, ActivityInfo info, int maxWidth, int maxHeight, Bitmap preview) {
final Canvas c = new Canvas();
if (preview == null) {
preview = Bitmap.createBitmap(maxWidth, maxHeight, Config.ARGB_8888);
@@ -591,7 +591,7 @@ public class WidgetPreviewLoader {
// which would gets re-written next time.
mVersions = getPackageVersion(mKey.componentName.getPackageName());
- Launcher launcher = Launcher.getLauncher(mCaller.getContext());
+ BaseActivity launcher = BaseActivity.fromContext(mCaller.getContext());
// it's not in the db... we need to generate it
preview = generatePreview(launcher, mInfo, unusedBitmap, mPreviewWidth, mPreviewHeight);
diff --git a/src/com/android/launcher3/compat/PinItemRequestCompat.java b/src/com/android/launcher3/compat/PinItemRequestCompat.java
new file mode 100644
index 000000000..956b38cb1
--- /dev/null
+++ b/src/com/android/launcher3/compat/PinItemRequestCompat.java
@@ -0,0 +1,83 @@
+/*
+ * 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.compat;
+
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.Intent;
+import android.content.pm.ShortcutInfo;
+import android.os.Bundle;
+import android.os.Parcelable;
+
+/**
+ * A wrapper around platform implementation of PinItemRequestCompat until the
+ * updated SDK is available.
+ */
+public class PinItemRequestCompat {
+
+ public static final String EXTRA_PIN_ITEM_REQUEST = "android.content.pm.extra.PIN_ITEM_REQUEST";
+
+ public static final int REQUEST_TYPE_SHORTCUT = 1;
+ public static final int REQUEST_TYPE_APPWIDGET = 2;
+
+ private final Parcelable mObject;
+
+ private PinItemRequestCompat(Parcelable object) {
+ mObject = object;
+ }
+
+ public int getRequestType() {
+ return (Integer) invokeMethod("getRequestType");
+ }
+
+ public ShortcutInfo getShortcutInfo() {
+ return (ShortcutInfo) invokeMethod("getShortcutInfo");
+ }
+
+ public AppWidgetProviderInfo getAppWidgetProviderInfo() {
+ return (AppWidgetProviderInfo) invokeMethod("getAppWidgetProviderInfo");
+ }
+
+ public boolean isValid() {
+ return (Boolean) invokeMethod("isValid");
+ }
+
+ public boolean accept() {
+ return (Boolean) invokeMethod("accept");
+ }
+
+ public boolean accept(Bundle options) {
+ try {
+ return (Boolean) mObject.getClass().getDeclaredMethod("accept", Bundle.class)
+ .invoke(mObject, options);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private Object invokeMethod(String methodName) {
+ try {
+ return mObject.getClass().getDeclaredMethod(methodName).invoke(mObject);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static PinItemRequestCompat getPinItemRequest(Intent intent) {
+ Parcelable extra = intent.getParcelableExtra(EXTRA_PIN_ITEM_REQUEST);
+ return extra == null ? null : new PinItemRequestCompat(extra);
+ }
+}
diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java
new file mode 100644
index 000000000..c48db60fa
--- /dev/null
+++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java
@@ -0,0 +1,207 @@
+/*
+ * 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.dragndrop;
+
+import android.annotation.TargetApi;
+import android.appwidget.AppWidgetHost;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.os.Build;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.TextView;
+
+import com.android.launcher3.BaseActivity;
+import com.android.launcher3.FastBitmapDrawable;
+import com.android.launcher3.InstallShortcutReceiver;
+import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherAppWidgetProviderInfo;
+import com.android.launcher3.R;
+import com.android.launcher3.compat.AppWidgetManagerCompat;
+import com.android.launcher3.compat.PinItemRequestCompat;
+import com.android.launcher3.graphics.LauncherIcons;
+import com.android.launcher3.shortcuts.DeepShortcutManager;
+import com.android.launcher3.shortcuts.ShortcutInfoCompat;
+import com.android.launcher3.widget.PendingAddWidgetInfo;
+import com.android.launcher3.widget.WidgetHostViewLoader;
+
+@TargetApi(Build.VERSION_CODES.N_MR1)
+public class AddItemActivity extends BaseActivity {
+
+ private static final int REQUEST_BIND_APPWIDGET = 1;
+ private static final String STATE_EXTRA_WIDGET_ID = "state.widget.id";
+
+ private PinItemRequestCompat mRequest;
+ private LauncherAppState mApp;
+ private InvariantDeviceProfile mIdp;
+
+ private TextView mTextView;
+
+ // Widget request specific options.
+ private AppWidgetHost mAppWidgetHost;
+ private AppWidgetManagerCompat mAppWidgetManager;
+ private PendingAddWidgetInfo mPendingWidgetInfo;
+ private int mPendingBindWidgetId;
+ private Bundle mWidgetOptions;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mRequest = PinItemRequestCompat.getPinItemRequest(getIntent());
+ if (mRequest == null) {
+ finish();
+ return;
+ }
+
+ setContentView(R.layout.add_item_confirmation_activity);
+ mTextView = (TextView) findViewById(R.id.drag_target);
+
+ mApp = LauncherAppState.getInstance(this);
+ mIdp = mApp.getInvariantDeviceProfile();
+
+ // Use the application context to get the device profile, as in multiwindow-mode, the
+ // confirmation activity might be rotated.
+ mDeviceProfile = mIdp.getDeviceProfile(getApplicationContext());
+
+ if (mRequest.getRequestType() == PinItemRequestCompat.REQUEST_TYPE_SHORTCUT) {
+ setupShortcut();
+ } else {
+ if (!setupWidget()) {
+ // TODO: show error toast?
+ finish();
+ }
+ }
+ }
+
+ private void setupShortcut() {
+ ShortcutInfoCompat shortcut = new ShortcutInfoCompat(mRequest.getShortcutInfo());
+ FastBitmapDrawable d = new FastBitmapDrawable(LauncherIcons.createIconBitmap(
+ DeepShortcutManager.getInstance(this).getShortcutIconDrawable(
+ shortcut, mIdp.fillResIconDpi), this));
+ d.setFilterBitmap(true);
+ mTextView.setText(TextUtils.isEmpty(shortcut.getLongLabel())
+ ? shortcut.getShortLabel() : shortcut.getLongLabel());
+ mTextView.setCompoundDrawables(null, d, null, null);
+ }
+
+ private boolean setupWidget() {
+ AppWidgetProviderInfo info = mRequest.getAppWidgetProviderInfo();
+ LauncherAppWidgetProviderInfo widgetInfo = AppWidgetManagerCompat.getInstance(this)
+ .findProvider(info.provider, info.getProfile());
+ if (widgetInfo.minSpanX > mIdp.numColumns || widgetInfo.minSpanY > mIdp.numRows) {
+ // Cannot add widget
+ return false;
+ }
+
+ mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);
+ mAppWidgetHost = new AppWidgetHost(this, Launcher.APPWIDGET_HOST_ID);
+
+ mPendingWidgetInfo = new PendingAddWidgetInfo(widgetInfo);
+ mPendingWidgetInfo.spanX = Math.min(mIdp.numColumns, widgetInfo.spanX);
+ mPendingWidgetInfo.spanY = Math.min(mIdp.numRows, widgetInfo.spanY);
+ mWidgetOptions = WidgetHostViewLoader.getDefaultOptionsForWidget(this, mPendingWidgetInfo);
+
+ Bitmap preview = mApp.getWidgetCache().generateWidgetPreview(this, widgetInfo,
+ mPendingWidgetInfo.spanX * mDeviceProfile.cellWidthPx, null, null);
+ FastBitmapDrawable d = new FastBitmapDrawable(preview);
+ d.setFilterBitmap(true);
+ mTextView.setText(widgetInfo.getLabel(getPackageManager()));
+ mTextView.setCompoundDrawables(null, d, null, null);
+ return true;
+ }
+
+ /**
+ * Called when the cancel button is clicked.
+ */
+ public void onCancelClick(View v) {
+ finish();
+ }
+
+ /**
+ * Called when place-automatically button is clicked.
+ */
+ public void onPlaceAutomaticallyClick(View v) {
+ if (mRequest.getRequestType() == PinItemRequestCompat.REQUEST_TYPE_SHORTCUT) {
+ InstallShortcutReceiver.queueShortcut(
+ new ShortcutInfoCompat(mRequest.getShortcutInfo()), this);
+ mRequest.accept();
+ finish();
+ return;
+ }
+
+ mPendingBindWidgetId = mAppWidgetHost.allocateAppWidgetId();
+ boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(
+ mPendingBindWidgetId, mRequest.getAppWidgetProviderInfo(), mWidgetOptions);
+ if (success) {
+ acceptWidget(mPendingBindWidgetId);
+ return;
+ }
+
+ // request bind widget
+ Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
+ intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mPendingBindWidgetId);
+ intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER,
+ mPendingWidgetInfo.componentName);
+ intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE,
+ mRequest.getAppWidgetProviderInfo().getProfile());
+ startActivityForResult(intent, REQUEST_BIND_APPWIDGET);
+ }
+
+ private void acceptWidget(int widgetId) {
+ InstallShortcutReceiver.queueWidget(mRequest.getAppWidgetProviderInfo(), widgetId, this);
+ mWidgetOptions.putInt(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
+ mRequest.accept(mWidgetOptions);
+ finish();
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == REQUEST_BIND_APPWIDGET) {
+ int widgetId = data != null
+ ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mPendingBindWidgetId)
+ : mPendingBindWidgetId;
+ if (resultCode == RESULT_OK) {
+ acceptWidget(widgetId);
+ } else {
+ // Simply wait it out.
+ mAppWidgetHost.deleteAppWidgetId(widgetId);
+ mPendingBindWidgetId = -1;
+ }
+ return;
+ }
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putInt(STATE_EXTRA_WIDGET_ID, mPendingBindWidgetId);
+ }
+
+ @Override
+ protected void onRestoreInstanceState(Bundle savedInstanceState) {
+ super.onRestoreInstanceState(savedInstanceState);
+ mPendingBindWidgetId = savedInstanceState
+ .getInt(STATE_EXTRA_WIDGET_ID, mPendingBindWidgetId);
+ }
+}
diff --git a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
index a03dd8f34..c97b3b5cf 100644
--- a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
+++ b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
@@ -70,7 +70,8 @@ public class AddWorkspaceItemsTask extends ExtendedModelTask {
ArrayList<Long> workspaceScreens = LauncherModel.loadWorkspaceScreensDb(context);
synchronized(dataModel) {
for (ItemInfo item : workspaceApps) {
- if (item instanceof ShortcutInfo) {
+ if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
+ item.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
// Short-circuit this logic if the icon exists somewhere on the workspace
if (shortcutExists(dataModel, item.getIntent(), item.user)) {
continue;
@@ -143,6 +144,10 @@ public class AddWorkspaceItemsTask extends ExtendedModelTask {
*/
protected boolean shortcutExists(BgDataModel dataModel, Intent intent, UserHandle user) {
final String intentWithPkg, intentWithoutPkg;
+ if (intent == null) {
+ // Skip items with null intents
+ return true;
+ }
if (intent.getComponent() != null) {
// If component is not null, an intent with null package will produce
// the same result and should also be a match.
diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java
index 5eeae87e2..9e2091b50 100644
--- a/src/com/android/launcher3/widget/WidgetCell.java
+++ b/src/com/android/launcher3/widget/WidgetCell.java
@@ -17,7 +17,6 @@
package com.android.launcher3.widget;
import android.content.Context;
-import android.content.res.Resources;
import android.graphics.Bitmap;
import android.util.AttributeSet;
import android.util.Log;
@@ -28,8 +27,8 @@ import android.view.ViewPropertyAnimator;
import android.widget.LinearLayout;
import android.widget.TextView;
+import com.android.launcher3.BaseActivity;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.SimpleOnStylusPressListener;
import com.android.launcher3.StylusEventHelper;
@@ -72,7 +71,7 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener {
private PreviewLoadRequest mActiveRequest;
private StylusEventHelper mStylusEventHelper;
- private final Launcher mLauncher;
+ private final BaseActivity mActivity;
public WidgetCell(Context context) {
this(context, null);
@@ -85,18 +84,17 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener {
public WidgetCell(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- final Resources r = context.getResources();
- mLauncher = Launcher.getLauncher(context);
+ mActivity = BaseActivity.fromContext(context);
mStylusEventHelper = new StylusEventHelper(new SimpleOnStylusPressListener(this), this);
setContainerWidth();
setWillNotDraw(false);
setClipToPadding(false);
- setAccessibilityDelegate(mLauncher.getAccessibilityDelegate());
+ setAccessibilityDelegate(mActivity.getAccessibilityDelegate());
}
private void setContainerWidth() {
- DeviceProfile profile = mLauncher.getDeviceProfile();
+ DeviceProfile profile = mActivity.getDeviceProfile();
cellSize = (int) (profile.cellWidthPx * WIDTH_SCALE);
mPresetPreviewSize = (int) (cellSize * PREVIEW_SCALE);
}