Home | History | Annotate | Download | only in launcher3
      1 package com.android.launcher3;
      2 
      3 import android.annotation.TargetApi;
      4 import android.content.ComponentName;
      5 import android.content.Context;
      6 import android.os.Build;
      7 import android.os.Bundle;
      8 import android.os.UserManager;
      9 import android.util.AttributeSet;
     10 import android.util.Pair;
     11 import com.android.launcher3.R;
     12 import com.android.launcher3.compat.UserHandleCompat;
     13 import com.android.launcher3.util.Thunk;
     14 
     15 public 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.uninstall_target_hover_tint);
     30 
     31         setDrawable(R.drawable.ic_uninstall_launcher);
     32     }
     33 
     34     @Override
     35     protected boolean supportsDrop(DragSource source, Object info) {
     36         return supportsDrop(getContext(), info);
     37     }
     38 
     39     @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
     40     public static boolean supportsDrop(Context context, Object info) {
     41         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
     42             UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
     43             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;
     85         if (startUninstallActivity(mLauncher, d.dragInfo)) {
     86 
     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 
    102     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 
    109     @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 }
    133