Make device storage option controlled by option.

Was always visible in productivity mode.
Simplify logic for fiddling display of menu item.
Introduce ScopedPreferences object to simplify saving prefs by activity.

Change-Id: I9f900583f6e6265e95b008a9877d68edacfa4e56
Bug: 32242016
diff --git a/src/com/android/documentsui/BaseActivity.java b/src/com/android/documentsui/BaseActivity.java
index 3928a01..a81b0ca 100644
--- a/src/com/android/documentsui/BaseActivity.java
+++ b/src/com/android/documentsui/BaseActivity.java
@@ -18,11 +18,6 @@
 
 import static com.android.documentsui.base.Shared.DEBUG;
 import static com.android.documentsui.base.Shared.EXTRA_BENCHMARK;
-import static com.android.documentsui.base.State.ACTION_CREATE;
-import static com.android.documentsui.base.State.ACTION_GET_CONTENT;
-import static com.android.documentsui.base.State.ACTION_OPEN;
-import static com.android.documentsui.base.State.ACTION_OPEN_TREE;
-import static com.android.documentsui.base.State.ACTION_PICK_COPY_DESTINATION;
 import static com.android.documentsui.base.State.MODE_GRID;
 
 import android.app.Activity;
@@ -58,6 +53,7 @@
 import com.android.documentsui.base.Events;
 import com.android.documentsui.base.LocalPreferences;
 import com.android.documentsui.base.RootInfo;
+import com.android.documentsui.base.ScopedPreferences;
 import com.android.documentsui.base.Shared;
 import com.android.documentsui.base.State;
 import com.android.documentsui.base.State.ViewMode;
@@ -106,11 +102,16 @@
     @LayoutRes
     private int mLayoutId;
 
-    private RootsMonitor<BaseActivity> mRootsMonitor;
+    private RootsMonitor<BaseActivity<?>> mRootsMonitor;
 
     private boolean mNavDrawerHasFocus;
     private long mStartTime;
 
+    public BaseActivity(@LayoutRes int layoutId, String tag) {
+        mLayoutId = layoutId;
+        mTag = tag;
+    }
+
     protected abstract void onTaskFinished(Uri... uris);
     protected abstract void refreshDirectory(int anim);
     /** Allows sub-classes to include information in a newly created State instance. */
@@ -127,6 +128,12 @@
      * Provides Activity a means of injection into and specialization of
      * DirectoryFragment.
      */
+    public abstract ScopedPreferences getScopedPreferences();
+
+    /**
+     * Provides Activity a means of injection into and specialization of
+     * DirectoryFragment.
+     */
     public abstract SelectionManager getSelectionManager(
             DocumentsAdapter adapter, SelectionPredicate canSetState);
 
@@ -167,11 +174,6 @@
         return mMessages;
     }
 
-    public BaseActivity(@LayoutRes int layoutId, String tag) {
-        mLayoutId = layoutId;
-        mTag = tag;
-    }
-
     @CallSuper
     @Override
     public void onCreate(Bundle icicle) {
@@ -296,19 +298,11 @@
 
         includeState(state);
 
-        // Advanced roots are shown by default without menu option if forced by config or intent.
-        boolean forceAdvanced = Shared.shouldShowDeviceRoot(this, intent);
-        boolean chosenAdvanced = LocalPreferences.getShowDeviceRoot(this, state.action);
-        state.showAdvanced = forceAdvanced || chosenAdvanced;
+        state.showAdvanced =
+                Shared.mustShowDeviceRoot(intent) || getScopedPreferences().getShowDeviceRoot();
 
-        // Menu option is shown for whitelisted intents if advanced roots are not shown by default.
-        state.showAdvancedOption = !forceAdvanced && (
-                Shared.shouldShowFancyFeatures(this)
-                || state.action == ACTION_OPEN
-                || state.action == ACTION_CREATE
-                || state.action == ACTION_OPEN_TREE
-                || state.action == ACTION_PICK_COPY_DESTINATION
-                || state.action == ACTION_GET_CONTENT);
+        // Only show the toggle if advanced isn't forced enabled.
+        state.showAdvancedOption = !Shared.mustShowDeviceRoot(intent);
 
         if (DEBUG) Log.d(mTag, "Created new state object: " + state);
 
@@ -477,8 +471,8 @@
         return (root.flags & Root.FLAG_SUPPORTS_SEARCH) != 0;
     }
 
-    public static BaseActivity get(Fragment fragment) {
-        return (BaseActivity) fragment.getActivity();
+    public static BaseActivity<?> get(Fragment fragment) {
+        return (BaseActivity<?>) fragment.getActivity();
     }
 
     public State getDisplayState() {
@@ -497,7 +491,7 @@
         Metrics.logUserAction(this,
                 display ? Metrics.USER_ACTION_SHOW_ADVANCED : Metrics.USER_ACTION_HIDE_ADVANCED);
 
-        LocalPreferences.setShowDeviceRoot(this, mState.action, display);
+        getScopedPreferences().setShowDeviceRoot(display);
         mState.showAdvanced = display;
         RootsFragment.get(getFragmentManager()).onDisplayStateChanged();
         invalidateOptionsMenu();
diff --git a/src/com/android/documentsui/MenuManager.java b/src/com/android/documentsui/MenuManager.java
index 05e7f17..f7685e1 100644
--- a/src/com/android/documentsui/MenuManager.java
+++ b/src/com/android/documentsui/MenuManager.java
@@ -296,9 +296,9 @@
     }
 
     public static class DirectoryDetails {
-        private final BaseActivity mActivity;
+        private final BaseActivity<?> mActivity;
 
-        public DirectoryDetails(BaseActivity activity) {
+        public DirectoryDetails(BaseActivity<?> activity) {
             mActivity = activity;
         }
 
diff --git a/src/com/android/documentsui/base/LocalPreferences.java b/src/com/android/documentsui/base/LocalPreferences.java
index e9d8350..0d1e639 100644
--- a/src/com/android/documentsui/base/LocalPreferences.java
+++ b/src/com/android/documentsui/base/LocalPreferences.java
@@ -26,14 +26,12 @@
 import android.os.UserHandle;
 import android.preference.PreferenceManager;
 
-import com.android.documentsui.base.State.ActionType;
 import com.android.documentsui.base.State.ViewMode;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
 public class LocalPreferences {
-    private static final String INCLUDE_DEVICE_ROOT = "includeDeviceRoot-";
     private static final String ROOT_VIEW_MODE_PREFIX = "rootViewMode-";
 
     public static @ViewMode int getViewMode(Context context, RootInfo root,
@@ -41,15 +39,6 @@
         return getPrefs(context).getInt(createKey(root), fallback);
     }
 
-    public static boolean getShowDeviceRoot(Context context, @ActionType int action) {
-        return getPrefs(context).getBoolean(INCLUDE_DEVICE_ROOT + action, false);
-    }
-
-    public static void setShowDeviceRoot(
-            Context context, @ActionType int action, boolean display) {
-        getPrefs(context).edit().putBoolean(INCLUDE_DEVICE_ROOT + action, display).apply();
-    }
-
     public static void setViewMode(Context context, RootInfo root, @ViewMode int viewMode) {
         assert(viewMode != MODE_UNKNOWN);
         getPrefs(context).edit().putInt(createKey(root), viewMode).apply();
diff --git a/src/com/android/documentsui/base/ScopedPreferences.java b/src/com/android/documentsui/base/ScopedPreferences.java
new file mode 100644
index 0000000..e933ad0
--- /dev/null
+++ b/src/com/android/documentsui/base/ScopedPreferences.java
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+package com.android.documentsui.base;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+
+public interface ScopedPreferences {
+
+    boolean getShowDeviceRoot();
+    void setShowDeviceRoot(boolean display);
+
+    public static ScopedPreferences create(Context context, String scope) {
+        return new RuntimeScopedPreferences(
+                PreferenceManager.getDefaultSharedPreferences(context), scope);
+    }
+
+    static final class RuntimeScopedPreferences implements ScopedPreferences {
+
+        private static final String INCLUDE_DEVICE_ROOT = "includeDeviceRoot-";
+
+        private SharedPreferences mSharedPrefs;
+        private String mScope;
+
+        private RuntimeScopedPreferences(SharedPreferences sharedPrefs, String scope)  {
+            mSharedPrefs = sharedPrefs;
+            mScope = scope;
+        }
+
+        @Override
+        public boolean getShowDeviceRoot() {
+            return mSharedPrefs.getBoolean(INCLUDE_DEVICE_ROOT + mScope, false);
+        }
+
+        @Override
+        public void setShowDeviceRoot(boolean display) {
+            mSharedPrefs.edit().putBoolean(INCLUDE_DEVICE_ROOT + mScope, display).apply();
+        }
+    }
+}
diff --git a/src/com/android/documentsui/base/Shared.java b/src/com/android/documentsui/base/Shared.java
index 63f2886..14bb081 100644
--- a/src/com/android/documentsui/base/Shared.java
+++ b/src/com/android/documentsui/base/Shared.java
@@ -251,9 +251,8 @@
     /*
      * Returns true if device root should be shown.
      */
-    public static boolean shouldShowDeviceRoot(Context context, Intent intent) {
-        return isProductivityMode(context, intent)
-                || intent.getBooleanExtra(DocumentsContract.EXTRA_SHOW_ADVANCED, false);
+    public static boolean mustShowDeviceRoot(Intent intent) {
+        return intent.getBooleanExtra(DocumentsContract.EXTRA_SHOW_ADVANCED, false);
     }
 
     /**
diff --git a/src/com/android/documentsui/files/FilesActivity.java b/src/com/android/documentsui/files/FilesActivity.java
index 877914b..0de44ea 100644
--- a/src/com/android/documentsui/files/FilesActivity.java
+++ b/src/com/android/documentsui/files/FilesActivity.java
@@ -48,6 +48,7 @@
 import com.android.documentsui.base.DocumentStack;
 import com.android.documentsui.base.EventHandler;
 import com.android.documentsui.base.RootInfo;
+import com.android.documentsui.base.ScopedPreferences;
 import com.android.documentsui.base.Shared;
 import com.android.documentsui.base.State;
 import com.android.documentsui.clipping.DocumentClipper;
@@ -71,9 +72,12 @@
 public class FilesActivity
         extends BaseActivity<ActionHandler<FilesActivity>> implements ActionHandler.Addons {
 
-    public static final String TAG = "FilesActivity";
+    private static final String TAG = "FilesActivity";
+    private static final String PREFERENCES_SCOPE = "files";
 
     private final Config mConfig = new Config();
+
+    private ScopedPreferences mPrefs;
     private SelectionManager mSelectionMgr;
     private MenuManager mMenuManager;
     private DialogController mDialogs;
@@ -88,6 +92,11 @@
 
     @Override
     public void onCreate(Bundle icicle) {
+
+        // must be initialized before calling super.onCreate because prefs
+        // are used in State initialization.
+        mPrefs = ScopedPreferences.create(this, PREFERENCES_SCOPE);
+
         super.onCreate(icicle);
 
         mClipper = DocumentsApplication.getDocumentClipper(this);
@@ -368,6 +377,11 @@
     }
 
     @Override
+    public ScopedPreferences getScopedPreferences() {
+        return mPrefs;
+    }
+
+    @Override
     public SelectionManager getSelectionManager(
             DocumentsAdapter adapter, SelectionPredicate canSetState) {
         return mSelectionMgr.reset(adapter, canSetState);
diff --git a/src/com/android/documentsui/files/MenuManager.java b/src/com/android/documentsui/files/MenuManager.java
index 61d57b5..d0fd570 100644
--- a/src/com/android/documentsui/files/MenuManager.java
+++ b/src/com/android/documentsui/files/MenuManager.java
@@ -25,7 +25,6 @@
 import android.view.MenuItem;
 import android.view.View;
 
-import com.android.documentsui.BaseActivity;
 import com.android.documentsui.R;
 import com.android.documentsui.SearchViewManager;
 import com.android.documentsui.base.DocumentInfo;
diff --git a/src/com/android/documentsui/picker/PickActivity.java b/src/com/android/documentsui/picker/PickActivity.java
index 645b7f7..3e71402 100644
--- a/src/com/android/documentsui/picker/PickActivity.java
+++ b/src/com/android/documentsui/picker/PickActivity.java
@@ -56,6 +56,7 @@
 import com.android.documentsui.base.MimeTypes;
 import com.android.documentsui.base.PairedTask;
 import com.android.documentsui.base.RootInfo;
+import com.android.documentsui.base.ScopedPreferences;
 import com.android.documentsui.base.Shared;
 import com.android.documentsui.base.State;
 import com.android.documentsui.dirlist.DirectoryFragment;
@@ -75,10 +76,13 @@
 public class PickActivity
         extends BaseActivity<ActionHandler<PickActivity>> implements ActionHandler.Addons {
 
-    private static final int CODE_FORWARD = 42;
     private static final String TAG = "PickActivity";
+    private static final String PREFERENCES_SCOPE = "picker";
+    private static final int CODE_FORWARD = 42;
+
     private final Config mConfig = new Config();
 
+    private ScopedPreferences mPrefs;
     private SelectionManager mSelectionMgr;
     private MenuManager mMenuManager;
     private ActionModeController mActionModeController;
@@ -89,6 +93,11 @@
 
     @Override
     public void onCreate(Bundle icicle) {
+
+        // must be initialized before calling super.onCreate because prefs
+        // are used in State initialization.
+        mPrefs = ScopedPreferences.create(this, PREFERENCES_SCOPE);
+
         super.onCreate(icicle);
 
         mSelectionMgr = new SelectionManager(
@@ -416,6 +425,11 @@
         return mConfig;
     }
 
+    @Override
+    public ScopedPreferences getScopedPreferences() {
+        return mPrefs;
+    }
+
     public SelectionManager getSelectionManager(
             DocumentsAdapter adapter, SelectionPredicate canSetState) {
         return mSelectionMgr.reset(adapter, canSetState);