blob: c3511358d0b7d94358d498cfcb08ad1d975c637d [file] [log] [blame]
Sunny Goyalfa401a12015-04-10 13:45:42 -07001package 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
Sunny Goyal3a2698b2015-04-28 21:36:46 -070029 mHoverColor = getResources().getColor(R.color.uninstall_target_hover_tint);
Sunny Goyalfa401a12015-04-10 13:45:42 -070030
31 setDrawable(R.drawable.uninstall_target_selector);
32 }
33
34 @Override
35 protected boolean supportsDrop(DragSource source, Object info) {
Sunny Goyal1a70cef2015-04-22 11:29:51 -070036 return supportsDrop(getContext(), info);
37 }
38
39 public static boolean supportsDrop(Context context, Object info) {
Sunny Goyalfa401a12015-04-10 13:45:42 -070040 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
Sunny Goyal1a70cef2015-04-22 11:29:51 -070041 UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
Sunny Goyalfa401a12015-04-10 13:45:42 -070042 Bundle restrictions = userManager.getUserRestrictions();
43 if (restrictions.getBoolean(UserManager.DISALLOW_APPS_CONTROL, false)
44 || restrictions.getBoolean(UserManager.DISALLOW_UNINSTALL_APPS, false)) {
45 return false;
46 }
47 }
48
49 Pair<ComponentName, Integer> componentInfo = getAppInfoFlags(info);
50 return componentInfo != null && (componentInfo.second & AppInfo.DOWNLOADED_FLAG) != 0;
51 }
52
53 /**
54 * @return the component name and flags if {@param info} is an AppInfo or an app shortcut.
55 */
56 private static Pair<ComponentName, Integer> getAppInfoFlags(Object item) {
57 if (item instanceof AppInfo) {
58 AppInfo info = (AppInfo) item;
59 return Pair.create(info.componentName, info.flags);
60 } else if (item instanceof ShortcutInfo) {
61 ShortcutInfo info = (ShortcutInfo) item;
62 ComponentName component = info.getTargetComponent();
63 if (info.itemType == LauncherSettings.BaseLauncherColumns.ITEM_TYPE_APPLICATION
64 && component != null) {
65 return Pair.create(component, info.flags);
66 }
67 }
68 return null;
69 }
70
71 @Override
72 public void onDrop(DragObject d) {
73 // Differ item deletion
74 if (d.dragSource instanceof UninstallSource) {
75 ((UninstallSource) d.dragSource).deferCompleteDropAfterUninstallActivity();
76 }
77 super.onDrop(d);
78 }
79
80 @Override
81 void completeDrop(final DragObject d) {
82 final Pair<ComponentName, Integer> componentInfo = getAppInfoFlags(d.dragInfo);
83 final UserHandleCompat user = ((ItemInfo) d.dragInfo).user;
Sunny Goyal1a70cef2015-04-22 11:29:51 -070084 if (startUninstallActivity(mLauncher, d.dragInfo)) {
Sunny Goyalfa401a12015-04-10 13:45:42 -070085
86 final Runnable checkIfUninstallWasSuccess = new Runnable() {
87 @Override
88 public void run() {
89 String packageName = componentInfo.first.getPackageName();
90 boolean uninstallSuccessful = !AllAppsList.packageHasActivities(
91 getContext(), packageName, user);
92 sendUninstallResult(d.dragSource, uninstallSuccessful);
93 }
94 };
95 mLauncher.addOnResumeCallback(checkIfUninstallWasSuccess);
96 } else {
97 sendUninstallResult(d.dragSource, false);
98 }
99 }
100
Sunny Goyal1a70cef2015-04-22 11:29:51 -0700101 public static boolean startUninstallActivity(Launcher launcher, Object info) {
102 final Pair<ComponentName, Integer> componentInfo = getAppInfoFlags(info);
103 final UserHandleCompat user = ((ItemInfo) info).user;
104 return launcher.startApplicationUninstallActivity(
105 componentInfo.first, componentInfo.second, user);
106 }
107
Sunny Goyalfa401a12015-04-10 13:45:42 -0700108 @Thunk void sendUninstallResult(DragSource target, boolean result) {
109 if (target instanceof UninstallSource) {
110 ((UninstallSource) target).onUninstallActivityReturned(result);
111 }
112 }
113
114 /**
115 * Interface defining an object that can provide uninstallable drag objects.
116 */
117 public static interface UninstallSource {
118
119 /**
120 * A pending uninstall operation was complete.
121 * @param result true if uninstall was successful, false otherwise.
122 */
123 void onUninstallActivityReturned(boolean result);
124
125 /**
126 * Indicates that an uninstall request are made and the actual result may come
127 * after some time.
128 */
129 void deferCompleteDropAfterUninstallActivity();
130 }
131}