blob: 419939000f6c4c7c48816572b17c6df924129ffe [file] [log] [blame]
Sunny Goyalfa401a12015-04-10 13:45:42 -07001package com.android.launcher3;
2
Sunny Goyal70660032015-05-14 00:07:08 -07003import android.annotation.TargetApi;
Sunny Goyalfa401a12015-04-10 13:45:42 -07004import 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;
Sunny Goyalfa401a12015-04-10 13:45:42 -070011import 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
Sunny Goyal3a644ed2015-05-21 10:28:02 -070031 setDrawable(R.drawable.ic_launcher_uninstall_normal);
Sunny Goyalfa401a12015-04-10 13:45:42 -070032 }
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
Sunny Goyal70660032015-05-14 00:07:08 -070039 @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
Sunny Goyal1a70cef2015-04-22 11:29:51 -070040 public static boolean supportsDrop(Context context, Object info) {
Sunny Goyalfa401a12015-04-10 13:45:42 -070041 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
Sunny Goyal1a70cef2015-04-22 11:29:51 -070042 UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
Sunny Goyalfa401a12015-04-10 13:45:42 -070043 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 = ((ItemInfo) d.dragInfo).user;
Sunny Goyal1a70cef2015-04-22 11:29:51 -070085 if (startUninstallActivity(mLauncher, d.dragInfo)) {
Sunny Goyalfa401a12015-04-10 13:45:42 -070086
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
Sunny Goyal1a70cef2015-04-22 11:29:51 -0700102 public static boolean startUninstallActivity(Launcher launcher, Object info) {
103 final Pair<ComponentName, Integer> componentInfo = getAppInfoFlags(info);
104 final UserHandleCompat user = ((ItemInfo) info).user;
105 return launcher.startApplicationUninstallActivity(
106 componentInfo.first, componentInfo.second, user);
107 }
108
Sunny Goyalfa401a12015-04-10 13:45:42 -0700109 @Thunk void sendUninstallResult(DragSource target, boolean result) {
110 if (target instanceof UninstallSource) {
111 ((UninstallSource) target).onUninstallActivityReturned(result);
112 }
113 }
114
115 /**
116 * Interface defining an object that can provide uninstallable drag objects.
117 */
118 public static interface UninstallSource {
119
120 /**
121 * A pending uninstall operation was complete.
122 * @param result true if uninstall was successful, false otherwise.
123 */
124 void onUninstallActivityReturned(boolean result);
125
126 /**
127 * Indicates that an uninstall request are made and the actual result may come
128 * after some time.
129 */
130 void deferCompleteDropAfterUninstallActivity();
131 }
132}