Merge "Accounting for recent changes in padding when detecting backgound taps to close AllApps." into ub-launcher3-burnaby
diff --git a/proguard.flags b/proguard.flags
index ee6bfa5..e2a4b5b 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -6,7 +6,6 @@
public void onClickVoiceButton(android.view.View);
public void onClickConfigureButton(android.view.View);
public void onClickAllAppsButton(android.view.View);
- public void onClickAppMarketButton(android.view.View);
public void dismissFirstRunCling(android.view.View);
public void dismissMigrationClingCopyApps(android.view.View);
public void dismissMigrationClingUseDefault(android.view.View);
diff --git a/res/drawable-hdpi/ic_launcher_market_holo.png b/res/drawable-hdpi/ic_launcher_market_holo.png
deleted file mode 100644
index dc78251..0000000
--- a/res/drawable-hdpi/ic_launcher_market_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_launcher_market_holo.png b/res/drawable-mdpi/ic_launcher_market_holo.png
deleted file mode 100644
index cacb374..0000000
--- a/res/drawable-mdpi/ic_launcher_market_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_launcher_market_holo.png b/res/drawable-xhdpi/ic_launcher_market_holo.png
deleted file mode 100644
index 958f0de..0000000
--- a/res/drawable-xhdpi/ic_launcher_market_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/layout/search_drop_target_bar.xml b/res/layout/search_drop_target_bar.xml
index 0d7167e..9b0da1d 100644
--- a/res/layout/search_drop_target_bar.xml
+++ b/res/layout/search_drop_target_bar.xml
@@ -45,6 +45,19 @@
style="@style/DropTargetButtonContainer"
android:layout_weight="1" >
+ <!-- Uninstall target -->
+
+ <com.android.launcher3.UninstallDropTarget
+ android:id="@+id/uninstall_target_text"
+ style="@style/DropTargetButton"
+ android:drawableStart="@drawable/uninstall_target_selector"
+ android:text="@string/delete_target_uninstall_label" />
+ </FrameLayout>
+
+ <FrameLayout
+ style="@style/DropTargetButtonContainer"
+ android:layout_weight="1" >
+
<!-- Info target -->
<com.android.launcher3.InfoDropTarget
diff --git a/src/com/android/launcher3/AppsContainerView.java b/src/com/android/launcher3/AppsContainerView.java
index 376f888..b247145 100644
--- a/src/com/android/launcher3/AppsContainerView.java
+++ b/src/com/android/launcher3/AppsContainerView.java
@@ -34,6 +34,7 @@
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
+
import com.android.launcher3.util.Thunk;
import java.util.List;
@@ -297,7 +298,7 @@
@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 019f86c..5b39908 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 @@
/** 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 @@
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 @@
return null;
}
- public void onDrop(DragObject d) {
- }
+ @Override
+ public void onFlingToDelete(DragObject d, int x, int y, PointF vec) { }
- public void onFlingToDelete(DragObject d, int x, int y, PointF vec) {
- // Do nothing
- }
-
- public void onDragEnter(DragObject d) {
+ @Override
+ public final void onDragEnter(DragObject d) {
d.dragView.setColor(mHoverColor);
+ mDrawable.startTransition(mTransitionDuration);
+ setTextColor(mHoverColor);
}
+ @Override
public void onDragOver(DragObject d) {
// Do nothing
}
- public void onDragExit(DragObject d) {
- d.dragView.setColor(0);
+ protected void resetHoverColor() {
+ mDrawable.resetTransition();
+ setTextColor(mOriginalTextColor);
}
- public void onDragStart(DragSource source, Object info, int dragAction) {
- // 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);
+ }
}
+ @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);
+ }
+
+ @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 @@
}
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 @@
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 62aa285..aa3e66c 100644
--- a/src/com/android/launcher3/DeleteDropTarget.java
+++ b/src/com/android/launcher3/DeleteDropTarget.java
@@ -19,33 +19,22 @@
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 @@
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 @@
@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);
+ mHoverColor = getResources().getColor(R.color.delete_target_hover_tint);
- 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("");
- }
- }
+ setDrawable(R.drawable.remove_target_selector);
}
- 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);
+ public static boolean willAcceptDrop(DragSource source, Object info) {
+ return (info instanceof ItemInfo) && source.supportsDeleteDropTarget();
}
@Override
- public boolean acceptDrop(DragObject d) {
- return willAcceptDrop(d.dragInfo);
- }
-
- 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;
- }
-
- @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 @@
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 @@
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 @@
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 3473747..b24608c 100644
--- a/src/com/android/launcher3/DragController.java
+++ b/src/com/android/launcher3/DragController.java
@@ -125,7 +125,7 @@
/**
* Interface to receive notifications when a drag starts or stops
*/
- interface DragListener {
+ public interface DragListener {
/**
* A drag has begun
*
@@ -400,7 +400,7 @@
}
}
- void onDeferredEndFling(DropTarget.DragObject d) {
+ public void onDeferredEndFling(DropTarget.DragObject d) {
d.dragSource.onFlingToDeleteCompleted();
}
@@ -462,7 +462,8 @@
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 @@
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 94ae82b..c5cca3b 100644
--- a/src/com/android/launcher3/DropTarget.java
+++ b/src/com/android/launcher3/DropTarget.java
@@ -139,7 +139,7 @@
/**
* 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 @@
/**
* 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 1163324..c35ce94 100644
--- a/src/com/android/launcher3/Folder.java
+++ b/src/com/android/launcher3/Folder.java
@@ -51,6 +51,7 @@
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 @@
*/
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 @@
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 3c36361..e48640c 100644
--- a/src/com/android/launcher3/InfoDropTarget.java
+++ b/src/com/android/launcher3/InfoDropTarget.java
@@ -18,21 +18,14 @@
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 @@
@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();
+ mHoverColor = getResources().getColor(R.color.info_target_hover_tint);
- 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.
-
- 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 @@
}
@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 cfc1bd9..8ba02ea 100644
--- a/src/com/android/launcher3/LauncherAccessibilityDelegate.java
+++ b/src/com/android/launcher3/LauncherAccessibilityDelegate.java
@@ -105,7 +105,8 @@
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 37f1ea8..f7df6bc 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -1079,7 +1079,7 @@
* @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 @@
/**
* 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 @@
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 @@
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/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index d75ef73..f9f5ae1 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -69,8 +69,8 @@
static final String OLD_AUTHORITY = "com.android.launcher2.settings";
static final String AUTHORITY = ProviderConfig.AUTHORITY;
- static final String TABLE_FAVORITES = "favorites";
- static final String TABLE_WORKSPACE_SCREENS = "workspaceScreens";
+ static final String TABLE_FAVORITES = LauncherSettings.Favorites.TABLE_NAME;
+ static final String TABLE_WORKSPACE_SCREENS = LauncherSettings.WorkspaceScreens.TABLE_NAME;
static final String EMPTY_DATABASE_CREATED = "EMPTY_DATABASE_CREATED";
private static final String URI_PARAM_IS_EXTERNAL_ADD = "isExternalAdd";
diff --git a/src/com/android/launcher3/LauncherSettings.java b/src/com/android/launcher3/LauncherSettings.java
index 111de40..90e60e4 100644
--- a/src/com/android/launcher3/LauncherSettings.java
+++ b/src/com/android/launcher3/LauncherSettings.java
@@ -19,6 +19,8 @@
import android.net.Uri;
import android.provider.BaseColumns;
+import com.android.launcher3.config.ProviderConfig;
+
/**
* Settings related utilities.
*/
@@ -45,7 +47,7 @@
* an Intent that can be launched.
* <P>Type: TEXT</P>
*/
- static final String INTENT = "intent";
+ public static final String INTENT = "intent";
/**
* The type of the gesture
@@ -104,29 +106,35 @@
*
* Tracks the order of workspace screens.
*/
- static final class WorkspaceScreens implements ChangeLogColumns {
+ public static final class WorkspaceScreens implements ChangeLogColumns {
+
+ public static final String TABLE_NAME = "workspaceScreens";
+
/**
* The content:// style URL for this table
*/
static final Uri CONTENT_URI = Uri.parse("content://" +
- LauncherProvider.AUTHORITY + "/" + LauncherProvider.TABLE_WORKSPACE_SCREENS);
+ ProviderConfig.AUTHORITY + "/" + TABLE_NAME);
/**
* The rank of this screen -- ie. how it is ordered relative to the other screens.
* <P>Type: INTEGER</P>
*/
- static final String SCREEN_RANK = "screenRank";
+ public static final String SCREEN_RANK = "screenRank";
}
/**
* Favorites.
*/
public static final class Favorites implements BaseLauncherColumns {
+
+ public static final String TABLE_NAME = "favorites";
+
/**
* The content:// style URL for this table
*/
- static final Uri CONTENT_URI = Uri.parse("content://" +
- LauncherProvider.AUTHORITY + "/" + LauncherProvider.TABLE_FAVORITES);
+ public static final Uri CONTENT_URI = Uri.parse("content://" +
+ ProviderConfig.AUTHORITY + "/" + TABLE_NAME);
/**
* The content:// style URL for a given row, identified by its id.
@@ -136,21 +144,21 @@
* @return The unique content URL for the specified row.
*/
static Uri getContentUri(long id) {
- return Uri.parse("content://" + LauncherProvider.AUTHORITY +
- "/" + LauncherProvider.TABLE_FAVORITES + "/" + id);
+ return Uri.parse("content://" + ProviderConfig.AUTHORITY +
+ "/" + TABLE_NAME + "/" + id);
}
/**
* The container holding the favorite
* <P>Type: INTEGER</P>
*/
- static final String CONTAINER = "container";
+ public static final String CONTAINER = "container";
/**
* The icon is a resource identified by a package name and an integer id.
*/
- static final int CONTAINER_DESKTOP = -100;
- static final int CONTAINER_HOTSEAT = -101;
+ public static final int CONTAINER_DESKTOP = -100;
+ public static final int CONTAINER_HOTSEAT = -101;
static final String containerToString(int container) {
switch (container) {
@@ -164,7 +172,7 @@
* The screen holding the favorite (if container is CONTAINER_DESKTOP)
* <P>Type: INTEGER</P>
*/
- static final String SCREEN = "screen";
+ public static final String SCREEN = "screen";
/**
* The X coordinate of the cell holding the favorite
diff --git a/src/com/android/launcher3/SearchDropTargetBar.java b/src/com/android/launcher3/SearchDropTargetBar.java
index cc17820..a8dcd0f 100644
--- a/src/com/android/launcher3/SearchDropTargetBar.java
+++ b/src/com/android/launcher3/SearchDropTargetBar.java
@@ -44,11 +44,14 @@
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 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 @@
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 0000000..4a7fffe
--- /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 671dcaa..6b03e31 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -66,6 +66,7 @@
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 @@
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;
@@ -4271,11 +4272,13 @@
}
}
+ @Override
public void deferCompleteDropAfterUninstallActivity() {
mDeferDropAfterUninstall = true;
}
/// maybe move this into a smaller part
+ @Override
public void onUninstallActivityReturned(boolean success) {
mDeferDropAfterUninstall = false;
mUninstallSuccessful = success;