Merge "DO NOT MERGE: Temporarily disable the non-snapshot path for archives." into nyc-andromeda-dev
diff --git a/res/drawable/drag_shadow_background.xml b/res/drawable/drag_shadow_background.xml
index 49465cb..d6ec373 100644
--- a/res/drawable/drag_shadow_background.xml
+++ b/res/drawable/drag_shadow_background.xml
@@ -16,7 +16,7 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
- <solid android:color="@color/item_doc_background" />
+ <solid android:color="@color/item_drag_shadow_background" />
<stroke
android:width="1dp"
android:color="#ff9f9f9f" />
diff --git a/res/drawable/drag_shadow_background_no_drop.xml b/res/drawable/drag_shadow_background_no_drop.xml
new file mode 100644
index 0000000..b92c30a
--- /dev/null
+++ b/res/drawable/drag_shadow_background_no_drop.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <solid android:color="@color/item_drag_shadow_background_no_drop" />
+ <stroke
+ android:width="1dp"
+ android:color="#ff9f9f9f" />
+ <corners
+ android:bottomRightRadius="3dp"
+ android:bottomLeftRadius="3dp"
+ android:topLeftRadius="3dp"
+ android:topRightRadius="3dp"/>
+</shape>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 9da7742..1353d6f 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -39,4 +39,7 @@
<color name="item_doc_background_selected">@*android:color/accent_device_default_50</color>
<color name="item_breadcrumb_background_hovered">#1affffff</color>
+ <color name="item_drag_shadow_background">#fffafafa</color>
+ <color name="item_drag_shadow_background_no_drop">#ffffb6c1</color>
+
</resources>
diff --git a/src/com/android/documentsui/BaseActivity.java b/src/com/android/documentsui/BaseActivity.java
index d0160ce..3928a01 100644
--- a/src/com/android/documentsui/BaseActivity.java
+++ b/src/com/android/documentsui/BaseActivity.java
@@ -485,6 +485,11 @@
return mState;
}
+ public DragShadowBuilder getShadowBuilder() {
+ throw new UnsupportedOperationException(
+ "Drag and drop not supported, can't get shadow builder");
+ }
+
/**
* Set internal storage visible based on explicit user action.
*/
diff --git a/src/com/android/documentsui/dirlist/DragShadowBuilder.java b/src/com/android/documentsui/DragShadowBuilder.java
similarity index 72%
rename from src/com/android/documentsui/dirlist/DragShadowBuilder.java
rename to src/com/android/documentsui/DragShadowBuilder.java
index 0092f6c..d6877ec 100644
--- a/src/com/android/documentsui/dirlist/DragShadowBuilder.java
+++ b/src/com/android/documentsui/DragShadowBuilder.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.documentsui.dirlist;
+package com.android.documentsui;
import android.content.Context;
import android.graphics.Canvas;
@@ -26,32 +26,37 @@
import android.widget.ImageView;
import android.widget.TextView;
-import com.android.documentsui.R;
import com.android.documentsui.base.DocumentInfo;
import com.android.documentsui.base.Shared;
+import com.android.documentsui.dirlist.IconHelper;
+import com.android.documentsui.dirlist.Model;
import com.android.documentsui.selection.Selection;
import java.util.List;
import java.util.function.Function;
-final class DragShadowBuilder extends View.DragShadowBuilder {
+public final class DragShadowBuilder extends View.DragShadowBuilder {
private final View mShadowView;
private final TextView mTitle;
private final ImageView mIcon;
private final int mWidth;
private final int mHeight;
+ private final Drawable mDefaultBackground;
+ private final Drawable mNoDropBackground;
- public DragShadowBuilder(Context context, String title, Drawable icon) {
+ public DragShadowBuilder(Context context) {
mWidth = context.getResources().getDimensionPixelSize(R.dimen.drag_shadow_width);
- mHeight= context.getResources().getDimensionPixelSize(R.dimen.drag_shadow_height);
+ mHeight = context.getResources().getDimensionPixelSize(R.dimen.drag_shadow_height);
mShadowView = LayoutInflater.from(context).inflate(R.layout.drag_shadow_layout, null);
mTitle = (TextView) mShadowView.findViewById(android.R.id.title);
mIcon = (ImageView) mShadowView.findViewById(android.R.id.icon);
- mTitle.setText(title);
- mIcon.setImageDrawable(icon);
+ mDefaultBackground = context.getResources().getDrawable(R.drawable.drag_shadow_background,
+ null);
+ mNoDropBackground = context.getResources()
+ .getDrawable(R.drawable.drag_shadow_background_no_drop, null);
}
@Override
@@ -72,20 +77,39 @@
mShadowView.draw(canvas);
}
+ public void updateTitle(String title) {
+ mTitle.setText(title);
+ }
+
+ public void updateIcon(Drawable icon) {
+ mIcon.setImageDrawable(icon);
+ }
+
+ public void resetBackground() {
+ mShadowView.setBackground(mDefaultBackground);
+ }
+
+ public void setNoDropBackground() {
+ mShadowView.setBackground(mNoDropBackground);
+ }
+
/**
* Provides a means of fully isolating the mechanics of building drag shadows (and builders)
* in support of testing.
*/
- public static final class Factory implements Function<Selection, DragShadowBuilder> {
+ public static final class Updater implements Function<Selection, DragShadowBuilder> {
private final Context mContext;
private final IconHelper mIconHelper;
private final Drawable mDefaultDragIcon;
- private Model mModel;
+ private final Model mModel;
+ private final DragShadowBuilder mShadowBuilder;
- public Factory(
- Context context, Model model, IconHelper iconHelper, Drawable defaultDragIcon) {
+ public Updater(
+ Context context, DragShadowBuilder shadowBuilder, Model model,
+ IconHelper iconHelper, Drawable defaultDragIcon) {
mContext = context;
+ mShadowBuilder = shadowBuilder;
mModel = model;
mIconHelper = iconHelper;
mDefaultDragIcon = defaultDragIcon;
@@ -93,10 +117,10 @@
@Override
public DragShadowBuilder apply(Selection selection) {
- return new DragShadowBuilder(
- mContext,
- getDragTitle(selection),
- getDragIcon(selection));
+ mShadowBuilder.updateTitle(getDragTitle(selection));
+ mShadowBuilder.updateIcon(getDragIcon(selection));
+
+ return mShadowBuilder;
}
private Drawable getDragIcon(Selection selection) {
diff --git a/src/com/android/documentsui/DrawerController.java b/src/com/android/documentsui/DrawerController.java
index d5b8f4f..f8062a7 100644
--- a/src/com/android/documentsui/DrawerController.java
+++ b/src/com/android/documentsui/DrawerController.java
@@ -160,7 +160,7 @@
}
@Override
- public void onDragEntered(View v) {
+ public void onDragEntered(View v, Object localState) {
assert (v.getId() == R.id.drawer_edge);
setOpen(true);
diff --git a/src/com/android/documentsui/HorizontalBreadcrumb.java b/src/com/android/documentsui/HorizontalBreadcrumb.java
index e804e47..881fbbc 100644
--- a/src/com/android/documentsui/HorizontalBreadcrumb.java
+++ b/src/com/android/documentsui/HorizontalBreadcrumb.java
@@ -126,7 +126,7 @@
}
@Override
- public void onDragEntered(View v) {
+ public void onDragEntered(View v, Object localState) {
// do nothing
}
diff --git a/src/com/android/documentsui/ItemDragListener.java b/src/com/android/documentsui/ItemDragListener.java
index bb20909..79f71d9 100644
--- a/src/com/android/documentsui/ItemDragListener.java
+++ b/src/com/android/documentsui/ItemDragListener.java
@@ -78,7 +78,7 @@
}
private void handleEnteredEvent(View v, DragEvent event) {
- mDragHost.onDragEntered(v);
+ mDragHost.onDragEntered(v, event.getLocalState());
@Nullable TimerTask task = createOpenTask(v, event);
if (task == null) {
return;
@@ -167,7 +167,8 @@
/**
* Notifies right away when drag shadow enters the view
* @param v the view which drop shadow just entered
+ * @param localState the Local state object given by DragEvent
*/
- void onDragEntered(View v);
+ void onDragEntered(View v, Object localState);
}
}
diff --git a/src/com/android/documentsui/dirlist/DirectoryDragListener.java b/src/com/android/documentsui/dirlist/DirectoryDragListener.java
index 57175a9..044d688 100644
--- a/src/com/android/documentsui/dirlist/DirectoryDragListener.java
+++ b/src/com/android/documentsui/dirlist/DirectoryDragListener.java
@@ -35,9 +35,17 @@
public boolean onDrag(View v, DragEvent event) {
final boolean result = super.onDrag(v, event);
- if (event.getAction() == DragEvent.ACTION_DRAG_ENDED) {
- // getResult() is true if drag was accepted
- mDragHost.dragStopped(event.getResult());
+ switch (event.getAction()) {
+ case DragEvent.ACTION_DRAG_EXITED:
+ // If drag exits, we want to update drag and drop status on the drop shadow
+ mDragHost.dragExited(v);
+ break;
+ case DragEvent.ACTION_DRAG_ENDED:
+ // getResult() is true if drag was accepted
+ mDragHost.dragStopped(event.getResult());
+ break;
+ default:
+ break;
}
return result;
@@ -50,7 +58,7 @@
@Override
public @Nullable TimerTask createOpenTask(final View v, DragEvent event) {
- return mDragHost.shouldCopyTo(event.getLocalState(), v) ?
+ return mDragHost.canCopyTo(event.getLocalState(), v) ?
super.createOpenTask(v, event) : null;
}
}
\ No newline at end of file
diff --git a/src/com/android/documentsui/dirlist/DirectoryFragment.java b/src/com/android/documentsui/dirlist/DirectoryFragment.java
index 2885a4b..84d8b05 100644
--- a/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -335,7 +335,8 @@
mState,
this::getModelId,
mRecView::findChildViewUnder,
- getContext().getDrawable(com.android.internal.R.drawable.ic_doc_generic))
+ getContext().getDrawable(com.android.internal.R.drawable.ic_doc_generic),
+ mActivity.getShadowBuilder())
: DragStartListener.DUMMY;
EventHandler<InputEvent> gestureHandler = mState.allowMultiple
@@ -880,6 +881,12 @@
}
}
+ void dragExited(View v) {
+ // For now, just always reset drag shadow when drag exits
+ mActivity.getShadowBuilder().resetBackground();
+ v.updateDragShadow(mActivity.getShadowBuilder());
+ }
+
void dragStopped(boolean result) {
if (result) {
mSelectionMgr.clearSelection();
@@ -897,8 +904,15 @@
* In DirectoryFragment, we close the roots drawer right away.
*/
@Override
- public void onDragEntered(View view) {
- mActivity.setRootsDrawerOpen(false);
+ public void onDragEntered(View v, Object localState) {
+ mActivity.setRootsDrawerOpen(false);
+
+ if (canCopyTo(localState, v)) {
+ mActivity.getShadowBuilder().resetBackground();
+ } else {
+ mActivity.getShadowBuilder().setNoDropBackground();
+ }
+ v.updateDragShadow(mActivity.getShadowBuilder());
}
/**
@@ -924,7 +938,7 @@
assert(DocumentClipper.getOpType(clipData) == FileOperationService.OPERATION_COPY);
- if (!shouldCopyTo(event.getLocalState(), v)) {
+ if (!canCopyTo(event.getLocalState(), v)) {
return false;
}
@@ -946,7 +960,7 @@
// Don't copy from the cwd into a provided list of prohibited directories. (ie. into cwd, into
// a selected directory). Note: this currently doesn't work for multi-window drag, because
// localState isn't carried over from one process to another.
- boolean shouldCopyTo(Object dragLocalState, View destinationView) {
+ boolean canCopyTo(Object dragLocalState, View destinationView) {
if (dragLocalState == null || !(dragLocalState instanceof List<?>)) {
if (DEBUG) Log.d(TAG, "Invalid local state object. Will allow copy.");
return true;
diff --git a/src/com/android/documentsui/dirlist/DragStartListener.java b/src/com/android/documentsui/dirlist/DragStartListener.java
index 5bf41d7..af864d9 100644
--- a/src/com/android/documentsui/dirlist/DragStartListener.java
+++ b/src/com/android/documentsui/dirlist/DragStartListener.java
@@ -25,13 +25,14 @@
import android.util.Log;
import android.view.View;
+import com.android.documentsui.DragShadowBuilder;
import com.android.documentsui.base.DocumentInfo;
import com.android.documentsui.base.Events;
-import com.android.documentsui.base.State;
import com.android.documentsui.base.Events.InputEvent;
+import com.android.documentsui.base.State;
import com.android.documentsui.clipping.DocumentClipper;
-import com.android.documentsui.selection.SelectionManager;
import com.android.documentsui.selection.Selection;
+import com.android.documentsui.selection.SelectionManager;
import com.android.documentsui.services.FileOperationService;
import com.android.documentsui.services.FileOperationService.OpType;
@@ -190,10 +191,15 @@
State state,
Function<View, String> idFinder,
ViewFinder viewFinder,
- Drawable defaultDragIcon) {
+ Drawable defaultDragIcon,
+ DragShadowBuilder shadowBuilder) {
- DragShadowBuilder.Factory shadowFactory =
- new DragShadowBuilder.Factory(context, model, iconHelper, defaultDragIcon);
+ DragShadowBuilder.Updater shadowFactory = new DragShadowBuilder.Updater(
+ context,
+ shadowBuilder,
+ model,
+ iconHelper,
+ defaultDragIcon);
return new ActiveListener(
state,
diff --git a/src/com/android/documentsui/files/FilesActivity.java b/src/com/android/documentsui/files/FilesActivity.java
index 5777f9c..877914b 100644
--- a/src/com/android/documentsui/files/FilesActivity.java
+++ b/src/com/android/documentsui/files/FilesActivity.java
@@ -37,6 +37,7 @@
import com.android.documentsui.ActivityConfig;
import com.android.documentsui.BaseActivity;
import com.android.documentsui.DocumentsApplication;
+import com.android.documentsui.DragShadowBuilder;
import com.android.documentsui.MenuManager.DirectoryDetails;
import com.android.documentsui.MenuManager.SelectionDetails;
import com.android.documentsui.OperationDialogFragment;
@@ -79,6 +80,7 @@
private DocumentClipper mClipper;
private ActionModeController mActionModeController;
private ActivityInputHandler mActivityInputHandler;
+ private DragShadowBuilder mShadowBuilder;
public FilesActivity() {
super(R.layout.files_activity, TAG);
@@ -99,9 +101,9 @@
return mClipper.hasItemsToPaste();
}
});
-
mDialogs = DialogController.create(this, getMessages());
+ mShadowBuilder = new DragShadowBuilder(this);
mActionModeController = new ActionModeController(
this,
mSelectionMgr,
@@ -297,6 +299,11 @@
}
@Override
+ public DragShadowBuilder getShadowBuilder() {
+ return mShadowBuilder;
+ }
+
+ @Override
public boolean onKeyShortcut(int keyCode, KeyEvent event) {
DirectoryFragment dir;
// TODO: All key events should be statically bound using alphabeticShortcut.
diff --git a/src/com/android/documentsui/sidebar/RootsFragment.java b/src/com/android/documentsui/sidebar/RootsFragment.java
index ecdc053..8890fb3 100644
--- a/src/com/android/documentsui/sidebar/RootsFragment.java
+++ b/src/com/android/documentsui/sidebar/RootsFragment.java
@@ -376,7 +376,7 @@
* In RootsFragment we don't do anything
*/
@Override
- public void onDragEntered(View v) {
+ public void onDragEntered(View v, Object localState) {
}
/**
diff --git a/tests/unit/com/android/documentsui/ItemDragListenerTest.java b/tests/unit/com/android/documentsui/ItemDragListenerTest.java
index 6293c45..865d8b6 100644
--- a/tests/unit/com/android/documentsui/ItemDragListenerTest.java
+++ b/tests/unit/com/android/documentsui/ItemDragListenerTest.java
@@ -217,7 +217,7 @@
}
@Override
- public void onDragEntered(View v) {
+ public void onDragEntered(View v, Object localState) {
mLastEnteredView = v;
}
}
diff --git a/tests/unit/com/android/documentsui/dirlist/DragScrollListenerTest.java b/tests/unit/com/android/documentsui/dirlist/DragScrollListenerTest.java
index daae554..fc5933a 100644
--- a/tests/unit/com/android/documentsui/dirlist/DragScrollListenerTest.java
+++ b/tests/unit/com/android/documentsui/dirlist/DragScrollListenerTest.java
@@ -200,7 +200,7 @@
}
@Override
- public void onDragEntered(View v) {
+ public void onDragEntered(View v, Object localState) {
}
}
diff --git a/tests/unit/com/android/documentsui/dirlist/DragStartListenerTest.java b/tests/unit/com/android/documentsui/dirlist/DragStartListenerTest.java
index f2e044b..b898653 100644
--- a/tests/unit/com/android/documentsui/dirlist/DragStartListenerTest.java
+++ b/tests/unit/com/android/documentsui/dirlist/DragStartListenerTest.java
@@ -24,6 +24,7 @@
import com.android.documentsui.base.State;
import com.android.documentsui.dirlist.DragStartListener.ActiveListener;
+import com.android.documentsui.DragShadowBuilder;
import com.android.documentsui.base.Events.InputEvent;
import com.android.documentsui.selection.SelectionManager;
import com.android.documentsui.selection.Selection;