Additional tidy up after Features.

1) Correctly hook Archive Creation up to features.
2) Remove archive creation as a preference.
3) Replace a few remaining direct references to R.bool.feature_...
4) Normalize test method naming in files.MenuManagerTest.

Bug: 35936932
Test: Build and run tests, test app manually.
Change-Id: I46db960fa17c438bb02fb3767b97dac3459c7cec
diff --git a/src/com/android/documentsui/AbstractActionHandler.java b/src/com/android/documentsui/AbstractActionHandler.java
index 617e5ae..e1af79b 100644
--- a/src/com/android/documentsui/AbstractActionHandler.java
+++ b/src/com/android/documentsui/AbstractActionHandler.java
@@ -440,6 +440,7 @@
         return mSelectionMgr.getSelection(new Selection());
     }
 
+    @Override
     public ActionHandler reset(DirectoryReloadLock reloadLock) {
         mDirectoryReloadLock = reloadLock;
         mActivity.getLoaderManager().destroyLoader(LOADER_ID);
@@ -477,6 +478,7 @@
                                 + DocumentInfo.debugString(mState.stack.peek()));
 
                 return new DirectoryLoader(
+                        mInjector.features,
                         context,
                         mState.stack.getRoot(),
                         mState.stack.peek(),
diff --git a/src/com/android/documentsui/DirectoryLoader.java b/src/com/android/documentsui/DirectoryLoader.java
index 4fbb3ff..7b50cc6 100644
--- a/src/com/android/documentsui/DirectoryLoader.java
+++ b/src/com/android/documentsui/DirectoryLoader.java
@@ -38,6 +38,7 @@
 import com.android.documentsui.archives.ArchivesProvider;
 import com.android.documentsui.base.DebugFlags;
 import com.android.documentsui.base.DocumentInfo;
+import com.android.documentsui.base.Features;
 import com.android.documentsui.base.FilteringCursorWrapper;
 import com.android.documentsui.base.RootInfo;
 import com.android.documentsui.roots.RootCursorWrapper;
@@ -61,7 +62,10 @@
     private CancellationSignal mSignal;
     private DirectoryResult mResult;
 
+    private Features mFeatures;
+
     public DirectoryLoader(
+            Features freatures,
             Context context,
             RootInfo root,
             DocumentInfo doc,
@@ -71,6 +75,7 @@
             boolean inSearchMode) {
 
         super(context, ProviderExecutor.forAuthority(root.authority));
+        mFeatures = freatures;
         mRoot = root;
         mUri = uri;
         mModel = model;
@@ -104,7 +109,7 @@
             result.client = client;
 
             Resources resources = getContext().getResources();
-            if (resources.getBoolean(R.bool.feature_content_paging)) {
+            if (mFeatures.isContentPagingEnabled()) {
                 Bundle queryArgs = new Bundle();
                 mModel.addQuerySortArgs(queryArgs);
 
@@ -126,14 +131,14 @@
 
             cursor = new RootCursorWrapper(mUri.getAuthority(), mRoot.rootId, cursor, -1);
 
-            if (mSearchMode && !resources.getBoolean(R.bool.feature_folders_in_search_results)) {
+            if (mSearchMode && !mFeatures.isFoldersInSearchResultsEnabled()) {
                 // There is no findDocumentPath API. Enable filtering on folders in search mode.
                 cursor = new FilteringCursorWrapper(cursor, null, SEARCH_REJECT_MIMES);
             }
 
             // TODO: When API tweaks have landed, use ContentResolver.EXTRA_HONORED_ARGS
             // instead of checking directly for ContentResolver.QUERY_ARG_SORT_COLUMNS (won't work)
-            if (resources.getBoolean(R.bool.feature_content_paging)
+            if (mFeatures.isContentPagingEnabled()
                         && cursor.getExtras().containsKey(ContentResolver.QUERY_ARG_SORT_COLUMNS)) {
                 if (VERBOSE) Log.d(TAG, "Skipping sort of pre-sorted cursor. Booya!");
             } else {
diff --git a/src/com/android/documentsui/files/FilesActivity.java b/src/com/android/documentsui/files/FilesActivity.java
index 3b02239..103c272 100644
--- a/src/com/android/documentsui/files/FilesActivity.java
+++ b/src/com/android/documentsui/files/FilesActivity.java
@@ -98,7 +98,7 @@
                 getColor(R.color.accent_dark));
 
         mInjector.menuManager = new MenuManager(
-                mInjector.prefs,
+                mInjector.features,
                 mSearchManager,
                 mState,
                 new DirectoryDetails(this) {
@@ -286,6 +286,7 @@
      * @deprecated use {@link ActionHandler#onDocumentPicked(DocumentInfo)}
      * @param doc
      */
+    @Deprecated
     @Override
     public void onDocumentPicked(DocumentInfo doc) {
         mInjector.actions.onDocumentPicked(doc);
diff --git a/src/com/android/documentsui/files/MenuManager.java b/src/com/android/documentsui/files/MenuManager.java
index 1d65326..0257634 100644
--- a/src/com/android/documentsui/files/MenuManager.java
+++ b/src/com/android/documentsui/files/MenuManager.java
@@ -27,25 +27,25 @@
 
 import com.android.documentsui.R;
 import com.android.documentsui.base.DocumentInfo;
+import com.android.documentsui.base.Features;
 import com.android.documentsui.base.RootInfo;
-import com.android.documentsui.base.Shared;
 import com.android.documentsui.base.State;
-import com.android.documentsui.prefs.ScopedPreferences;
 import com.android.documentsui.queries.SearchViewManager;
 
 import java.util.List;
 import java.util.function.IntFunction;
 
 public final class MenuManager extends com.android.documentsui.MenuManager {
-    private final ScopedPreferences mPreferences;
+
+    private final Features mFeatures;
 
     public MenuManager(
-            ScopedPreferences preferences,
+            Features features,
             SearchViewManager searchManager,
             State displayState,
             DirectoryDetails dirDetails) {
         super(searchManager, displayState, dirDetails);
-        mPreferences = preferences;
+        mFeatures = features;
     }
 
     @Override
@@ -185,7 +185,7 @@
     @Override
     protected void updateCompress(MenuItem compress, SelectionDetails selectionDetails) {
         final boolean readOnly = !mDirDetails.canCreateDoc();
-        compress.setVisible(mPreferences.getEnableArchiveCreation());
+        compress.setVisible(mFeatures.isArchiveCreationEnabled());
         compress.setEnabled(!readOnly && !selectionDetails.containsPartialFiles() &&
                 !selectionDetails.canExtract());
     }
diff --git a/src/com/android/documentsui/prefs/ScopedPreferences.java b/src/com/android/documentsui/prefs/ScopedPreferences.java
index 4b2c36d..04c3f50 100644
--- a/src/com/android/documentsui/prefs/ScopedPreferences.java
+++ b/src/com/android/documentsui/prefs/ScopedPreferences.java
@@ -17,12 +17,9 @@
 
 import android.content.Context;
 import android.content.SharedPreferences;
-import android.content.res.Resources;
 import android.preference.PreferenceManager;
 import android.text.TextUtils;
 
-import com.android.documentsui.R;
-
 /**
  * Provides an interface (and runtime implementation) for preferences that are
  * scoped (presumably to an activity). This eliminates the need to pass
@@ -37,29 +34,23 @@
     boolean getShowDeviceRoot();
     void setShowDeviceRoot(boolean display);
 
-    boolean getEnableArchiveCreation();
-    void setEnableArchiveCreation(boolean enabled);
-
     /**
      * @param scope An arbitrary string representitive of the scope
      *        for prefs that are set using this object.
      */
     public static ScopedPreferences create(Context context, String scope) {
-        return new RuntimeScopedPreferences(context.getResources(),
+        return new RuntimeScopedPreferences(
                 PreferenceManager.getDefaultSharedPreferences(context), scope);
     }
 
     static final class RuntimeScopedPreferences implements ScopedPreferences {
 
-        private Resources mResources;
         private SharedPreferences mSharedPrefs;
         private String mScope;
 
-        private RuntimeScopedPreferences(Resources resources, SharedPreferences sharedPrefs,
-                String scope)  {
+        private RuntimeScopedPreferences(SharedPreferences sharedPrefs, String scope)  {
             assert(!TextUtils.isEmpty(scope));
 
-            mResources = resources;
             mSharedPrefs = sharedPrefs;
             mScope = scope;
         }
@@ -73,17 +64,6 @@
         public void setShowDeviceRoot(boolean display) {
             mSharedPrefs.edit().putBoolean(INCLUDE_DEVICE_ROOT, display).apply();
         }
-
-        @Override
-        public boolean getEnableArchiveCreation() {
-            final boolean defaultValue = mResources.getBoolean(R.bool.feature_archive_creation);
-            return mSharedPrefs.getBoolean(ENABLE_ARCHIVE_CREATION + mScope, defaultValue);
-        }
-
-        @Override
-        public void setEnableArchiveCreation(boolean enabled) {
-            mSharedPrefs.edit().putBoolean(ENABLE_ARCHIVE_CREATION + mScope, enabled).apply();
-        }
     }
 
     static boolean shouldBackup(String s) {
diff --git a/src/com/android/documentsui/sorting/SortModel.java b/src/com/android/documentsui/sorting/SortModel.java
index a61543f..f03d5be 100644
--- a/src/com/android/documentsui/sorting/SortModel.java
+++ b/src/com/android/documentsui/sorting/SortModel.java
@@ -17,6 +17,7 @@
 package com.android.documentsui.sorting;
 
 import static com.android.documentsui.base.Shared.DEBUG;
+import static com.android.documentsui.base.Shared.VERBOSE;
 
 import android.annotation.IntDef;
 import android.annotation.Nullable;
@@ -275,12 +276,13 @@
     }
 
     public @Nullable String getDocumentSortQuery() {
-        // This method should only be called when R.bool.feature_content_paging is false.
-        // Once that feature is enabled by default, this method should be removed.
-        // The following assert exists simply to make reference to the resource id
-        // so the compiler will fail when the feature is removed...reminding you and me
-        // to remove this method :)
-        assert(R.bool.feature_content_paging != Integer.MIN_VALUE);
+        // This method should only be called when R.bool.feature_content_paging exists.
+        // Once that feature is enabled by default (and reference removed), this method
+        // should also be removed.
+        // The following log message exists simply to make reference to
+        // R.bool.feature_content_paging so that compiler will fail when value
+        // is remove from config.xml.
+        if (VERBOSE) Log.v(TAG, "Can you remove me now? " + R.bool.feature_content_paging);
 
         final int id = getSortedDimensionId();
         final String columnName;