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