blob: b69c79da1143a683cc694d51a2f12b452dfc8fb0 [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 Goyalaa8ef112015-06-12 20:04:41 -070011
Sunny Goyalfa401a12015-04-10 13:45:42 -070012import 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 Goyal40b626b2015-06-04 22:40:14 -070031 setDrawable(R.drawable.ic_uninstall_launcher);
Sunny Goyalfa401a12015-04-10 13:45:42 -070032 }
33
34 @Override
Sunny Goyalaa8ef112015-06-12 20:04:41 -070035 protected boolean supportsDrop(DragSource source, ItemInfo 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 Goyal9fc953b2015-08-17 12:24:25 -070041 if (Utilities.ATLEAST_JB_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);
Sunny Goyalaa8ef112015-06-12 20:04:41 -070084 final UserHandleCompat user = d.dragInfo.user;
Tony Wickham734dfbe2015-09-16 16:22:36 -070085 if (startActivityWithUninstallAffordance(d)) {
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
Tony Wickham734dfbe2015-09-16 16:22:36 -0700102 protected boolean startActivityWithUninstallAffordance(DragObject d) {
103 return startUninstallActivity(mLauncher, d.dragInfo);
104 }
105
Sunny Goyalaa8ef112015-06-12 20:04:41 -0700106 public static boolean startUninstallActivity(Launcher launcher, ItemInfo info) {
Sunny Goyal1a70cef2015-04-22 11:29:51 -0700107 final Pair<ComponentName, Integer> componentInfo = getAppInfoFlags(info);
Sunny Goyalaa8ef112015-06-12 20:04:41 -0700108 final UserHandleCompat user = info.user;
Sunny Goyal1a70cef2015-04-22 11:29:51 -0700109 return launcher.startApplicationUninstallActivity(
110 componentInfo.first, componentInfo.second, user);
111 }
112
Sunny Goyalfa401a12015-04-10 13:45:42 -0700113 @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 */
Tony Wickham734dfbe2015-09-16 16:22:36 -0700122 public interface UninstallSource {
Sunny Goyalfa401a12015-04-10 13:45:42 -0700123
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}