summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSunny Goyal <sunnygoyal@google.com>2015-04-10 13:45:42 -0700
committerSunny Goyal <sunnygoyal@google.com>2015-04-16 15:52:04 -0700
commitfa401a10e7e9341daf6f3c5949bf9331902c26d0 (patch)
tree28e3834dee3afe2acfed418a05a599541ceacb6d /src
parentfb9ca2392894a3dea83570267f9597ac0750b9fd (diff)
downloadandroid_packages_apps_Trebuchet-fa401a10e7e9341daf6f3c5949bf9331902c26d0.tar.gz
android_packages_apps_Trebuchet-fa401a10e7e9341daf6f3c5949bf9331902c26d0.tar.bz2
android_packages_apps_Trebuchet-fa401a10e7e9341daf6f3c5949bf9331902c26d0.zip
Updating drop button targets
> Splitting DeleteDropTarget into delete and uninstall > Showing UninstallDropTarget for app shortcuts on workspace > Showing InfoDropTarget only when developer options is enabled Change-Id: I4396571d2199d1581bb9c733aef88ab9b0ebd79d
Diffstat (limited to 'src')
-rw-r--r--src/com/android/launcher3/AppsContainerView.java3
-rw-r--r--src/com/android/launcher3/ButtonDropTarget.java132
-rw-r--r--src/com/android/launcher3/DeleteDropTarget.java278
-rw-r--r--src/com/android/launcher3/DragController.java9
-rw-r--r--src/com/android/launcher3/DropTarget.java4
-rw-r--r--src/com/android/launcher3/Folder.java5
-rw-r--r--src/com/android/launcher3/InfoDropTarget.java85
-rw-r--r--src/com/android/launcher3/LauncherAccessibilityDelegate.java3
-rw-r--r--src/com/android/launcher3/LauncherModel.java10
-rw-r--r--src/com/android/launcher3/SearchDropTargetBar.java17
-rw-r--r--src/com/android/launcher3/UninstallDropTarget.java122
-rw-r--r--src/com/android/launcher3/Workspace.java5
12 files changed, 299 insertions, 374 deletions
diff --git a/src/com/android/launcher3/AppsContainerView.java b/src/com/android/launcher3/AppsContainerView.java
index 52bc6b6ef..5f1594f28 100644
--- a/src/com/android/launcher3/AppsContainerView.java
+++ b/src/com/android/launcher3/AppsContainerView.java
@@ -34,6 +34,7 @@ import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
+
import com.android.launcher3.util.Thunk;
import java.util.List;
@@ -286,7 +287,7 @@ public class AppsContainerView extends FrameLayout implements DragSource, Insett
@Override
public boolean supportsDeleteDropTarget() {
- return true;
+ return false;
}
@Override
diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java
index 019f86c21..5b399087a 100644
--- a/src/com/android/launcher3/ButtonDropTarget.java
+++ b/src/com/android/launcher3/ButtonDropTarget.java
@@ -17,19 +17,29 @@
package com.android.launcher3;
import android.content.Context;
+import android.content.res.ColorStateList;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.TransitionDrawable;
import android.util.AttributeSet;
import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.LinearInterpolator;
import android.widget.TextView;
+import com.android.launcher3.R;
+import com.android.launcher3.util.Thunk;
/**
* Implements a DropTarget.
*/
-public class ButtonDropTarget extends TextView implements DropTarget, DragController.DragListener {
+public abstract class ButtonDropTarget extends TextView implements DropTarget, DragController.DragListener {
+
+ private static int DRAG_VIEW_DROP_DURATION = 285;
protected final int mTransitionDuration;
@@ -44,6 +54,9 @@ public class ButtonDropTarget extends TextView implements DropTarget, DragContro
/** The paint applied to the drag view on hover */
protected int mHoverColor = 0;
+ protected ColorStateList mOriginalTextColor;
+ protected TransitionDrawable mDrawable;
+
public ButtonDropTarget(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
@@ -56,12 +69,37 @@ public class ButtonDropTarget extends TextView implements DropTarget, DragContro
mBottomDragPadding = r.getDimensionPixelSize(R.dimen.drop_target_drag_padding);
}
- void setLauncher(Launcher launcher) {
- mLauncher = launcher;
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mOriginalTextColor = getTextColors();
+
+ // Remove the text in the Phone UI in landscape
+ int orientation = getResources().getConfiguration().orientation;
+ if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
+ if (!LauncherAppState.getInstance().isScreenLarge()) {
+ setText("");
+ }
+ }
}
- public boolean acceptDrop(DragObject d) {
- return false;
+ protected void setDrawable(int resId) {
+ // Get the hover color
+ mDrawable = (TransitionDrawable) getCurrentDrawable();
+
+ if (mDrawable == null) {
+ // TODO: investigate why this is ever happening. Presently only on one known device.
+ mDrawable = (TransitionDrawable) getResources().getDrawable(resId);
+ setCompoundDrawablesRelativeWithIntrinsicBounds(mDrawable, null, null, null);
+ }
+
+ if (null != mDrawable) {
+ mDrawable.setCrossFadeEnabled(true);
+ }
+ }
+
+ public void setLauncher(Launcher launcher) {
+ mLauncher = launcher;
}
public void setSearchDropTargetBar(SearchDropTargetBar searchDropTargetBar) {
@@ -78,37 +116,94 @@ public class ButtonDropTarget extends TextView implements DropTarget, DragContro
return null;
}
- public void onDrop(DragObject d) {
+ @Override
+ public void onFlingToDelete(DragObject d, int x, int y, PointF vec) { }
+
+ @Override
+ public final void onDragEnter(DragObject d) {
+ d.dragView.setColor(mHoverColor);
+ mDrawable.startTransition(mTransitionDuration);
+ setTextColor(mHoverColor);
}
- public void onFlingToDelete(DragObject d, int x, int y, PointF vec) {
+ @Override
+ public void onDragOver(DragObject d) {
// Do nothing
}
- public void onDragEnter(DragObject d) {
- d.dragView.setColor(mHoverColor);
+ protected void resetHoverColor() {
+ mDrawable.resetTransition();
+ setTextColor(mOriginalTextColor);
}
- public void onDragOver(DragObject d) {
- // Do nothing
+ @Override
+ public final void onDragExit(DragObject d) {
+ if (!d.dragComplete) {
+ d.dragView.setColor(0);
+ resetHoverColor();
+ } else {
+ // Restore the hover color
+ d.dragView.setColor(mHoverColor);
+ }
}
- public void onDragExit(DragObject d) {
- d.dragView.setColor(0);
+ @Override
+ public final void onDragStart(DragSource source, Object info, int dragAction) {
+ mActive = supportsDrop(source, info);
+ mDrawable.resetTransition();
+ setTextColor(mOriginalTextColor);
+ ((ViewGroup) getParent()).setVisibility(mActive ? View.VISIBLE : View.GONE);
}
- public void onDragStart(DragSource source, Object info, int dragAction) {
- // Do nothing
+ @Override
+ public final boolean acceptDrop(DragObject dragObject) {
+ return supportsDrop(dragObject.dragSource, dragObject.dragInfo);
}
+ protected abstract boolean supportsDrop(DragSource source, Object info);
+
+ @Override
public boolean isDropEnabled() {
return mActive;
}
+ @Override
public void onDragEnd() {
- // Do nothing
+ mActive = false;
}
+ /**
+ * On drop animate the dropView to the icon.
+ */
+ @Override
+ public void onDrop(final DragObject d) {
+ final DragLayer dragLayer = mLauncher.getDragLayer();
+ final Rect from = new Rect();
+ dragLayer.getViewRectRelativeToSelf(d.dragView, from);
+
+ int width = mDrawable.getIntrinsicWidth();
+ int height = mDrawable.getIntrinsicHeight();
+ final Rect to = getIconRect(d.dragView.getMeasuredWidth(), d.dragView.getMeasuredHeight(),
+ width, height);
+ final float scale = (float) to.width() / from.width();
+ mSearchDropTargetBar.deferOnDragEnd();
+
+ Runnable onAnimationEndRunnable = new Runnable() {
+ @Override
+ public void run() {
+ completeDrop(d);
+ mSearchDropTargetBar.onDragEnd();
+ mLauncher.exitSpringLoadedDragModeDelayed(true, 0, null);
+ }
+ };
+ dragLayer.animateView(d.dragView, from, to, scale, 1f, 1f, 0.1f, 0.1f,
+ DRAG_VIEW_DROP_DURATION, new DecelerateInterpolator(2),
+ new LinearInterpolator(), onAnimationEndRunnable,
+ DragLayer.ANIMATION_END_DISAPPEAR, null);
+ }
+
+ @Thunk abstract void completeDrop(DragObject d);
+
@Override
public void getHitRectRelativeToDragLayer(android.graphics.Rect outRect) {
super.getHitRect(outRect);
@@ -120,10 +215,10 @@ public class ButtonDropTarget extends TextView implements DropTarget, DragContro
}
private boolean isRtl() {
- return (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
+ return (getLayoutDirection() == LAYOUT_DIRECTION_RTL);
}
- Rect getIconRect(int viewWidth, int viewHeight, int drawableWidth, int drawableHeight) {
+ protected Rect getIconRect(int viewWidth, int viewHeight, int drawableWidth, int drawableHeight) {
DragLayer dragLayer = mLauncher.getDragLayer();
// Find the rect to animate to (the view is center aligned)
@@ -157,6 +252,7 @@ public class ButtonDropTarget extends TextView implements DropTarget, DragContro
return to;
}
+ @Override
public void getLocationInDragLayer(int[] loc) {
mLauncher.getDragLayer().getLocationInDragLayer(this, loc);
}
diff --git a/src/com/android/launcher3/DeleteDropTarget.java b/src/com/android/launcher3/DeleteDropTarget.java
index 62aa285ab..aa3e66c09 100644
--- a/src/com/android/launcher3/DeleteDropTarget.java
+++ b/src/com/android/launcher3/DeleteDropTarget.java
@@ -19,33 +19,22 @@ package com.android.launcher3;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.annotation.TargetApi;
-import android.content.ComponentName;
import android.content.Context;
-import android.content.res.ColorStateList;
-import android.content.res.Configuration;
-import android.content.res.Resources;
import android.graphics.PointF;
import android.graphics.Rect;
-import android.graphics.drawable.TransitionDrawable;
import android.os.AsyncTask;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.UserManager;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewConfiguration;
-import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.view.animation.DecelerateInterpolator;
-import android.view.animation.LinearInterpolator;
-import com.android.launcher3.compat.UserHandleCompat;
+import com.android.launcher3.R;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.widget.WidgetsContainerView;
public class DeleteDropTarget extends ButtonDropTarget {
- private static int DELETE_ANIMATION_DURATION = 285;
+
private static int FLING_DELETE_ANIMATION_DURATION = 350;
private static float FLING_TO_DELETE_FRICTION = 0.035f;
private static int MODE_FLING_DELETE_TO_TRASH = 0;
@@ -53,13 +42,6 @@ public class DeleteDropTarget extends ButtonDropTarget {
private final int mFlingDeleteMode = MODE_FLING_DELETE_ALONG_VECTOR;
- private ColorStateList mOriginalTextColor;
- private TransitionDrawable mUninstallDrawable;
- private TransitionDrawable mRemoveDrawable;
- private TransitionDrawable mCurrentDrawable;
-
- @Thunk boolean mWaitingForUninstall = false;
-
public DeleteDropTarget(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
@@ -71,258 +53,27 @@ public class DeleteDropTarget extends ButtonDropTarget {
@Override
protected void onFinishInflate() {
super.onFinishInflate();
-
- // Get the drawable
- mOriginalTextColor = getTextColors();
-
// Get the hover color
- Resources r = getResources();
- mHoverColor = r.getColor(R.color.delete_target_hover_tint);
- mUninstallDrawable = (TransitionDrawable)
- r.getDrawable(R.drawable.uninstall_target_selector);
- mRemoveDrawable = (TransitionDrawable) r.getDrawable(R.drawable.remove_target_selector);
-
- mRemoveDrawable.setCrossFadeEnabled(true);
- mUninstallDrawable.setCrossFadeEnabled(true);
-
- // The current drawable is set to either the remove drawable or the uninstall drawable
- // and is initially set to the remove drawable, as set in the layout xml.
- mCurrentDrawable = (TransitionDrawable) getCurrentDrawable();
-
- // Remove the text in the Phone UI in landscape
- int orientation = getResources().getConfiguration().orientation;
- if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
- if (!LauncherAppState.getInstance().isScreenLarge()) {
- setText("");
- }
- }
- }
-
- private boolean isAllAppsApplication(DragSource source, Object info) {
- return source.supportsAppInfoDropTarget() && (info instanceof AppInfo);
- }
-
- private boolean isWidget(DragSource source, Object info) {
- if (source instanceof WidgetsContainerView) {
- if (info instanceof PendingAddItemInfo) {
- PendingAddItemInfo addInfo = (PendingAddItemInfo) info;
- switch (addInfo.itemType) {
- case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
- case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
- case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:
- return true;
- }
- }
- }
- return false;
- }
- private boolean isDragSourceWorkspaceOrFolder(DragObject d) {
- return (d.dragSource instanceof Workspace) || (d.dragSource instanceof Folder);
- }
-
- private void setHoverColor() {
- if (mCurrentDrawable != null) {
- mCurrentDrawable.startTransition(mTransitionDuration);
- }
- setTextColor(mHoverColor);
- }
- private void resetHoverColor() {
- if (mCurrentDrawable != null) {
- mCurrentDrawable.resetTransition();
- }
- setTextColor(mOriginalTextColor);
- }
+ mHoverColor = getResources().getColor(R.color.delete_target_hover_tint);
- @Override
- public boolean acceptDrop(DragObject d) {
- return willAcceptDrop(d.dragInfo);
+ setDrawable(R.drawable.remove_target_selector);
}
- public static boolean willAcceptDrop(Object info) {
- if (info instanceof ItemInfo) {
- ItemInfo item = (ItemInfo) info;
- if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET ||
- item.itemType == LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET ||
- item.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
- return true;
- }
-
- if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
- return true;
- }
-
- if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION &&
- item instanceof AppInfo) {
- AppInfo appInfo = (AppInfo) info;
- return (appInfo.flags & AppInfo.DOWNLOADED_FLAG) != 0;
- }
-
- if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION &&
- item instanceof ShortcutInfo) {
- return true;
- }
- }
- return false;
+ public static boolean willAcceptDrop(DragSource source, Object info) {
+ return (info instanceof ItemInfo) && source.supportsDeleteDropTarget();
}
- @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
- public void onDragStart(DragSource source, Object info, int dragAction) {
- boolean isVisible = true;
- boolean useUninstallLabel = isAllAppsApplication(source, info);
- boolean useDeleteLabel = !useUninstallLabel && source.supportsDeleteDropTarget();
-
- // If we are dragging an application from AppsCustomize, only show the control if we can
- // delete the app (it was downloaded), and rename the string to "uninstall" in such a case.
- // Hide the delete target if it is a widget from AppsCustomize.
- if (!willAcceptDrop(info) || isWidget(source, info)) {
- isVisible = false;
- }
- if (useUninstallLabel) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
- UserManager userManager = (UserManager)
- getContext().getSystemService(Context.USER_SERVICE);
- Bundle restrictions = userManager.getUserRestrictions();
- if (restrictions.getBoolean(UserManager.DISALLOW_APPS_CONTROL, false)
- || restrictions.getBoolean(UserManager.DISALLOW_UNINSTALL_APPS, false)) {
- isVisible = false;
- }
- }
- }
-
- if (useUninstallLabel) {
- setCompoundDrawablesRelativeWithIntrinsicBounds(mUninstallDrawable, null, null, null);
- } else if (useDeleteLabel) {
- setCompoundDrawablesRelativeWithIntrinsicBounds(mRemoveDrawable, null, null, null);
- } else {
- isVisible = false;
- }
- mCurrentDrawable = (TransitionDrawable) getCurrentDrawable();
-
- mActive = isVisible;
- resetHoverColor();
- ((ViewGroup) getParent()).setVisibility(isVisible ? View.VISIBLE : View.GONE);
- if (isVisible && getText().length() > 0) {
- setText(useUninstallLabel ? R.string.delete_target_uninstall_label
- : R.string.delete_target_label);
- }
+ protected boolean supportsDrop(DragSource source, Object info) {
+ return willAcceptDrop(source, info);
}
@Override
- public void onDragEnd() {
- super.onDragEnd();
- mActive = false;
- }
-
- public void onDragEnter(DragObject d) {
- super.onDragEnter(d);
-
- setHoverColor();
- }
-
- public void onDragExit(DragObject d) {
- super.onDragExit(d);
-
- if (!d.dragComplete) {
- resetHoverColor();
- } else {
- // Restore the hover color if we are deleting
- d.dragView.setColor(mHoverColor);
- }
- }
-
- private void animateToTrashAndCompleteDrop(final DragObject d) {
- final DragLayer dragLayer = mLauncher.getDragLayer();
- final Rect from = new Rect();
- dragLayer.getViewRectRelativeToSelf(d.dragView, from);
-
- int width = mCurrentDrawable == null ? 0 : mCurrentDrawable.getIntrinsicWidth();
- int height = mCurrentDrawable == null ? 0 : mCurrentDrawable.getIntrinsicHeight();
- final Rect to = getIconRect(d.dragView.getMeasuredWidth(), d.dragView.getMeasuredHeight(),
- width, height);
- final float scale = (float) to.width() / from.width();
-
- mSearchDropTargetBar.deferOnDragEnd();
- deferCompleteDropIfUninstalling(d);
-
- Runnable onAnimationEndRunnable = new Runnable() {
- @Override
- public void run() {
- completeDrop(d);
- mSearchDropTargetBar.onDragEnd();
- mLauncher.exitSpringLoadedDragModeDelayed(true, 0, null);
- }
- };
- dragLayer.animateView(d.dragView, from, to, scale, 1f, 1f, 0.1f, 0.1f,
- DELETE_ANIMATION_DURATION, new DecelerateInterpolator(2),
- new LinearInterpolator(), onAnimationEndRunnable,
- DragLayer.ANIMATION_END_DISAPPEAR, null);
- }
-
- private void deferCompleteDropIfUninstalling(DragObject d) {
- mWaitingForUninstall = false;
- if (isUninstallFromWorkspace(d)) {
- if (d.dragSource instanceof Folder) {
- ((Folder) d.dragSource).deferCompleteDropAfterUninstallActivity();
- } else if (d.dragSource instanceof Workspace) {
- ((Workspace) d.dragSource).deferCompleteDropAfterUninstallActivity();
- }
- mWaitingForUninstall = true;
- }
- }
-
- private boolean isUninstallFromWorkspace(DragObject d) {
- return false;
- }
-
@Thunk void completeDrop(DragObject d) {
ItemInfo item = (ItemInfo) d.dragInfo;
- boolean wasWaitingForUninstall = mWaitingForUninstall;
- mWaitingForUninstall = false;
- if (isAllAppsApplication(d.dragSource, item)) {
- uninstallApp(mLauncher, (AppInfo) item);
- } else if (isUninstallFromWorkspace(d)) {
- ShortcutInfo shortcut = (ShortcutInfo) item;
- if (shortcut.intent != null && shortcut.intent.getComponent() != null) {
- final ComponentName componentName = shortcut.intent.getComponent();
- final DragSource dragSource = d.dragSource;
- final UserHandleCompat user = shortcut.user;
- mWaitingForUninstall = mLauncher.startApplicationUninstallActivity(
- componentName, shortcut.flags, user);
- if (mWaitingForUninstall) {
- final Runnable checkIfUninstallWasSuccess = new Runnable() {
- @Override
- public void run() {
- mWaitingForUninstall = false;
- String packageName = componentName.getPackageName();
- boolean uninstallSuccessful = !AllAppsList.packageHasActivities(
- getContext(), packageName, user);
- if (dragSource instanceof Folder) {
- ((Folder) dragSource).
- onUninstallActivityReturned(uninstallSuccessful);
- } else if (dragSource instanceof Workspace) {
- ((Workspace) dragSource).
- onUninstallActivityReturned(uninstallSuccessful);
- }
- }
- };
- mLauncher.addOnResumeCallback(checkIfUninstallWasSuccess);
- }
- }
- } else if (isDragSourceWorkspaceOrFolder(d)) {
+ if ((d.dragSource instanceof Workspace) || (d.dragSource instanceof Folder)) {
removeWorkspaceOrFolderItem(mLauncher, item, null);
}
- if (wasWaitingForUninstall && !mWaitingForUninstall) {
- if (d.dragSource instanceof Folder) {
- ((Folder) d.dragSource).onUninstallActivityReturned(false);
- } else if (d.dragSource instanceof Workspace) {
- ((Workspace) d.dragSource).onUninstallActivityReturned(false);
- }
- }
- }
-
- public static void uninstallApp(Launcher launcher, AppInfo info) {
- launcher.startApplicationUninstallActivity(info.componentName, info.flags, info.user);
}
/**
@@ -354,7 +105,7 @@ public class DeleteDropTarget extends ButtonDropTarget {
appWidgetHost.deleteAppWidgetId(widget.appWidgetId);
return null;
}
- }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
+ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
} else {
return false;
@@ -367,18 +118,14 @@ public class DeleteDropTarget extends ButtonDropTarget {
return true;
}
- public void onDrop(DragObject d) {
- animateToTrashAndCompleteDrop(d);
- }
-
/**
* Creates an animation from the current drag view to the delete trash icon.
*/
private AnimatorUpdateListener createFlingToTrashAnimatorListener(final DragLayer dragLayer,
DragObject d, PointF vel, ViewConfiguration config) {
- int width = mCurrentDrawable == null ? 0 : mCurrentDrawable.getIntrinsicWidth();
- int height = mCurrentDrawable == null ? 0 : mCurrentDrawable.getIntrinsicHeight();
+ int width = mDrawable.getIntrinsicWidth();
+ int height = mDrawable.getIntrinsicHeight();
final Rect to = getIconRect(d.dragView.getMeasuredWidth(), d.dragView.getMeasuredHeight(),
width, height);
final Rect from = new Rect();
@@ -541,7 +288,6 @@ public class DeleteDropTarget extends ButtonDropTarget {
updateCb = createFlingAlongVectorAnimatorListener(dragLayer, d, vel, startTime,
duration, config);
}
- deferCompleteDropIfUninstalling(d);
Runnable onAnimationEndRunnable = new Runnable() {
@Override
diff --git a/src/com/android/launcher3/DragController.java b/src/com/android/launcher3/DragController.java
index 347374738..b24608cb1 100644
--- a/src/com/android/launcher3/DragController.java
+++ b/src/com/android/launcher3/DragController.java
@@ -125,7 +125,7 @@ public class DragController {
/**
* Interface to receive notifications when a drag starts or stops
*/
- interface DragListener {
+ public interface DragListener {
/**
* A drag has begun
*
@@ -400,7 +400,7 @@ public class DragController {
}
}
- void onDeferredEndFling(DropTarget.DragObject d) {
+ public void onDeferredEndFling(DropTarget.DragObject d) {
d.dragSource.onFlingToDeleteCompleted();
}
@@ -462,7 +462,8 @@ public class DragController {
mLastTouchUpTime = System.currentTimeMillis();
if (mDragging) {
PointF vec = isFlingingToDelete(mDragObject.dragSource);
- if (!DeleteDropTarget.willAcceptDrop(mDragObject.dragInfo)) {
+ if (!DeleteDropTarget.willAcceptDrop(mDragObject.dragSource,
+ mDragObject.dragInfo)) {
vec = null;
}
if (vec != null) {
@@ -616,7 +617,7 @@ public class DragController {
if (mDragging) {
PointF vec = isFlingingToDelete(mDragObject.dragSource);
- if (!DeleteDropTarget.willAcceptDrop(mDragObject.dragInfo)) {
+ if (!DeleteDropTarget.willAcceptDrop(mDragObject.dragSource, mDragObject.dragInfo)) {
vec = null;
}
if (vec != null) {
diff --git a/src/com/android/launcher3/DropTarget.java b/src/com/android/launcher3/DropTarget.java
index 94ae82b82..c5cca3b28 100644
--- a/src/com/android/launcher3/DropTarget.java
+++ b/src/com/android/launcher3/DropTarget.java
@@ -139,7 +139,7 @@ public interface DropTarget {
/**
* Handle an object being dropped on the DropTarget
- *
+ *
* @param source DragSource where the drag started
* @param x X coordinate of the drop location
* @param y Y coordinate of the drop location
@@ -169,7 +169,7 @@ public interface DropTarget {
/**
* Check if a drop action can occur at, or near, the requested location.
* This will be called just before onDrop.
- *
+ *
* @param source DragSource where the drag started
* @param x X coordinate of the drop location
* @param y Y coordinate of the drop location
diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java
index 116332438..c35ce944f 100644
--- a/src/com/android/launcher3/Folder.java
+++ b/src/com/android/launcher3/Folder.java
@@ -51,6 +51,7 @@ import android.widget.TextView;
import com.android.launcher3.DragController.DragListener;
import com.android.launcher3.FolderInfo.FolderListener;
+import com.android.launcher3.UninstallDropTarget.UninstallSource;
import com.android.launcher3.Workspace.ItemOperator;
import com.android.launcher3.util.Thunk;
@@ -62,7 +63,7 @@ import java.util.Collections;
*/
public class Folder extends LinearLayout implements DragSource, View.OnClickListener,
View.OnLongClickListener, DropTarget, FolderListener, TextView.OnEditorActionListener,
- View.OnFocusChangeListener, DragListener {
+ View.OnFocusChangeListener, DragListener, UninstallSource {
private static final String TAG = "Launcher.Folder";
/**
@@ -772,10 +773,12 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
updateItemLocationsInDatabaseBatch();
}
+ @Override
public void deferCompleteDropAfterUninstallActivity() {
mDeferDropAfterUninstall = true;
}
+ @Override
public void onUninstallActivityReturned(boolean success) {
mDeferDropAfterUninstall = false;
mUninstallSuccessful = success;
diff --git a/src/com/android/launcher3/InfoDropTarget.java b/src/com/android/launcher3/InfoDropTarget.java
index 3c36361aa..e48640c93 100644
--- a/src/com/android/launcher3/InfoDropTarget.java
+++ b/src/com/android/launcher3/InfoDropTarget.java
@@ -18,21 +18,14 @@ package com.android.launcher3;
import android.content.ComponentName;
import android.content.Context;
-import android.content.res.ColorStateList;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.graphics.drawable.TransitionDrawable;
+import android.provider.Settings;
import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
+import com.android.launcher3.R;
import com.android.launcher3.compat.UserHandleCompat;
public class InfoDropTarget extends ButtonDropTarget {
- private ColorStateList mOriginalTextColor;
- private TransitionDrawable mDrawable;
-
public InfoDropTarget(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
@@ -44,43 +37,10 @@ public class InfoDropTarget extends ButtonDropTarget {
@Override
protected void onFinishInflate() {
super.onFinishInflate();
-
- mOriginalTextColor = getTextColors();
-
// Get the hover color
- Resources r = getResources();
- mHoverColor = r.getColor(R.color.info_target_hover_tint);
- mDrawable = (TransitionDrawable) getCurrentDrawable();
-
- if (mDrawable == null) {
- // TODO: investigate why this is ever happening. Presently only on one known device.
- mDrawable = (TransitionDrawable) r.getDrawable(R.drawable.info_target_selector);
- setCompoundDrawablesRelativeWithIntrinsicBounds(mDrawable, null, null, null);
- }
-
- if (null != mDrawable) {
- mDrawable.setCrossFadeEnabled(true);
- }
-
- // Remove the text in the Phone UI in landscape
- int orientation = getResources().getConfiguration().orientation;
- if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
- if (!LauncherAppState.getInstance().isScreenLarge()) {
- setText("");
- }
- }
- }
-
- @Override
- public boolean acceptDrop(DragObject d) {
- // acceptDrop is called just before onDrop. We do the work here, rather than
- // in onDrop, because it allows us to reject the drop (by returning false)
- // so that the object being dragged isn't removed from the drag source.
+ mHoverColor = getResources().getColor(R.color.info_target_hover_tint);
- startDetailsActivityForInfo(d.dragInfo, mLauncher);
- // There is no post-drop animation, so clean up the DragView now
- d.deferDragViewCleanupPostAnimation = false;
- return false;
+ setDrawable(R.drawable.info_target_selector);
}
public static void startDetailsActivityForInfo(Object info, Launcher launcher) {
@@ -105,39 +65,14 @@ public class InfoDropTarget extends ButtonDropTarget {
}
@Override
- public void onDragStart(DragSource source, Object info, int dragAction) {
- boolean isVisible = true;
-
- // Hide this button unless we are dragging something from AllApps
- if (!source.supportsAppInfoDropTarget()) {
- isVisible = false;
- }
-
- mActive = isVisible;
- mDrawable.resetTransition();
- setTextColor(mOriginalTextColor);
- ((ViewGroup) getParent()).setVisibility(isVisible ? View.VISIBLE : View.GONE);
+ protected boolean supportsDrop(DragSource source, Object info) {
+ return source.supportsAppInfoDropTarget() &&
+ Settings.Global.getInt(getContext().getContentResolver(),
+ Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) == 1;
}
@Override
- public void onDragEnd() {
- super.onDragEnd();
- mActive = false;
- }
-
- public void onDragEnter(DragObject d) {
- super.onDragEnter(d);
-
- mDrawable.startTransition(mTransitionDuration);
- setTextColor(mHoverColor);
- }
-
- public void onDragExit(DragObject d) {
- super.onDragExit(d);
-
- if (!d.dragComplete) {
- mDrawable.resetTransition();
- setTextColor(mOriginalTextColor);
- }
+ void completeDrop(DragObject d) {
+ startDetailsActivityForInfo(d.dragInfo, mLauncher);
}
}
diff --git a/src/com/android/launcher3/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/LauncherAccessibilityDelegate.java
index cfc1bd96c..8ba02ea5f 100644
--- a/src/com/android/launcher3/LauncherAccessibilityDelegate.java
+++ b/src/com/android/launcher3/LauncherAccessibilityDelegate.java
@@ -105,7 +105,8 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate {
InfoDropTarget.startDetailsActivityForInfo(item, mLauncher);
return true;
} else if (action == UNINSTALL) {
- DeleteDropTarget.uninstallApp(mLauncher, (AppInfo) item);
+ AppInfo info = (AppInfo) item;
+ mLauncher.startApplicationUninstallActivity(info.componentName, info.flags, info.user);
return true;
} else if (action == MOVE) {
beginAccessibleDrag(host, item);
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 37f1ea86e..f7df6bc1a 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -1079,7 +1079,7 @@ public class LauncherModel extends BroadcastReceiver
* @param context
* @param item
*/
- static void deleteItemFromDatabase(Context context, final ItemInfo item) {
+ public static void deleteItemFromDatabase(Context context, final ItemInfo item) {
ArrayList<ItemInfo> items = new ArrayList<ItemInfo>();
items.add(item);
deleteItemsFromDatabase(context, items);
@@ -1185,7 +1185,7 @@ public class LauncherModel extends BroadcastReceiver
/**
* Remove the contents of the specified folder from the database
*/
- static void deleteFolderContentsFromDatabase(Context context, final FolderInfo info) {
+ public static void deleteFolderContentsFromDatabase(Context context, final FolderInfo info) {
final ContentResolver cr = context.getContentResolver();
Runnable r = new Runnable() {
@@ -3106,6 +3106,9 @@ public class LauncherModel extends BroadcastReceiver
si.status &= ~ShortcutInfo.FLAG_RESTORED_ICON
& ~ShortcutInfo.FLAG_AUTOINTALL_ICON
& ~ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE;
+ if (appInfo != null) {
+ si.flags = appInfo.flags;
+ }
infoUpdated = true;
si.updateIcon(mIconCache);
@@ -3414,6 +3417,9 @@ public class LauncherModel extends BroadcastReceiver
info.user = user;
info.contentDescription = mUserManager.getBadgedLabelForUser(
info.title.toString(), info.user);
+ if (lai != null) {
+ info.flags = AppInfo.initFlags(lai);
+ }
return info;
}
diff --git a/src/com/android/launcher3/SearchDropTargetBar.java b/src/com/android/launcher3/SearchDropTargetBar.java
index cc17820ff..a8dcd0f06 100644
--- a/src/com/android/launcher3/SearchDropTargetBar.java
+++ b/src/com/android/launcher3/SearchDropTargetBar.java
@@ -44,11 +44,14 @@ public class SearchDropTargetBar extends FrameLayout implements DragController.D
private boolean mIsSearchBarHidden;
private View mQSBSearchBar;
private View mDropTargetBar;
- private ButtonDropTarget mInfoDropTarget;
- private ButtonDropTarget mDeleteDropTarget;
private int mBarHeight;
private boolean mDeferOnDragEnd = false;
+ // Drop targets
+ private ButtonDropTarget mInfoDropTarget;
+ private ButtonDropTarget mDeleteDropTarget;
+ private ButtonDropTarget mUninstallDropTarget;
+
private boolean mEnableDropDownDropTargets;
public SearchDropTargetBar(Context context, AttributeSet attrs) {
@@ -61,13 +64,19 @@ public class SearchDropTargetBar extends FrameLayout implements DragController.D
public void setup(Launcher launcher, DragController dragController) {
dragController.addDragListener(this);
+ dragController.setFlingToDeleteDropTarget(mDeleteDropTarget);
+
dragController.addDragListener(mInfoDropTarget);
dragController.addDragListener(mDeleteDropTarget);
+ dragController.addDragListener(mUninstallDropTarget);
+
dragController.addDropTarget(mInfoDropTarget);
dragController.addDropTarget(mDeleteDropTarget);
- dragController.setFlingToDeleteDropTarget(mDeleteDropTarget);
+ dragController.addDropTarget(mUninstallDropTarget);
+
mInfoDropTarget.setLauncher(launcher);
mDeleteDropTarget.setLauncher(launcher);
+ mUninstallDropTarget.setLauncher(launcher);
}
public void setQsbSearchBar(View qsb) {
@@ -116,9 +125,11 @@ public class SearchDropTargetBar extends FrameLayout implements DragController.D
mDropTargetBar = findViewById(R.id.drag_target_bar);
mInfoDropTarget = (ButtonDropTarget) mDropTargetBar.findViewById(R.id.info_target_text);
mDeleteDropTarget = (ButtonDropTarget) mDropTargetBar.findViewById(R.id.delete_target_text);
+ mUninstallDropTarget = (ButtonDropTarget) mDropTargetBar.findViewById(R.id.uninstall_target_text);
mInfoDropTarget.setSearchDropTargetBar(this);
mDeleteDropTarget.setSearchDropTargetBar(this);
+ mUninstallDropTarget.setSearchDropTargetBar(this);
mEnableDropDownDropTargets =
getResources().getBoolean(R.bool.config_useDropTargetDownTransition);
diff --git a/src/com/android/launcher3/UninstallDropTarget.java b/src/com/android/launcher3/UninstallDropTarget.java
new file mode 100644
index 000000000..4a7fffeb2
--- /dev/null
+++ b/src/com/android/launcher3/UninstallDropTarget.java
@@ -0,0 +1,122 @@
+package com.android.launcher3;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.UserManager;
+import android.util.AttributeSet;
+import android.util.Pair;
+
+import com.android.launcher3.R;
+import com.android.launcher3.compat.UserHandleCompat;
+import com.android.launcher3.util.Thunk;
+
+public class UninstallDropTarget extends ButtonDropTarget {
+
+ public UninstallDropTarget(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public UninstallDropTarget(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ // Get the hover color
+ mHoverColor = getResources().getColor(R.color.delete_target_hover_tint);
+
+ setDrawable(R.drawable.uninstall_target_selector);
+ }
+
+ @Override
+ protected boolean supportsDrop(DragSource source, Object info) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
+ UserManager userManager = (UserManager)
+ getContext().getSystemService(Context.USER_SERVICE);
+ Bundle restrictions = userManager.getUserRestrictions();
+ if (restrictions.getBoolean(UserManager.DISALLOW_APPS_CONTROL, false)
+ || restrictions.getBoolean(UserManager.DISALLOW_UNINSTALL_APPS, false)) {
+ return false;
+ }
+ }
+
+ Pair<ComponentName, Integer> componentInfo = getAppInfoFlags(info);
+ return componentInfo != null && (componentInfo.second & AppInfo.DOWNLOADED_FLAG) != 0;
+ }
+
+ /**
+ * @return the component name and flags if {@param info} is an AppInfo or an app shortcut.
+ */
+ private static Pair<ComponentName, Integer> getAppInfoFlags(Object item) {
+ if (item instanceof AppInfo) {
+ AppInfo info = (AppInfo) item;
+ return Pair.create(info.componentName, info.flags);
+ } else if (item instanceof ShortcutInfo) {
+ ShortcutInfo info = (ShortcutInfo) item;
+ ComponentName component = info.getTargetComponent();
+ if (info.itemType == LauncherSettings.BaseLauncherColumns.ITEM_TYPE_APPLICATION
+ && component != null) {
+ return Pair.create(component, info.flags);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void onDrop(DragObject d) {
+ // Differ item deletion
+ if (d.dragSource instanceof UninstallSource) {
+ ((UninstallSource) d.dragSource).deferCompleteDropAfterUninstallActivity();
+ }
+ super.onDrop(d);
+ }
+
+ @Override
+ void completeDrop(final DragObject d) {
+ final Pair<ComponentName, Integer> componentInfo = getAppInfoFlags(d.dragInfo);
+ final UserHandleCompat user = ((ItemInfo) d.dragInfo).user;
+ if (mLauncher.startApplicationUninstallActivity(
+ componentInfo.first, componentInfo.second, user)) {
+
+ final Runnable checkIfUninstallWasSuccess = new Runnable() {
+ @Override
+ public void run() {
+ String packageName = componentInfo.first.getPackageName();
+ boolean uninstallSuccessful = !AllAppsList.packageHasActivities(
+ getContext(), packageName, user);
+ sendUninstallResult(d.dragSource, uninstallSuccessful);
+ }
+ };
+ mLauncher.addOnResumeCallback(checkIfUninstallWasSuccess);
+ } else {
+ sendUninstallResult(d.dragSource, false);
+ }
+ }
+
+ @Thunk void sendUninstallResult(DragSource target, boolean result) {
+ if (target instanceof UninstallSource) {
+ ((UninstallSource) target).onUninstallActivityReturned(result);
+ }
+ }
+
+ /**
+ * Interface defining an object that can provide uninstallable drag objects.
+ */
+ public static interface UninstallSource {
+
+ /**
+ * A pending uninstall operation was complete.
+ * @param result true if uninstall was successful, false otherwise.
+ */
+ void onUninstallActivityReturned(boolean result);
+
+ /**
+ * Indicates that an uninstall request are made and the actual result may come
+ * after some time.
+ */
+ void deferCompleteDropAfterUninstallActivity();
+ }
+}
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 043ecb075..568fbb301 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -66,6 +66,7 @@ import com.android.launcher3.FolderIcon.FolderRingAnimator;
import com.android.launcher3.Launcher.CustomContentCallbacks;
import com.android.launcher3.Launcher.LauncherOverlay;
import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.UninstallDropTarget.UninstallSource;
import com.android.launcher3.compat.PackageInstallerCompat;
import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;
import com.android.launcher3.compat.UserHandleCompat;
@@ -88,7 +89,7 @@ import java.util.concurrent.atomic.AtomicInteger;
public class Workspace extends SmoothPagedView
implements DropTarget, DragSource, DragScroller, View.OnTouchListener,
DragController.DragListener, LauncherTransitionable, ViewGroup.OnHierarchyChangeListener,
- Insettable {
+ Insettable, UninstallSource {
private static final String TAG = "Launcher.Workspace";
private static final int CHILDREN_OUTLINE_FADE_OUT_DELAY = 0;
@@ -4269,11 +4270,13 @@ public class Workspace extends SmoothPagedView
}
}
+ @Override
public void deferCompleteDropAfterUninstallActivity() {
mDeferDropAfterUninstall = true;
}
/// maybe move this into a smaller part
+ @Override
public void onUninstallActivityReturned(boolean success) {
mDeferDropAfterUninstall = false;
mUninstallSuccessful = success;