UninstallDropTarget.java revision fa401a10e7e9341daf6f3c5949bf9331902c26d0
1package com.android.launcher3; 2 3import android.content.ComponentName; 4import android.content.Context; 5import android.os.Build; 6import android.os.Bundle; 7import android.os.UserManager; 8import android.util.AttributeSet; 9import android.util.Pair; 10 11import com.android.launcher3.R; 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.delete_target_hover_tint); 30 31 setDrawable(R.drawable.uninstall_target_selector); 32 } 33 34 @Override 35 protected boolean supportsDrop(DragSource source, Object info) { 36 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { 37 UserManager userManager = (UserManager) 38 getContext().getSystemService(Context.USER_SERVICE); 39 Bundle restrictions = userManager.getUserRestrictions(); 40 if (restrictions.getBoolean(UserManager.DISALLOW_APPS_CONTROL, false) 41 || restrictions.getBoolean(UserManager.DISALLOW_UNINSTALL_APPS, false)) { 42 return false; 43 } 44 } 45 46 Pair<ComponentName, Integer> componentInfo = getAppInfoFlags(info); 47 return componentInfo != null && (componentInfo.second & AppInfo.DOWNLOADED_FLAG) != 0; 48 } 49 50 /** 51 * @return the component name and flags if {@param info} is an AppInfo or an app shortcut. 52 */ 53 private static Pair<ComponentName, Integer> getAppInfoFlags(Object item) { 54 if (item instanceof AppInfo) { 55 AppInfo info = (AppInfo) item; 56 return Pair.create(info.componentName, info.flags); 57 } else if (item instanceof ShortcutInfo) { 58 ShortcutInfo info = (ShortcutInfo) item; 59 ComponentName component = info.getTargetComponent(); 60 if (info.itemType == LauncherSettings.BaseLauncherColumns.ITEM_TYPE_APPLICATION 61 && component != null) { 62 return Pair.create(component, info.flags); 63 } 64 } 65 return null; 66 } 67 68 @Override 69 public void onDrop(DragObject d) { 70 // Differ item deletion 71 if (d.dragSource instanceof UninstallSource) { 72 ((UninstallSource) d.dragSource).deferCompleteDropAfterUninstallActivity(); 73 } 74 super.onDrop(d); 75 } 76 77 @Override 78 void completeDrop(final DragObject d) { 79 final Pair<ComponentName, Integer> componentInfo = getAppInfoFlags(d.dragInfo); 80 final UserHandleCompat user = ((ItemInfo) d.dragInfo).user; 81 if (mLauncher.startApplicationUninstallActivity( 82 componentInfo.first, componentInfo.second, user)) { 83 84 final Runnable checkIfUninstallWasSuccess = new Runnable() { 85 @Override 86 public void run() { 87 String packageName = componentInfo.first.getPackageName(); 88 boolean uninstallSuccessful = !AllAppsList.packageHasActivities( 89 getContext(), packageName, user); 90 sendUninstallResult(d.dragSource, uninstallSuccessful); 91 } 92 }; 93 mLauncher.addOnResumeCallback(checkIfUninstallWasSuccess); 94 } else { 95 sendUninstallResult(d.dragSource, false); 96 } 97 } 98 99 @Thunk void sendUninstallResult(DragSource target, boolean result) { 100 if (target instanceof UninstallSource) { 101 ((UninstallSource) target).onUninstallActivityReturned(result); 102 } 103 } 104 105 /** 106 * Interface defining an object that can provide uninstallable drag objects. 107 */ 108 public static interface UninstallSource { 109 110 /** 111 * A pending uninstall operation was complete. 112 * @param result true if uninstall was successful, false otherwise. 113 */ 114 void onUninstallActivityReturned(boolean result); 115 116 /** 117 * Indicates that an uninstall request are made and the actual result may come 118 * after some time. 119 */ 120 void deferCompleteDropAfterUninstallActivity(); 121 } 122} 123