Follow up changes from ag/1190582.
Change-Id: I40121fc3d36e430c402da2835027283eb4b11071
(cherry picked from commit ce83f978d5bff5505a1d5f9bec894fe5f1091a4d)
diff --git a/packages/DocumentsUI/res/layout/item_root.xml b/packages/DocumentsUI/res/layout/item_root.xml
index 9671813..114fd09 100644
--- a/packages/DocumentsUI/res/layout/item_root.xml
+++ b/packages/DocumentsUI/res/layout/item_root.xml
@@ -77,7 +77,7 @@
android:duplicateParentState="true">
<ImageView
- android:id="@+id/unmount_icon"
+ android:id="@+id/eject_icon"
android:layout_width="@dimen/root_icon_size"
android:layout_height="match_parent"
android:scaleType="centerInside"
diff --git a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
index f40e771..1622f64 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
@@ -103,7 +103,6 @@
abstract void onTaskFinished(Uri... uris);
abstract void refreshDirectory(int anim);
- abstract void openRootSettings(RootInfo root);
/** Allows sub-classes to include information in a newly created State instance. */
abstract void includeState(State initialState);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/CheckedTask.java b/packages/DocumentsUI/src/com/android/documentsui/CheckedTask.java
index ae15902..ecd57cc 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/CheckedTask.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/CheckedTask.java
@@ -34,7 +34,7 @@
abstract class CheckedTask<Input, Output>
extends AsyncTask<Input, Void, Output> {
- private Check mCheck ;
+ private Check mCheck;
public CheckedTask(Check check) {
mCheck = check;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
index 8041a1b..05f36e8 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
@@ -97,7 +97,7 @@
mState.action == ACTION_CREATE ||
mState.action == ACTION_OPEN_TREE ||
mState.action == ACTION_PICK_COPY_DESTINATION) {
- RootsFragment.show(getFragmentManager(), null);
+ RootsFragment.show(getFragmentManager(), (Intent) null);
}
if (mState.restored) {
@@ -233,11 +233,6 @@
}
@Override
- void openRootSettings(RootInfo root) {
- throw new UnsupportedOperationException();
- }
-
- @Override
void refreshDirectory(int anim) {
final FragmentManager fm = getFragmentManager();
final RootInfo root = getCurrentRoot();
diff --git a/packages/DocumentsUI/src/com/android/documentsui/EjectRootTask.java b/packages/DocumentsUI/src/com/android/documentsui/EjectRootTask.java
index fcee472..e47a262 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/EjectRootTask.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/EjectRootTask.java
@@ -23,25 +23,30 @@
import android.provider.DocumentsContract;
import android.util.Log;
+import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
-final class EjectRootTask
- extends CheckedTask<Void, Boolean> {
+final class EjectRootTask extends CheckedTask<Void, Boolean> {
private final String mAuthority;
private final String mRootId;
- private final Consumer<Boolean> mListener;
+ private final Consumer<Boolean> mCallback;
private Context mContext;
- public EjectRootTask(Check check,
+ /**
+ * @param ejectCanceledCheck The method reference we use to see whether eject should be stopped
+ * at any point
+ * @param finishCallback The end callback necessary when the eject task finishes
+ */
+ public EjectRootTask(Context context,
String authority,
String rootId,
- Context context,
- Consumer<Boolean> listener) {
- super(check);
+ BooleanSupplier ejectCanceledCheck,
+ Consumer<Boolean> finishCallback) {
+ super(ejectCanceledCheck::getAsBoolean);
mAuthority = authority;
mRootId = rootId;
mContext = context;
- mListener = listener;
+ mCallback = finishCallback;
}
@Override
@@ -65,6 +70,6 @@
@Override
protected void finish(Boolean ejected) {
- mListener.accept(ejected);
+ mCallback.accept(ejected);
}
}
\ No newline at end of file
diff --git a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
index 01dd237..41f5d24 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
@@ -91,7 +91,7 @@
}
};
- RootsFragment.show(getFragmentManager(), null);
+ RootsFragment.show(getFragmentManager(), this::openRootSettings);
final Intent intent = getIntent();
final Uri uri = intent.getData();
@@ -241,7 +241,6 @@
return true;
}
- @Override
void openRootSettings(RootInfo root) {
Metrics.logUserAction(this, Metrics.USER_ACTION_SETTINGS);
final Intent intent = new Intent(DocumentsContract.ACTION_DOCUMENT_ROOT_SETTINGS);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/FilesMenuManager.java b/packages/DocumentsUI/src/com/android/documentsui/FilesMenuManager.java
index e1da944..a7e4905 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/FilesMenuManager.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/FilesMenuManager.java
@@ -16,7 +16,6 @@
package com.android.documentsui;
-import android.provider.DocumentsContract.Root;
import android.view.Menu;
import android.view.MenuItem;
@@ -45,7 +44,7 @@
@Override
void updateEject(MenuItem eject, RootInfo root) {
eject.setVisible(true);
- eject.setEnabled(((root.flags & Root.FLAG_SUPPORTS_EJECT) > 0) && !root.ejecting);
+ eject.setEnabled(root.supportsEject() && !root.ejecting);
}
@Override
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
index a33b35b..ac33288 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
@@ -84,8 +84,16 @@
private ListView mList;
private RootsAdapter mAdapter;
private LoaderCallbacks<Collection<RootInfo>> mCallbacks;
+ private Consumer<RootInfo> mOpenSettings = (RootInfo) -> {
+ throw new UnsupportedOperationException("Can't open settings.");
+ };
- public static void show(FragmentManager fm, Intent includeApps) {
+ public static void show(FragmentManager fm, Consumer<RootInfo> openSettings) {
+ RootsFragment fragment = show(fm, (Intent) null);
+ fragment.mOpenSettings = openSettings;
+ }
+
+ public static RootsFragment show(FragmentManager fm, Intent includeApps) {
final Bundle args = new Bundle();
args.putParcelable(EXTRA_INCLUDE_APPS, includeApps);
@@ -95,6 +103,8 @@
final FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.container_roots, fragment);
ft.commitAllowingStateLoss();
+
+ return fragment;
}
public static RootsFragment get(FragmentManager fm) {
@@ -108,8 +118,12 @@
final View view = inflater.inflate(R.layout.fragment_roots, container, false);
mList = (ListView) view.findViewById(R.id.roots_list);
mList.setOnItemClickListener(mItemListener);
- // For right-clicks, we want to trap the click and not pass it to OnClickListener
- // For all other clicks, we will pass the events down
+ // ListView does not have right-click specific listeners, so we will have a
+ // GenericMotionListener to listen for it.
+ // Currently, right click is viewed the same as long press, so we will have to quickly
+ // register for context menu when we receive a right click event, and quickly unregister
+ // it afterwards to prevent context menus popping up upon long presses.
+ // All other motion events will then get passed to OnItemClickListener.
mList.setOnGenericMotionListener(
new OnGenericMotionListener() {
@Override
@@ -270,12 +284,11 @@
final RootItem rootItem = (RootItem) mAdapter.getItem(adapterMenuInfo.position);
switch(item.getItemId()) {
case R.id.menu_eject_root:
- final View unmountIcon = adapterMenuInfo.targetView.findViewById(R.id.unmount_icon);
- ejectClicked(unmountIcon, rootItem.root);
+ final View ejectIcon = adapterMenuInfo.targetView.findViewById(R.id.eject_icon);
+ ejectClicked(ejectIcon, rootItem.root);
return true;
case R.id.menu_settings:
- final RootInfo root = rootItem.root;
- getBaseActivity().openRootSettings(root);
+ mOpenSettings.accept(rootItem.root);
return true;
default:
if (DEBUG) Log.d(TAG, "Unhandled menu item selected: " + item);
@@ -286,6 +299,7 @@
private static void ejectClicked(View ejectIcon, RootInfo root) {
assert(ejectIcon != null);
assert(ejectIcon.getContext() instanceof BaseActivity);
+ assert (!root.ejecting);
ejectIcon.setEnabled(false);
root.ejecting = true;
ejectRoot(
@@ -306,10 +320,10 @@
BooleanSupplier predicate = () -> {
return !(ejectIcon.getVisibility() == View.VISIBLE);
};
- new EjectRootTask(predicate::getAsBoolean,
+ new EjectRootTask(ejectIcon.getContext(),
authority,
rootId,
- ejectIcon.getContext(),
+ predicate,
listener).executeOnExecutor(ProviderExecutor.forAuthority(authority));
}
@@ -385,24 +399,24 @@
final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon);
final TextView title = (TextView) convertView.findViewById(android.R.id.title);
final TextView summary = (TextView) convertView.findViewById(android.R.id.summary);
- final ImageView unmountIcon = (ImageView) convertView.findViewById(R.id.unmount_icon);
+ final ImageView ejectIcon = (ImageView) convertView.findViewById(R.id.eject_icon);
final Context context = convertView.getContext();
icon.setImageDrawable(root.loadDrawerIcon(context));
title.setText(root.title);
if (root.supportsEject()) {
- unmountIcon.setVisibility(View.VISIBLE);
- unmountIcon.setImageDrawable(root.loadEjectIcon(context));
- unmountIcon.setOnClickListener(new OnClickListener() {
+ ejectIcon.setVisibility(View.VISIBLE);
+ ejectIcon.setImageDrawable(root.loadEjectIcon(context));
+ ejectIcon.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View unmountIcon) {
RootsFragment.ejectClicked(unmountIcon, root);
}
});
} else {
- unmountIcon.setVisibility(View.GONE);
- unmountIcon.setOnClickListener(null);
+ ejectIcon.setVisibility(View.GONE);
+ ejectIcon.setOnClickListener(null);
}
// Show available space if no summary
String summaryText = root.summary;
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/FilesMenuManagerTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/FilesMenuManagerTest.java
index 76ca2f3..3644abc 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/FilesMenuManagerTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/FilesMenuManagerTest.java
@@ -266,11 +266,21 @@
}
@Test
- public void testRootContextMenu_canEject() {
+ public void testRootContextMenu_eject() {
testRootInfo.flags = Root.FLAG_SUPPORTS_EJECT;
FilesMenuManager mgr = new FilesMenuManager(testSearchManager, state);
mgr.updateRootContextMenu(testMenu, testRootInfo);
eject.assertEnabled();
}
+
+ @Test
+ public void testRootContextMenu_ejectInProcess() {
+ testRootInfo.flags = Root.FLAG_SUPPORTS_EJECT;
+ testRootInfo.ejecting = true;
+ FilesMenuManager mgr = new FilesMenuManager(testSearchManager, state);
+ mgr.updateRootContextMenu(testMenu, testRootInfo);
+
+ eject.assertDisabled();
+ }
}