Merging duplicate logic for deferred drop handling in Worksace and Folder
> All the logic is contained in UninstallDropTarget
> Also fixing a bug were mWaitingForResume was not cleared
Bug: 34692289
Change-Id: I617475ce53062902d6817954fb608198e6e03d3c
diff --git a/src/com/android/launcher3/UninstallDropTarget.java b/src/com/android/launcher3/UninstallDropTarget.java
index 3f7de06..e8c4528 100644
--- a/src/com/android/launcher3/UninstallDropTarget.java
+++ b/src/com/android/launcher3/UninstallDropTarget.java
@@ -12,9 +12,13 @@
import android.os.UserManager;
import android.util.AttributeSet;
import android.util.Log;
+import android.view.View;
import android.widget.Toast;
+import com.android.launcher3.Launcher.OnResumeCallback;
import com.android.launcher3.compat.LauncherAppsCompat;
+import com.android.launcher3.dragndrop.DragOptions;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
import java.net.URISyntaxException;
@@ -91,98 +95,110 @@
}
@Override
- public void onDrop(DragObject d) {
- // Differ item deletion
- if (d.dragSource instanceof DropTargetSource) {
- ((DropTargetSource) d.dragSource).deferCompleteDropAfterUninstallActivity();
+ public void onDrop(DragObject d, DragOptions options) {
+ // Defer onComplete
+ if (options.deferCompleteForUninstall) {
+ d.dragSource = new DeferredOnComplete(d.dragSource, getContext());
}
- super.onDrop(d);
+ super.onDrop(d, options);
}
@Override
public void completeDrop(final DragObject d) {
- DropTargetResultCallback callback = d.dragSource instanceof DropTargetResultCallback
- ? (DropTargetResultCallback) d.dragSource : null;
- startUninstallActivity(mLauncher, d.dragInfo, callback);
+ ComponentName target = performDropAction(d);
+ if (d.dragSource instanceof DeferredOnComplete) {
+ DeferredOnComplete deferred = (DeferredOnComplete) d.dragSource;
+ if (target != null) {
+ deferred.mPackageName = target.getPackageName();
+ mLauncher.setOnResumeCallback(deferred);
+ } else {
+ deferred.sendFailure();
+ }
+ }
}
- public static boolean startUninstallActivity(Launcher launcher, ItemInfo info) {
- return startUninstallActivity(launcher, info, null);
+ /**
+ * Performs the drop action and returns the target component for the dragObject or null if
+ * the action was not performed.
+ */
+ protected ComponentName performDropAction(DragObject d) {
+ return performDropAction(mLauncher, d.dragInfo);
}
- public static boolean startUninstallActivity(
- final Launcher launcher, ItemInfo info, DropTargetResultCallback callback) {
- final ComponentName cn = getUninstallTarget(launcher, info);
-
- boolean canUninstall;
+ /**
+ * Performs the drop action and returns the target component for the dragObject or null if
+ * the action was not performed.
+ */
+ private static ComponentName performDropAction(Context context, ItemInfo info) {
+ ComponentName cn = getUninstallTarget(context, info);
if (cn == null) {
// System applications cannot be installed. For now, show a toast explaining that.
// We may give them the option of disabling apps this way.
- Toast.makeText(launcher, R.string.uninstall_system_app_text, Toast.LENGTH_SHORT).show();
- canUninstall = false;
- } else {
- try {
- Intent i = Intent.parseUri(launcher.getString(R.string.delete_package_intent), 0)
- .setData(Uri.fromParts("package", cn.getPackageName(), cn.getClassName()))
- .putExtra(Intent.EXTRA_USER, info.user);
- launcher.startActivity(i);
- canUninstall = true;
- } catch (URISyntaxException e) {
- Log.e(TAG, "Failed to parse intent to start uninstall activity for item=" + info);
- canUninstall = false;
+ Toast.makeText(context, R.string.uninstall_system_app_text, Toast.LENGTH_SHORT).show();
+ return null;
+ }
+ try {
+ Intent i = Intent.parseUri(context.getString(R.string.delete_package_intent), 0)
+ .setData(Uri.fromParts("package", cn.getPackageName(), cn.getClassName()))
+ .putExtra(Intent.EXTRA_USER, info.user);
+ context.startActivity(i);
+ return cn;
+ } catch (URISyntaxException e) {
+ Log.e(TAG, "Failed to parse intent to start uninstall activity for item=" + info);
+ return null;
+ }
+ }
+
+ public static boolean startUninstallActivity(Launcher launcher, ItemInfo info) {
+ return performDropAction(launcher, info) != null;
+ }
+
+ /**
+ * A wrapper around {@link DragSource} which delays the {@link #onDropCompleted} action until
+ * {@link #onLauncherResume}
+ */
+ private class DeferredOnComplete implements DragSource, OnResumeCallback {
+
+ private final DragSource mOriginal;
+ private final Context mContext;
+
+ private String mPackageName;
+ private DragObject mDragObject;
+
+ public DeferredOnComplete(DragSource original, Context context) {
+ mOriginal = original;
+ mContext = context;
+ }
+
+ @Override
+ public void onDropCompleted(View target, DragObject d, boolean isFlingToDelete,
+ boolean success) {
+ mDragObject = d;
+ }
+
+ @Override
+ public void fillInLogContainerData(View v, ItemInfo info, Target target,
+ Target targetParent) {
+ mOriginal.fillInLogContainerData(v, info, target, targetParent);
+ }
+
+ @Override
+ public void onLauncherResume() {
+ // We use MATCH_UNINSTALLED_PACKAGES as the app can be on SD card as well.
+ if (LauncherAppsCompat.getInstance(mContext)
+ .getApplicationInfo(mPackageName, PackageManager.MATCH_UNINSTALLED_PACKAGES,
+ mDragObject.dragInfo.user) == null) {
+ mDragObject.dragSource = mOriginal;
+ mOriginal.onDropCompleted(UninstallDropTarget.this, mDragObject, false, true);
+ } else {
+ sendFailure();
}
}
- if (callback != null) {
- sendUninstallResult(launcher, canUninstall, cn, info.user, callback);
+
+ public void sendFailure() {
+ mDragObject.dragSource = mOriginal;
+ mDragObject.cancelled = true;
+ mOriginal.onDropCompleted(UninstallDropTarget.this, mDragObject, false, false);
}
- return canUninstall;
- }
-
- /**
- * Notifies the {@param callback} whether the uninstall was successful or not.
- *
- * Since there is no direct callback for an uninstall request, we check the package existence
- * when the launch resumes next time. This assumes that the uninstall activity will finish only
- * after the task is completed
- */
- protected static void sendUninstallResult(
- final Launcher launcher, boolean activityStarted,
- final ComponentName cn, final UserHandle user,
- final DropTargetResultCallback callback) {
- if (activityStarted) {
- final Runnable checkIfUninstallWasSuccess = new Runnable() {
- @Override
- public void run() {
- // We use MATCH_UNINSTALLED_PACKAGES as the app can be on SD card as well.
- boolean uninstallSuccessful = LauncherAppsCompat.getInstance(launcher)
- .getApplicationInfo(cn.getPackageName(),
- PackageManager.MATCH_UNINSTALLED_PACKAGES, user) == null;
- callback.onDragObjectRemoved(uninstallSuccessful);
- }
- };
- launcher.addOnResumeCallback(checkIfUninstallWasSuccess);
- } else {
- callback.onDragObjectRemoved(false);
- }
- }
-
- public interface DropTargetResultCallback {
- /**
- * A drag operation was complete.
- * @param isRemoved true if the drag object should be removed, false otherwise.
- */
- void onDragObjectRemoved(boolean isRemoved);
- }
-
- /**
- * Interface defining an object that can provide uninstallable drag objects.
- */
- public interface DropTargetSource extends DropTargetResultCallback {
-
- /**
- * Indicates that an uninstall request are made and the actual result may come
- * after some time.
- */
- void deferCompleteDropAfterUninstallActivity();
}
}