summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornebkat <nebkat@teamhacksung.org>2012-02-24 16:03:42 +0000
committernebkat <nebkat@teamhacksung.org>2012-02-24 19:35:38 +0000
commit76c72386989cd2adc30086fb36aa1fdd7304014b (patch)
tree769ebd129cc45ed561ec3e63b830ea0abed22811
parent5883db238421c3209fab1be5420e9137104672b6 (diff)
downloadandroid_packages_apps_Trebuchet-76c72386989cd2adc30086fb36aa1fdd7304014b.tar.gz
android_packages_apps_Trebuchet-76c72386989cd2adc30086fb36aa1fdd7304014b.tar.bz2
android_packages_apps_Trebuchet-76c72386989cd2adc30086fb36aa1fdd7304014b.zip
DeleteDropTarget: Long-Hold To Uninstall
Change-Id: I2f60040c4cc645a54e9a8e696f330a8e70ff833c
-rw-r--r--src/com/cyanogenmod/trebuchet/DeleteDropTarget.java187
-rw-r--r--src/com/cyanogenmod/trebuchet/Launcher.java21
2 files changed, 138 insertions, 70 deletions
diff --git a/src/com/cyanogenmod/trebuchet/DeleteDropTarget.java b/src/com/cyanogenmod/trebuchet/DeleteDropTarget.java
index 131882895..7c23677cb 100644
--- a/src/com/cyanogenmod/trebuchet/DeleteDropTarget.java
+++ b/src/com/cyanogenmod/trebuchet/DeleteDropTarget.java
@@ -17,13 +17,16 @@
package com.cyanogenmod.trebuchet;
import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
-import android.graphics.drawable.TransitionDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
@@ -31,12 +34,20 @@ import android.view.animation.DecelerateInterpolator;
public class DeleteDropTarget extends ButtonDropTarget {
+ private static final int MODE_DELETE = 0;
+ private static final int MODE_UNINSTALL = 1;
+ private int mMode = MODE_DELETE;
+
private static int DELETE_ANIMATION_DURATION = 250;
private ColorStateList mOriginalTextColor;
private int mHoverColor = 0xFFFF0000;
- private TransitionDrawable mUninstallDrawable;
- private TransitionDrawable mRemoveDrawable;
- private TransitionDrawable mCurrentDrawable;
+ private Drawable mUninstallActiveDrawable;
+ private Drawable mRemoveActiveDrawable;
+ private Drawable mRemoveNormalDrawable;
+ private Drawable mCurrentDrawable;
+ private boolean mUninstall;
+
+ private final Handler mHandler = new Handler();
public DeleteDropTarget(Context context, AttributeSet attrs) {
this(context, attrs, 0);
@@ -46,6 +57,12 @@ public class DeleteDropTarget extends ButtonDropTarget {
super(context, attrs, defStyle);
}
+ private final Runnable mShowUninstaller = new Runnable() {
+ public void run() {
+ switchToUninstallTarget();
+ }
+ };
+
@Override
protected void onFinishInflate() {
super.onFinishInflate();
@@ -58,16 +75,9 @@ public class DeleteDropTarget extends ButtonDropTarget {
mHoverColor = r.getColor(R.color.delete_target_hover_tint);
mHoverPaint.setColorFilter(new PorterDuffColorFilter(
mHoverColor, PorterDuff.Mode.SRC_ATOP));
- 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) getCompoundDrawables()[0];
+ mUninstallActiveDrawable = r.getDrawable(R.drawable.ic_launcher_trashcan_active_holo);
+ mRemoveActiveDrawable = r.getDrawable(R.drawable.ic_launcher_clear_active_holo);
+ mRemoveNormalDrawable = r.getDrawable(R.drawable.ic_launcher_clear_normal_holo);
// Remove the text in the Phone UI in landscape
int orientation = getResources().getConfiguration().orientation;
@@ -84,17 +94,17 @@ public class DeleteDropTarget extends ButtonDropTarget {
private boolean isAllAppsWidget(DragSource source, Object info) {
return (source instanceof AppsCustomizeView) && (info instanceof PendingAddWidgetInfo);
}
- private boolean isDragSourceWorkspaceOrFolder(DragObject d) {
- return (d.dragSource instanceof Workspace) || (d.dragSource instanceof Folder);
+ private boolean isDragSourceWorkspaceOrFolder(DragSource source) {
+ return (source instanceof Workspace) || (source instanceof Folder);
}
- private boolean isWorkspaceOrFolderApplication(DragObject d) {
- return isDragSourceWorkspaceOrFolder(d) && (d.dragInfo instanceof ShortcutInfo);
+ private boolean isWorkspaceOrFolderApplication(DragSource source, Object info) {
+ return isDragSourceWorkspaceOrFolder(source) && (info instanceof ShortcutInfo);
}
- private boolean isWorkspaceOrFolderWidget(DragObject d) {
- return isDragSourceWorkspaceOrFolder(d) && (d.dragInfo instanceof LauncherAppWidgetInfo);
+ private boolean isWorkspaceWidget(DragSource source, Object info) {
+ return isDragSourceWorkspaceOrFolder(source) && (info instanceof LauncherAppWidgetInfo);
}
- private boolean isWorkspaceFolder(DragObject d) {
- return (d.dragSource instanceof Workspace) && (d.dragInfo instanceof FolderInfo);
+ private boolean isWorkspaceFolder(DragSource source, Object info) {
+ return (source instanceof Workspace) && (info instanceof FolderInfo);
}
@Override
@@ -105,60 +115,87 @@ public class DeleteDropTarget extends ButtonDropTarget {
@Override
public void onDragStart(DragSource source, Object info, int dragAction) {
- boolean isVisible = true;
boolean isUninstall = false;
- // If we are dragging a widget from AppsCustomize, hide the delete target
- if (isAllAppsWidget(source, info)) {
- isVisible = false;
- }
-
- // 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
+ // If we are dragging an application from AppsCustomize, only show the uninstall control if we
+ // can delete the app (it was downloaded)
if (isAllAppsApplication(source, info)) {
ApplicationInfo appInfo = (ApplicationInfo) info;
if ((appInfo.flags & ApplicationInfo.DOWNLOADED_FLAG) != 0) {
isUninstall = true;
- } else {
- isVisible = false;
+ }
+ } else if (isWorkspaceOrFolderApplication(source, info)) {
+ ShortcutInfo shortcutInfo = (ShortcutInfo) info;
+ PackageManager pm = getContext().getPackageManager();
+ ResolveInfo resolveInfo = pm.resolveActivity(shortcutInfo.intent, 0);
+ if (resolveInfo != null && (resolveInfo.activityInfo.applicationInfo.flags &
+ android.content.pm.ApplicationInfo.FLAG_SYSTEM) == 0) {
+ isUninstall = true;
}
}
- if (isUninstall) {
- setCompoundDrawablesWithIntrinsicBounds(mUninstallDrawable, null, null, null);
- } else {
- setCompoundDrawablesWithIntrinsicBounds(mRemoveDrawable, null, null, null);
- }
- mCurrentDrawable = (TransitionDrawable) getCompoundDrawables()[0];
+ setCompoundDrawablesWithIntrinsicBounds(mRemoveNormalDrawable, null, null, null);
+ mCurrentDrawable = getCompoundDrawables()[0];
- mActive = isVisible;
- mCurrentDrawable.resetTransition();
+ mUninstall = isUninstall;
+ mActive = true;
+ mMode = MODE_DELETE;
setTextColor(mOriginalTextColor);
- ((ViewGroup) getParent()).setVisibility(isVisible ? View.VISIBLE : View.GONE);
+ ((ViewGroup) getParent()).setVisibility(View.VISIBLE);
if (getText().length() > 0) {
- setText(isUninstall ? R.string.delete_target_uninstall_label
- : R.string.delete_target_label);
+ setText(R.string.delete_target_label);
}
}
+ private void switchToUninstallTarget() {
+ if (!mUninstall) {
+ return;
+ }
+
+ mMode = MODE_UNINSTALL;
+
+ if (getText().length() > 0) {
+ setText(R.string.delete_target_uninstall_label);
+ }
+
+ setCompoundDrawablesWithIntrinsicBounds(mUninstallActiveDrawable, null, null, null);
+ mCurrentDrawable = getCompoundDrawables()[0];
+ }
+
@Override
public void onDragEnd() {
super.onDragEnd();
+
mActive = false;
}
public void onDragEnter(DragObject d) {
super.onDragEnter(d);
- mCurrentDrawable.startTransition(mTransitionDuration);
+ if (mUninstall) {
+ mHandler.removeCallbacks(mShowUninstaller);
+ mHandler.postDelayed(mShowUninstaller, 1000);
+ }
+
+ setCompoundDrawablesWithIntrinsicBounds(mRemoveActiveDrawable, null, null, null);
+ mCurrentDrawable = getCompoundDrawables()[0];
setTextColor(mHoverColor);
}
public void onDragExit(DragObject d) {
super.onDragExit(d);
+ mHandler.removeCallbacks(mShowUninstaller);
+
if (!d.dragComplete) {
- mCurrentDrawable.resetTransition();
+ mMode = MODE_DELETE;
+
+ if (getText().length() > 0) {
+ setText(R.string.delete_target_label);
+ }
+
+ setCompoundDrawablesWithIntrinsicBounds(mRemoveNormalDrawable, null, null, null);
+ mCurrentDrawable = getCompoundDrawables()[0];
setTextColor(mOriginalTextColor);
}
}
@@ -197,32 +234,42 @@ public class DeleteDropTarget extends ButtonDropTarget {
private void completeDrop(DragObject d) {
ItemInfo item = (ItemInfo) d.dragInfo;
- if (isAllAppsApplication(d.dragSource, item)) {
- // Uninstall the application if it is being dragged from AppsCustomize
- mLauncher.startApplicationUninstallActivity((ApplicationInfo) item);
- } else if (isWorkspaceOrFolderApplication(d)) {
- LauncherModel.deleteItemFromDatabase(mLauncher, item);
- } else if (isWorkspaceFolder(d)) {
- // Remove the folder from the workspace and delete the contents from launcher model
- FolderInfo folderInfo = (FolderInfo) item;
- mLauncher.removeFolder(folderInfo);
- LauncherModel.deleteFolderContentsFromDatabase(mLauncher, folderInfo);
- } else if (isWorkspaceOrFolderWidget(d)) {
- // Remove the widget from the workspace
- mLauncher.removeAppWidget((LauncherAppWidgetInfo) item);
- LauncherModel.deleteItemFromDatabase(mLauncher, item);
-
- final LauncherAppWidgetInfo launcherAppWidgetInfo = (LauncherAppWidgetInfo) item;
- final LauncherAppWidgetHost appWidgetHost = mLauncher.getAppWidgetHost();
- if (appWidgetHost != null) {
- // Deleting an app widget ID is a void call but writes to disk before returning
- // to the caller...
- new Thread("deleteAppWidgetId") {
- public void run() {
- appWidgetHost.deleteAppWidgetId(launcherAppWidgetInfo.appWidgetId);
+ switch (mMode) {
+ case MODE_DELETE:
+ if (isWorkspaceOrFolderApplication(d.dragSource, item)) {
+ LauncherModel.deleteItemFromDatabase(mLauncher, item);
+ } else if (isWorkspaceFolder(d.dragSource, d.dragInfo)) {
+ // Remove the folder from the workspace and delete the contents from launcher model
+ FolderInfo folderInfo = (FolderInfo) item;
+ mLauncher.removeFolder(folderInfo);
+ LauncherModel.deleteFolderContentsFromDatabase(mLauncher, folderInfo);
+ } else if (isWorkspaceWidget(d.dragSource, item)) {
+ // Remove the widget from the workspace
+ mLauncher.removeAppWidget((LauncherAppWidgetInfo) item);
+ LauncherModel.deleteItemFromDatabase(mLauncher, item);
+
+ final LauncherAppWidgetInfo launcherAppWidgetInfo = (LauncherAppWidgetInfo) item;
+ final LauncherAppWidgetHost appWidgetHost = mLauncher.getAppWidgetHost();
+ if (appWidgetHost != null) {
+ // Deleting an app widget ID is a void call but writes to disk before returning
+ // to the caller...
+ new Thread("deleteAppWidgetId") {
+ public void run() {
+ appWidgetHost.deleteAppWidgetId(launcherAppWidgetInfo.appWidgetId);
+ }
+ }.start();
}
- }.start();
- }
+ }
+ break;
+ case MODE_UNINSTALL:
+ if (isAllAppsApplication(d.dragSource, item)) {
+ // Uninstall the application
+ mLauncher.startApplicationUninstallActivity((ApplicationInfo) item);
+ } else if (isWorkspaceOrFolderApplication(d.dragSource, item)) {
+ // Uninstall the shortcut
+ mLauncher.startShortcutUninstallActivity((ShortcutInfo) item);
+ }
+ break;
}
}
diff --git a/src/com/cyanogenmod/trebuchet/Launcher.java b/src/com/cyanogenmod/trebuchet/Launcher.java
index 1d4757e33..cf1ccd88d 100644
--- a/src/com/cyanogenmod/trebuchet/Launcher.java
+++ b/src/com/cyanogenmod/trebuchet/Launcher.java
@@ -47,6 +47,7 @@ import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.ContentObserver;
@@ -1879,6 +1880,26 @@ public final class Launcher extends Activity
}
}
+ void startShortcutUninstallActivity(ShortcutInfo shortcutInfo) {
+ PackageManager pm = getPackageManager();
+ ResolveInfo resolveInfo = pm.resolveActivity(shortcutInfo.intent, 0);
+ if ((resolveInfo.activityInfo.applicationInfo.flags &
+ android.content.pm.ApplicationInfo.FLAG_SYSTEM) != 0) {
+ // System applications cannot be installed. For now, show a toast explaining that.
+ // We may give them the option of disabling apps this way.
+ int messageId = R.string.uninstall_system_app_text;
+ Toast.makeText(this, messageId, Toast.LENGTH_SHORT).show();
+ } else {
+ String packageName = shortcutInfo.intent.getComponent().getPackageName();
+ String className = shortcutInfo.intent.getComponent().getClassName();
+ Intent intent = new Intent(
+ Intent.ACTION_DELETE, Uri.fromParts("package", packageName, className));
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
+ Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+ startActivity(intent);
+ }
+ }
+
boolean startActivitySafely(Intent intent, Object tag) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {