Normalize and improve menu fiddling.

Also, don't show copy/paste menu items (though they can still be invoked via keyboard).
Show copy to /move to instead.

Change-Id: I6e7bdf35bf370ea30d4f12a5a200ad38ff0221f4
diff --git a/res/menu/activity.xml b/res/menu/activity.xml
index 673a254..7e0649b 100644
--- a/res/menu/activity.xml
+++ b/res/menu/activity.xml
@@ -23,13 +23,6 @@
         android:actionViewClass="android.widget.SearchView"
         android:imeOptions="actionSearch" />
     <item
-        android:id="@+id/menu_create_dir"
-        android:title="@string/menu_create_dir"
-        android:icon="@drawable/ic_menu_new_folder"
-        android:alphabeticShortcut="e"
-        android:showAsAction="always"
-        android:visible="false" />
-    <item
         android:id="@+id/menu_sort"
         android:title="@string/menu_sort"
         android:icon="@drawable/ic_menu_sortby"
@@ -63,6 +56,13 @@
         android:showAsAction="never"
         android:visible="false" />
     <item
+        android:id="@+id/menu_create_dir"
+        android:title="@string/menu_create_dir"
+        android:icon="@drawable/ic_menu_new_folder"
+        android:alphabeticShortcut="e"
+        android:showAsAction="always"
+        android:visible="false" />
+    <item
         android:id="@+id/menu_paste_from_clipboard"
         android:title="@string/menu_paste_from_clipboard"
         android:alphabeticShortcut="v"
@@ -70,11 +70,11 @@
         android:visible="false" />
     <!-- Copy action is defined in mode_directory.xml -->
     <item
-        android:id="@+id/menu_advanced"
+        android:id="@+id/menu_file_size"
         android:showAsAction="never"
         android:visible="false" />
     <item
-        android:id="@+id/menu_file_size"
+        android:id="@+id/menu_advanced"
         android:showAsAction="never"
         android:visible="false" />
     <item
diff --git a/res/values/config.xml b/res/values/config.xml
index ce5b174..ed7820b 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -15,5 +15,5 @@
 -->
 
 <resources>
-    <bool name="productivity_device">false</bool>
+    <bool name="productivity_device">true</bool>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a4acb60..d21b5ee 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -27,7 +27,7 @@
     <string name="title_save">Save to</string>
 
     <!-- Menu item that creates a new directory/folder at the current location [CHAR LIMIT=24] -->
-    <string name="menu_create_dir">Create folder</string>
+    <string name="menu_create_dir">New folder</string>
     <!-- Menu item that switches view to show documents as a large-format grid of thumbnails [CHAR LIMIT=24] -->
     <string name="menu_grid">Grid view</string>
     <!-- Menu item that switches view to show documents as a list [CHAR LIMIT=24] -->
diff --git a/src/com/android/documentsui/BaseActivity.java b/src/com/android/documentsui/BaseActivity.java
index ab0f666..caaa2b9 100644
--- a/src/com/android/documentsui/BaseActivity.java
+++ b/src/com/android/documentsui/BaseActivity.java
@@ -128,10 +128,10 @@
 
     @Override
     public boolean onPrepareOptionsMenu(Menu menu) {
-        boolean shown = super.onPrepareOptionsMenu(menu);
+        super.onPrepareOptionsMenu(menu);
 
         final RootInfo root = getCurrentRoot();
-        final DocumentInfo cwd = getCurrentDirectory();
+        final boolean inRecents = getCurrentDirectory() == null;
 
         final MenuItem sort = menu.findItem(R.id.menu_sort);
         final MenuItem sortSize = menu.findItem(R.id.menu_sort_size);
@@ -141,24 +141,28 @@
         final MenuItem fileSize = menu.findItem(R.id.menu_file_size);
         final MenuItem settings = menu.findItem(R.id.menu_settings);
 
-        mSearchManager.update(root);
+        // I'm thinkin' this isn't necesary here. If it is...'cuz of a bug....
+        // then uncomment the linke and let's get a proper bug reference here.
+        // mSearchManager.update(root);
 
         // Search uses backend ranking; no sorting
-        sort.setVisible(cwd != null && !mSearchManager.isSearching());
+        sort.setVisible(!inRecents && !mSearchManager.isSearching());
+
+        // grid/list is effectively a toggle.
+        grid.setVisible(mState.derivedMode != State.MODE_GRID);
+        list.setVisible(mState.derivedMode != State.MODE_LIST);
+
+        sortSize.setVisible(mState.showSize); // Only sort by size when visible
+        fileSize.setVisible(!mState.forceSize);
+        advanced.setVisible(!mState.forceAdvanced);
+        settings.setVisible((root.flags & Root.FLAG_HAS_SETTINGS) != 0);
 
         advanced.setTitle(LocalPreferences.getDisplayAdvancedDevices(this)
                 ? R.string.menu_advanced_hide : R.string.menu_advanced_show);
         fileSize.setTitle(LocalPreferences.getDisplayFileSize(this)
                 ? R.string.menu_file_size_hide : R.string.menu_file_size_show);
 
-        sortSize.setVisible(mState.showSize); // Only sort by size when visible
-        fileSize.setVisible(!mState.showSize);
-        grid.setVisible(mState.derivedMode != State.MODE_GRID);
-        list.setVisible(mState.derivedMode != State.MODE_LIST);
-        advanced.setVisible(!mState.showAdvanced);
-        settings.setVisible((root.flags & Root.FLAG_HAS_SETTINGS) != 0);
-
-        return shown;
+        return true;
     }
 
     State buildDefaultState() {
@@ -277,6 +281,7 @@
         return cwd != null
                 && cwd.isCreateSupported()
                 && !mSearchManager.isSearching()
+                && !root.isRecents()
                 && !root.isDownloads();
     }
 
diff --git a/src/com/android/documentsui/CopyService.java b/src/com/android/documentsui/CopyService.java
index 362052c..66f8acd 100644
--- a/src/com/android/documentsui/CopyService.java
+++ b/src/com/android/documentsui/CopyService.java
@@ -119,7 +119,7 @@
 
         int toastMessage = (mode == TRANSFER_MODE_COPY) ? R.plurals.copy_begin
                 : R.plurals.move_begin;
-        Shared.makeSnackbar(activity,
+        Snackbars.makeSnackbar(activity,
                 res.getQuantityString(toastMessage, srcDocs.size(), srcDocs.size()),
                 Snackbar.LENGTH_SHORT).show();
         activity.startService(copyIntent);
diff --git a/src/com/android/documentsui/CreateDirectoryFragment.java b/src/com/android/documentsui/CreateDirectoryFragment.java
index 9f44516..c6425a6 100644
--- a/src/com/android/documentsui/CreateDirectoryFragment.java
+++ b/src/com/android/documentsui/CreateDirectoryFragment.java
@@ -147,7 +147,7 @@
                 // Navigate into newly created child
                 mActivity.onDirectoryCreated(result);
             } else {
-                Shared.makeSnackbar(mActivity, R.string.create_error, Snackbar.LENGTH_SHORT).show();
+                Snackbars.makeSnackbar(mActivity, R.string.create_error, Snackbar.LENGTH_SHORT).show();
             }
 
             mActivity.setPending(false);
diff --git a/src/com/android/documentsui/DirectoryFragment.java b/src/com/android/documentsui/DirectoryFragment.java
index b3ce103..0abbf4e 100644
--- a/src/com/android/documentsui/DirectoryFragment.java
+++ b/src/com/android/documentsui/DirectoryFragment.java
@@ -44,7 +44,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.Loader;
-import android.content.res.Resources;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
@@ -54,7 +53,6 @@
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.CancellationSignal;
-import android.os.Handler;
 import android.os.Looper;
 import android.os.OperationCanceledException;
 import android.os.Parcelable;
@@ -134,8 +132,6 @@
     private Model mModel;
     private Model.UpdateListener mModelUpdateListener = new ModelUpdateListener();
 
-    private final Handler mHandler = new Handler(Looper.getMainLooper());
-
     private View mEmptyView;
     private RecyclerView mRecView;
 
@@ -217,8 +213,6 @@
     @Override
     public View onCreateView(
             LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-        final Context context = inflater.getContext();
-        final Resources res = context.getResources();
         final View view = inflater.inflate(R.layout.fragment_directory, container, false);
 
         mMessageBar = MessageBar.create(getChildFragmentManager());
@@ -678,6 +672,7 @@
             checkNotNull(mMenu);
             // Delegate update logic to our owning action, since specialized logic is desired.
             mFragmentTuner.updateActionMenu(mMenu, mType, mNoDeleteCount == 0);
+            Menus.disableHiddenItems(mMenu);
         }
 
         @Override
@@ -799,13 +794,12 @@
 
     private void deleteDocuments(final Selection selected) {
         Context context = getActivity();
-        ContentResolver resolver = context.getContentResolver();
         String message = Shared.getQuantityString(context, R.plurals.deleting, selected.size());
 
         mModel.markForDeletion(selected);
 
         final Activity activity = getActivity();
-        Shared.makeSnackbar(activity, message, Snackbar.LENGTH_LONG)
+        Snackbars.makeSnackbar(activity, message, Snackbar.LENGTH_LONG)
                 .setAction(
                         R.string.undo,
                         new android.view.View.OnClickListener() {
@@ -823,7 +817,7 @@
                                             new Model.DeletionListener() {
                                                 @Override
                                                 public void onError() {
-                                                    Shared.makeSnackbar(
+                                                    Snackbars.makeSnackbar(
                                                             activity,
                                                             R.string.toast_failed_delete,
                                                             Snackbar.LENGTH_LONG)
@@ -1244,7 +1238,7 @@
 
     private void copyDocuments(final List<DocumentInfo> docs, final DocumentInfo destination) {
         if (!canCopy(docs, destination)) {
-            Shared.makeSnackbar(
+            Snackbars.makeSnackbar(
                     getActivity(),
                     R.string.clipboard_files_cannot_paste,
                     Snackbar.LENGTH_SHORT)
@@ -1298,7 +1292,7 @@
             void onDocumentsReady(List<DocumentInfo> docs) {
                 mClipper.clipDocuments(docs);
                 Activity activity = getActivity();
-                Shared.makeSnackbar(activity,
+                Snackbars.makeSnackbar(activity,
                         activity.getResources().getQuantityString(
                                 R.plurals.clipboard_files_clipped, docs.size(), docs.size()),
                                 Snackbar.LENGTH_SHORT).show();
@@ -1608,23 +1602,25 @@
 
         @Override
         public void updateActionMenu(Menu menu, int dirType, boolean canDelete) {
+            boolean copyEnabled = mManaging && dirType != TYPE_RECENT_OPEN;
+            // TODO: The selection needs to be deletable.
+            boolean moveEnabled =
+                    SystemProperties.getBoolean("debug.documentsui.enable_move", false);
+            menu.findItem(R.id.menu_copy_to_clipboard).setEnabled(copyEnabled);
 
             final MenuItem open = menu.findItem(R.id.menu_open);
             final MenuItem share = menu.findItem(R.id.menu_share);
             final MenuItem delete = menu.findItem(R.id.menu_delete);
             final MenuItem copyTo = menu.findItem(R.id.menu_copy_to);
             final MenuItem moveTo = menu.findItem(R.id.menu_move_to);
-            final MenuItem copyToClipboard = menu.findItem(R.id.menu_copy_to_clipboard);
 
             open.setVisible(!mManaging);
             share.setVisible(mManaging);
             delete.setVisible(mManaging && canDelete);
-            // Disable copying from the Recents view.
-            copyTo.setVisible(mManaging && dirType != TYPE_RECENT_OPEN);
-            moveTo.setVisible(SystemProperties.getBoolean("debug.documentsui.enable_move", false));
-
-            // Only shown in files mode.
-            copyToClipboard.setVisible(false);
+            copyTo.setVisible(copyEnabled);
+            copyTo.setEnabled(copyEnabled);
+            moveTo.setVisible(moveEnabled);
+            moveTo.setEnabled(moveEnabled);
         }
 
         @Override
@@ -1638,13 +1634,14 @@
         @Override
         public void updateActionMenu(Menu menu, int dirType, boolean canDelete) {
 
+            menu.findItem(R.id.menu_copy_to_clipboard).setEnabled(dirType != TYPE_RECENT_OPEN);
+
             menu.findItem(R.id.menu_share).setVisible(true);
             menu.findItem(R.id.menu_delete).setVisible(canDelete);
-            menu.findItem(R.id.menu_copy_to_clipboard).setVisible(true);
 
             menu.findItem(R.id.menu_open).setVisible(false);
-            menu.findItem(R.id.menu_copy_to).setVisible(false);
-            menu.findItem(R.id.menu_move_to).setVisible(false);
+            menu.findItem(R.id.menu_copy_to).setVisible(true);
+            menu.findItem(R.id.menu_move_to).setVisible(true);
         }
 
         @Override
diff --git a/src/com/android/documentsui/DocumentsActivity.java b/src/com/android/documentsui/DocumentsActivity.java
index ced03cc..6b428f5 100644
--- a/src/com/android/documentsui/DocumentsActivity.java
+++ b/src/com/android/documentsui/DocumentsActivity.java
@@ -89,8 +89,6 @@
             setTheme(R.style.DocumentsNonDialogTheme);
         }
 
-        final Context context = this;
-
         if (mShowAsDialog) {
             mDrawer = DrawerController.createDummy();
 
@@ -314,41 +312,35 @@
     public boolean onPrepareOptionsMenu(Menu menu) {
         super.onPrepareOptionsMenu(menu);
 
-        final RootInfo root = getCurrentRoot();
         final DocumentInfo cwd = getCurrentDirectory();
 
         final MenuItem createDir = menu.findItem(R.id.menu_create_dir);
         final MenuItem grid = menu.findItem(R.id.menu_grid);
         final MenuItem list = menu.findItem(R.id.menu_list);
-        final MenuItem advanced = menu.findItem(R.id.menu_advanced);
         final MenuItem fileSize = menu.findItem(R.id.menu_file_size);
         final MenuItem settings = menu.findItem(R.id.menu_settings);
 
-        boolean fileSizeVisible = mState.showSize && !mState.forceSize;
-        if (mState.action == ACTION_CREATE
+        boolean recents = cwd == null;
+        boolean picking = mState.action == ACTION_CREATE
                 || mState.action == ACTION_OPEN_TREE
-                || mState.action == ACTION_OPEN_COPY_DESTINATION) {
-            createDir.setVisible(cwd != null && cwd.isCreateSupported());
-            mSearchManager.showMenu(false);
+                || mState.action == ACTION_OPEN_COPY_DESTINATION;
 
-            // No display options in recent directories
-            if (cwd == null) {
-                grid.setVisible(false);
-                list.setVisible(false);
-                fileSizeVisible = false;
-            }
+        createDir.setVisible(picking && !recents && cwd.isCreateSupported());
+        mSearchManager.showMenu(!picking);
 
-            if (mState.action == ACTION_CREATE) {
-                final FragmentManager fm = getFragmentManager();
-                SaveFragment.get(fm).setSaveEnabled(cwd != null && cwd.isCreateSupported());
-            }
-        } else {
-            createDir.setVisible(false);
+        // No display options in recent directories
+        grid.setVisible(!(picking && recents));
+        list.setVisible(!(picking && recents));
+
+        fileSize.setVisible(fileSize.isVisible() && !picking);
+        settings.setVisible(false);
+
+        if (mState.action == ACTION_CREATE) {
+            final FragmentManager fm = getFragmentManager();
+            SaveFragment.get(fm).setSaveEnabled(cwd != null && cwd.isCreateSupported());
         }
 
-        advanced.setVisible(!mState.forceAdvanced);
-        fileSize.setVisible(fileSizeVisible);
-        settings.setVisible(false);
+        Menus.disableHiddenItems(menu);
 
         return true;
     }
@@ -611,7 +603,7 @@
             if (result != null) {
                 onTaskFinished(result);
             } else {
-                Shared.makeSnackbar(
+                Snackbars.makeSnackbar(
                     DocumentsActivity.this, R.string.save_error, Snackbar.LENGTH_SHORT).show();
             }
 
diff --git a/src/com/android/documentsui/FilesActivity.java b/src/com/android/documentsui/FilesActivity.java
index f6a5131..70ddf59 100644
--- a/src/com/android/documentsui/FilesActivity.java
+++ b/src/com/android/documentsui/FilesActivity.java
@@ -225,30 +225,23 @@
 
     @Override
     public boolean onPrepareOptionsMenu(Menu menu) {
-        boolean shown = super.onPrepareOptionsMenu(menu);
-
-        menu.findItem(R.id.menu_file_size).setVisible(true);
-        menu.findItem(R.id.menu_advanced).setVisible(true);
+        super.onPrepareOptionsMenu(menu);
 
         final MenuItem createDir = menu.findItem(R.id.menu_create_dir);
         final MenuItem newWindow = menu.findItem(R.id.menu_new_window);
         final MenuItem pasteFromCb = menu.findItem(R.id.menu_paste_from_clipboard);
 
-        boolean canCreateDir = canCreateDirectory();
-
         createDir.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
-        createDir.setVisible(canCreateDir);
-        createDir.setEnabled(canCreateDir);
+        createDir.setVisible(true);
+        createDir.setEnabled(canCreateDirectory());
+
+        pasteFromCb.setEnabled(mClipper.hasItemsToPaste());
 
         newWindow.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
         newWindow.setVisible(mProductivityDevice);
-        newWindow.setEnabled(mProductivityDevice);
 
-        pasteFromCb.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
-        pasteFromCb.setVisible(true);
-        pasteFromCb.setEnabled(mClipper.hasItemsToPaste());
-
-        return shown;
+        Menus.disableHiddenItems(menu, pasteFromCb);
+        return true;
     }
 
     @Override
@@ -347,7 +340,7 @@
         try {
             startActivity(intent);
         } catch (ActivityNotFoundException ex2) {
-            Shared.makeSnackbar(this, R.string.toast_no_application, Snackbar.LENGTH_SHORT).show();
+            Snackbars.makeSnackbar(this, R.string.toast_no_application, Snackbar.LENGTH_SHORT).show();
         }
     }
 
diff --git a/src/com/android/documentsui/ManageRootActivity.java b/src/com/android/documentsui/ManageRootActivity.java
index ed7333d..14a33f9 100644
--- a/src/com/android/documentsui/ManageRootActivity.java
+++ b/src/com/android/documentsui/ManageRootActivity.java
@@ -140,6 +140,7 @@
     @Override
     public boolean onPrepareOptionsMenu(Menu menu) {
         super.onPrepareOptionsMenu(menu);
+        Menus.disableHiddenItems(menu);
         return true;
     }
 
@@ -184,7 +185,7 @@
                 try {
                     startActivity(view);
                 } catch (ActivityNotFoundException ex2) {
-                    Shared.makeSnackbar(this, R.string.toast_no_application, Snackbar.LENGTH_SHORT)
+                    Snackbars.makeSnackbar(this, R.string.toast_no_application, Snackbar.LENGTH_SHORT)
                             .show();
                 }
             }
diff --git a/src/com/android/documentsui/Menus.java b/src/com/android/documentsui/Menus.java
new file mode 100644
index 0000000..3f43a3d
--- /dev/null
+++ b/src/com/android/documentsui/Menus.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+package com.android.documentsui;
+
+import android.view.Menu;
+import android.view.MenuItem;
+
+final class Menus {
+
+    private Menus() {}
+
+    /**
+     * Disables hidden menu items so that they are not invokable via command shortcuts
+     */
+    static void disableHiddenItems(Menu menu, MenuItem... exclusions) {
+        for (int i = 0; i < menu.size(); i++) {
+            MenuItem item = menu.getItem(i);
+            if (item.isVisible()) {
+              continue;
+            }
+            if (contains(exclusions, item)) {
+                continue;
+            }
+            item.setEnabled(false);
+        }
+    }
+
+    private static boolean contains(MenuItem[] exclusions, MenuItem item) {
+        for (int x = 0; x < exclusions.length; x++) {
+            if (exclusions[x] == item) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/src/com/android/documentsui/Shared.java b/src/com/android/documentsui/Shared.java
index e06d6a5..a4d6dc5 100644
--- a/src/com/android/documentsui/Shared.java
+++ b/src/com/android/documentsui/Shared.java
@@ -16,12 +16,7 @@
 
 package com.android.documentsui;
 
-import static com.android.internal.util.Preconditions.checkNotNull;
-
-import android.app.Activity;
 import android.content.Context;
-import android.support.design.widget.Snackbar;
-import android.view.View;
 
 /** @hide */
 public final class Shared {
@@ -35,14 +30,4 @@
     public static final String getQuantityString(Context context, int resourceId, int quantity) {
         return context.getResources().getQuantityString(resourceId, quantity, quantity);
     }
-
-    public static final Snackbar makeSnackbar(Activity activity, int messageId, int duration) {
-        return makeSnackbar(activity, activity.getResources().getText(messageId), duration);
-    }
-
-    public static final Snackbar makeSnackbar(Activity activity, CharSequence message, int duration)
-    {
-        final View view = checkNotNull(activity.findViewById(R.id.coordinator_layout));
-        return Snackbar.make(view, message, duration);
-    }
 }
diff --git a/src/com/android/documentsui/Snackbars.java b/src/com/android/documentsui/Snackbars.java
new file mode 100644
index 0000000..f48b298
--- /dev/null
+++ b/src/com/android/documentsui/Snackbars.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+package com.android.documentsui;
+
+import static com.android.internal.util.Preconditions.checkNotNull;
+
+import android.app.Activity;
+import android.support.design.widget.Snackbar;
+import android.view.View;
+
+final class Snackbars {
+    private Snackbars() {}
+
+    public static final Snackbar makeSnackbar(Activity activity, int messageId, int duration) {
+        return Snackbars.makeSnackbar(activity, activity.getResources().getText(messageId), duration);
+    }
+
+    public static final Snackbar makeSnackbar(Activity activity, CharSequence message, int duration)
+    {
+        final View view = checkNotNull(activity.findViewById(R.id.coordinator_layout));
+        return Snackbar.make(view, message, duration);
+    }
+}