UninstallDropTarget.java revision 734dfbe2726c748b70eca6a2e3742a7443757bbe
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 String packageName = componentInfo.first.getPackageName(); 91 boolean uninstallSuccessful = !AllAppsList.packageHasActivities( 92 getContext(), packageName, user); 93 sendUninstallResult(d.dragSource, uninstallSuccessful); 94 } 95 }; 96 mLauncher.addOnResumeCallback(checkIfUninstallWasSuccess); 97 } else { 98 sendUninstallResult(d.dragSource, false); 99 } 100 } 101 102 protected boolean startActivityWithUninstallAffordance(DragObject d) { 103 return startUninstallActivity(mLauncher, d.dragInfo); 104 } 105 106 public static boolean startUninstallActivity(Launcher launcher, ItemInfo info) { 107 final Pair<ComponentName, Integer> componentInfo = getAppInfoFlags(info); 108 final UserHandleCompat user = info.user; 109 return launcher.startApplicationUninstallActivity( 110 componentInfo.first, componentInfo.second, user); 111 } 112 113 @Thunk void sendUninstallResult(DragSource target, boolean result) { 114 if (target instanceof UninstallSource) { 115 ((UninstallSource) target).onUninstallActivityReturned(result); 116 } 117 } 118 119 /** 120 * Interface defining an object that can provide uninstallable drag objects. 121 */ 122 public interface UninstallSource { 123 124 /** 125 * A pending uninstall operation was complete. 126 * @param result true if uninstall was successful, false otherwise. 127 */ 128 void onUninstallActivityReturned(boolean result); 129 130 /** 131 * Indicates that an uninstall request are made and the actual result may come 132 * after some time. 133 */ 134 void deferCompleteDropAfterUninstallActivity(); 135 } 136} 137