UninstallDropTarget.java revision ce86e194c41d37b40bd4423bd1954d05bde24840
1package com.android.launcher3; 2 3import android.annotation.TargetApi; 4import android.content.ComponentName; 5import android.content.Context; 6import android.os.Build; 7import android.os.Bundle; 8import android.os.UserManager; 9import android.util.AttributeSet; 10import android.util.Pair; 11 12import com.android.launcher3.compat.UserHandleCompat; 13import com.android.launcher3.util.Thunk; 14 15public class UninstallDropTarget extends ButtonDropTarget { 16 17 public UninstallDropTarget(Context context, AttributeSet attrs) { 18 this(context, attrs, 0); 19 } 20 21 public UninstallDropTarget(Context context, AttributeSet attrs, int defStyle) { 22 super(context, attrs, defStyle); 23 } 24 25 @Override 26 protected void onFinishInflate() { 27 super.onFinishInflate(); 28 // Get the hover color 29 mHoverColor = getResources().getColor(R.color.uninstall_target_hover_tint); 30 31 setDrawable(R.drawable.ic_uninstall_launcher); 32 } 33 34 @Override 35 protected boolean supportsDrop(DragSource source, ItemInfo info) { 36 return supportsDrop(getContext(), info); 37 } 38 39 @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) 40 public static boolean supportsDrop(Context context, Object info) { 41 if (Utilities.ATLEAST_JB_MR2) { 42 UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE); 43 Bundle restrictions = userManager.getUserRestrictions(); 44 if (restrictions.getBoolean(UserManager.DISALLOW_APPS_CONTROL, false) 45 || restrictions.getBoolean(UserManager.DISALLOW_UNINSTALL_APPS, false)) { 46 return false; 47 } 48 } 49 50 Pair<ComponentName, Integer> componentInfo = getAppInfoFlags(info); 51 return componentInfo != null && (componentInfo.second & AppInfo.DOWNLOADED_FLAG) != 0; 52 } 53 54 /** 55 * @return the component name and flags if {@param info} is an AppInfo or an app shortcut. 56 */ 57 private static Pair<ComponentName, Integer> getAppInfoFlags(Object item) { 58 if (item instanceof AppInfo) { 59 AppInfo info = (AppInfo) item; 60 return Pair.create(info.componentName, info.flags); 61 } else if (item instanceof ShortcutInfo) { 62 ShortcutInfo info = (ShortcutInfo) item; 63 ComponentName component = info.getTargetComponent(); 64 if (info.itemType == LauncherSettings.BaseLauncherColumns.ITEM_TYPE_APPLICATION 65 && component != null) { 66 return Pair.create(component, info.flags); 67 } 68 } 69 return null; 70 } 71 72 @Override 73 public void onDrop(DragObject d) { 74 // Differ item deletion 75 if (d.dragSource instanceof UninstallSource) { 76 ((UninstallSource) d.dragSource).deferCompleteDropAfterUninstallActivity(); 77 } 78 super.onDrop(d); 79 } 80 81 @Override 82 void completeDrop(final DragObject d) { 83 final Pair<ComponentName, Integer> componentInfo = getAppInfoFlags(d.dragInfo); 84 final UserHandleCompat user = d.dragInfo.user; 85 if (startActivityWithUninstallAffordance(d)) { 86 87 final Runnable checkIfUninstallWasSuccess = new Runnable() { 88 @Override 89 public void run() { 90 boolean uninstallSuccessful = false; 91 if (componentInfo != null) { 92 String packageName = componentInfo.first.getPackageName(); 93 uninstallSuccessful = !AllAppsList.packageHasActivities( 94 getContext(), packageName, user); 95 } 96 sendUninstallResult(d.dragSource, uninstallSuccessful); 97 } 98 }; 99 mLauncher.addOnResumeCallback(checkIfUninstallWasSuccess); 100 } else { 101 sendUninstallResult(d.dragSource, false); 102 } 103 } 104 105 protected boolean startActivityWithUninstallAffordance(DragObject d) { 106 return startUninstallActivity(mLauncher, d.dragInfo); 107 } 108 109 public static boolean startUninstallActivity(Launcher launcher, ItemInfo info) { 110 final Pair<ComponentName, Integer> componentInfo = getAppInfoFlags(info); 111 final UserHandleCompat user = info.user; 112 return launcher.startApplicationUninstallActivity( 113 componentInfo.first, componentInfo.second, user); 114 } 115 116 @Thunk void sendUninstallResult(DragSource target, boolean result) { 117 if (target instanceof UninstallSource) { 118 ((UninstallSource) target).onUninstallActivityReturned(result); 119 } 120 } 121 122 /** 123 * Interface defining an object that can provide uninstallable drag objects. 124 */ 125 public interface UninstallSource { 126 127 /** 128 * A pending uninstall operation was complete. 129 * @param result true if uninstall was successful, false otherwise. 130 */ 131 void onUninstallActivityReturned(boolean result); 132 133 /** 134 * Indicates that an uninstall request are made and the actual result may come 135 * after some time. 136 */ 137 void deferCompleteDropAfterUninstallActivity(); 138 } 139} 140