Merge "Address comments in ag/1514806." into nyc-andromeda-dev
diff --git a/src/com/android/documentsui/AbstractActionHandler.java b/src/com/android/documentsui/AbstractActionHandler.java
index 814899b..1a26bcc 100644
--- a/src/com/android/documentsui/AbstractActionHandler.java
+++ b/src/com/android/documentsui/AbstractActionHandler.java
@@ -39,6 +39,7 @@
import com.android.documentsui.dirlist.AnimationView;
import com.android.documentsui.dirlist.DocumentDetails;
import com.android.documentsui.files.LauncherActivity;
+import com.android.documentsui.queries.SearchViewManager;
import com.android.documentsui.roots.LoadRootTask;
import com.android.documentsui.roots.RootsAccess;
import com.android.documentsui.selection.Selection;
diff --git a/src/com/android/documentsui/BaseActivity.java b/src/com/android/documentsui/BaseActivity.java
index 1ea3b0f..d0bc30c 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;
@@ -52,12 +47,12 @@
import com.android.documentsui.AbstractActionHandler.CommonAddons;
import com.android.documentsui.MenuManager.SelectionDetails;
import com.android.documentsui.NavigationViewManager.Breadcrumb;
-import com.android.documentsui.SearchViewManager.SearchManagerListener;
import com.android.documentsui.base.DocumentInfo;
import com.android.documentsui.base.EventHandler;
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;
@@ -65,6 +60,8 @@
import com.android.documentsui.dirlist.DirectoryFragment;
import com.android.documentsui.dirlist.DocumentsAdapter;
import com.android.documentsui.dirlist.Model;
+import com.android.documentsui.queries.SearchViewManager;
+import com.android.documentsui.queries.SearchViewManager.SearchManagerListener;
import com.android.documentsui.roots.GetRootDocumentTask;
import com.android.documentsui.roots.RootsCache;
import com.android.documentsui.selection.Selection;
@@ -106,11 +103,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 +129,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 +175,6 @@
return mMessages;
}
- public BaseActivity(@LayoutRes int layoutId, String tag) {
- mLayoutId = layoutId;
- mTag = tag;
- }
-
@CallSuper
@Override
public void onCreate(Bundle icicle) {
@@ -296,19 +299,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 +472,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 +492,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..e261c9f 100644
--- a/src/com/android/documentsui/MenuManager.java
+++ b/src/com/android/documentsui/MenuManager.java
@@ -28,6 +28,7 @@
import com.android.documentsui.base.Shared;
import com.android.documentsui.base.State;
import com.android.documentsui.dirlist.DirectoryFragment;
+import com.android.documentsui.queries.SearchViewManager;
import com.android.documentsui.sidebar.RootsFragment;
import com.android.internal.annotations.VisibleForTesting;
@@ -296,9 +297,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/RootsMonitor.java b/src/com/android/documentsui/RootsMonitor.java
index d13f3b5..a0d4d0b 100644
--- a/src/com/android/documentsui/RootsMonitor.java
+++ b/src/com/android/documentsui/RootsMonitor.java
@@ -29,6 +29,7 @@
import com.android.documentsui.base.RootInfo;
import com.android.documentsui.base.State;
import com.android.documentsui.dirlist.AnimationView;
+import com.android.documentsui.queries.SearchViewManager;
import com.android.documentsui.roots.RootsAccess;
import java.util.Collection;
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/ActionHandler.java b/src/com/android/documentsui/files/ActionHandler.java
index 838a431..afea4cd 100644
--- a/src/com/android/documentsui/files/ActionHandler.java
+++ b/src/com/android/documentsui/files/ActionHandler.java
@@ -33,7 +33,6 @@
import com.android.documentsui.DocumentsApplication;
import com.android.documentsui.Metrics;
import com.android.documentsui.R;
-import com.android.documentsui.SearchViewManager;
import com.android.documentsui.base.ConfirmationCallback;
import com.android.documentsui.base.ConfirmationCallback.Result;
import com.android.documentsui.base.DocumentInfo;
@@ -42,6 +41,7 @@
import com.android.documentsui.base.Lookup;
import com.android.documentsui.base.MimeTypes;
import com.android.documentsui.base.RootInfo;
+import com.android.documentsui.base.Shared;
import com.android.documentsui.base.State;
import com.android.documentsui.clipping.ClipStore;
import com.android.documentsui.clipping.DocumentClipper;
@@ -51,6 +51,7 @@
import com.android.documentsui.dirlist.Model;
import com.android.documentsui.dirlist.Model.Update;
import com.android.documentsui.files.ActionHandler.Addons;
+import com.android.documentsui.queries.SearchViewManager;
import com.android.documentsui.roots.GetRootDocumentTask;
import com.android.documentsui.roots.RootsAccess;
import com.android.documentsui.selection.Selection;
@@ -355,7 +356,9 @@
}
Intent intent = Intent.createChooser(buildViewIntent(doc), null);
- intent.putExtra(Intent.EXTRA_AUTO_LAUNCH_SINGLE_CHOICE, false);
+ if (Shared.ENABLE_OMC_API_FEATURES) {
+ intent.putExtra(Intent.EXTRA_AUTO_LAUNCH_SINGLE_CHOICE, false);
+ }
try {
mActivity.startActivity(intent);
} catch (ActivityNotFoundException e) {
diff --git a/src/com/android/documentsui/files/FilesActivity.java b/src/com/android/documentsui/files/FilesActivity.java
index 823c9ea..42afa7f 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);
@@ -367,6 +376,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..839c245 100644
--- a/src/com/android/documentsui/files/MenuManager.java
+++ b/src/com/android/documentsui/files/MenuManager.java
@@ -25,12 +25,11 @@
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;
import com.android.documentsui.base.RootInfo;
import com.android.documentsui.base.State;
+import com.android.documentsui.queries.SearchViewManager;
import java.util.List;
import java.util.function.IntFunction;
diff --git a/src/com/android/documentsui/files/QuickViewIntentBuilder.java b/src/com/android/documentsui/files/QuickViewIntentBuilder.java
index b8d9fcb..3304cc1 100644
--- a/src/com/android/documentsui/files/QuickViewIntentBuilder.java
+++ b/src/com/android/documentsui/files/QuickViewIntentBuilder.java
@@ -38,6 +38,7 @@
import com.android.documentsui.R;
import com.android.documentsui.base.DocumentInfo;
import com.android.documentsui.dirlist.Model;
+import com.android.documentsui.queries.SetQuickViewerCommand;
import com.android.documentsui.roots.RootCursorWrapper;
import java.util.ArrayList;
@@ -54,7 +55,6 @@
// For that reason when trusted quick view package is set to this magic value
// we won't honor the system property.
public static final String IGNORE_DEBUG_PROP = "*disabled*";
-
private static final String TAG = "QuickViewIntentBuilder";
private final DocumentInfo mDocument;
@@ -142,6 +142,9 @@
// Allow users of debug devices to override default quick viewer
// for the purposes of testing.
if (Build.IS_DEBUGGABLE) {
+ if (SetQuickViewerCommand.sQuickViewer != null) {
+ return SetQuickViewerCommand.sQuickViewer;
+ }
return android.os.SystemProperties.get("debug.quick_viewer", resValue);
}
return resValue;
diff --git a/src/com/android/documentsui/picker/ActionHandler.java b/src/com/android/documentsui/picker/ActionHandler.java
index e6b1144..6e1b9d4 100644
--- a/src/com/android/documentsui/picker/ActionHandler.java
+++ b/src/com/android/documentsui/picker/ActionHandler.java
@@ -31,7 +31,6 @@
import com.android.documentsui.ActivityConfig;
import com.android.documentsui.DocumentsAccess;
import com.android.documentsui.Metrics;
-import com.android.documentsui.SearchViewManager;
import com.android.documentsui.base.DocumentInfo;
import com.android.documentsui.base.DocumentStack;
import com.android.documentsui.base.EventListener;
@@ -44,6 +43,7 @@
import com.android.documentsui.dirlist.Model;
import com.android.documentsui.dirlist.Model.Update;
import com.android.documentsui.picker.ActionHandler.Addons;
+import com.android.documentsui.queries.SearchViewManager;
import com.android.documentsui.roots.RootsAccess;
import com.android.documentsui.selection.SelectionManager;
diff --git a/src/com/android/documentsui/picker/MenuManager.java b/src/com/android/documentsui/picker/MenuManager.java
index a61081b..8bdd150 100644
--- a/src/com/android/documentsui/picker/MenuManager.java
+++ b/src/com/android/documentsui/picker/MenuManager.java
@@ -25,8 +25,8 @@
import android.view.Menu;
import android.view.MenuItem;
-import com.android.documentsui.SearchViewManager;
import com.android.documentsui.base.State;
+import com.android.documentsui.queries.SearchViewManager;
public final class MenuManager extends com.android.documentsui.MenuManager {
diff --git a/src/com/android/documentsui/picker/PickActivity.java b/src/com/android/documentsui/picker/PickActivity.java
index 17e6bb1..268d801 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(
@@ -415,6 +424,11 @@
return mConfig;
}
+ @Override
+ public ScopedPreferences getScopedPreferences() {
+ return mPrefs;
+ }
+
public SelectionManager getSelectionManager(
DocumentsAdapter adapter, SelectionPredicate canSetState) {
return mSelectionMgr.reset(adapter, canSetState);
diff --git a/src/com/android/documentsui/queries/DebugCommandProcessor.java b/src/com/android/documentsui/queries/DebugCommandProcessor.java
new file mode 100644
index 0000000..70d9d64
--- /dev/null
+++ b/src/com/android/documentsui/queries/DebugCommandProcessor.java
@@ -0,0 +1,57 @@
+/*
+ * 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.queries;
+
+import android.os.Build;
+import android.support.annotation.VisibleForTesting;
+import android.util.Log;
+
+import com.android.documentsui.base.EventHandler;
+
+import java.util.ArrayList;
+import java.util.List;
+
+final class DebugCommandProcessor implements EventHandler<String> {
+
+ private final List<EventHandler<String[]>> mCommands = new ArrayList<>();
+
+ public DebugCommandProcessor() {
+ if (Build.IS_DEBUGGABLE) {
+ mCommands.add(new SetQuickViewerCommand());
+ }
+ }
+
+ @VisibleForTesting
+ DebugCommandProcessor(EventHandler<String[]>... commands) {
+ for (EventHandler<String[]> c : commands) {
+ mCommands.add(c);
+ }
+ }
+
+ @Override
+ public boolean accept(String query) {
+ if (query.length() > 6 && query.substring(0, 6).equals("#debug")) {
+ String[] tokens = query.substring(7).split("\\s+");
+ for (EventHandler<String[]> command : mCommands) {
+ if (command.accept(tokens)) {
+ return true;
+ }
+ }
+ Log.d(SearchViewManager.TAG, "Unrecognized debug command: " + query);
+ }
+ return false;
+ }
+}
diff --git a/src/com/android/documentsui/SearchViewManager.java b/src/com/android/documentsui/queries/SearchViewManager.java
similarity index 90%
rename from src/com/android/documentsui/SearchViewManager.java
rename to src/com/android/documentsui/queries/SearchViewManager.java
index 51db34f..6ade64d 100644
--- a/src/com/android/documentsui/SearchViewManager.java
+++ b/src/com/android/documentsui/queries/SearchViewManager.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.documentsui;
+package com.android.documentsui.queries;
import static com.android.documentsui.base.Shared.DEBUG;
@@ -32,6 +32,8 @@
import android.widget.SearchView;
import android.widget.SearchView.OnQueryTextListener;
+import com.android.documentsui.DocumentsToolbar;
+import com.android.documentsui.R;
import com.android.documentsui.base.RootInfo;
import com.android.documentsui.base.Shared;
@@ -42,14 +44,9 @@
SearchView.OnCloseListener, OnQueryTextListener, OnClickListener, OnFocusChangeListener,
OnActionExpandListener {
- public interface SearchManagerListener {
- void onSearchChanged(@Nullable String query);
- void onSearchFinished();
- void onSearchViewChanged(boolean opened);
- }
-
- private static final String TAG = "SearchManager";
+ static final String TAG = "SearchManager";
private final SearchManagerListener mListener;
+ private final DebugCommandProcessor mCommandProcessor;
private boolean mSearchExpanded;
private String mCurrentSearch;
@@ -66,6 +63,12 @@
assert (listener != null);
mListener = listener;
mCurrentSearch = savedState != null ? savedState.getString(Shared.EXTRA_QUERY) : null;
+
+ // "Commands" are meta input for controlling system behavior.
+ // We piggy back on search input as it is the only text input
+ // area in the app. But the functionality is independent
+ // of "regular" search query processing.
+ mCommandProcessor = new DebugCommandProcessor();
}
public void install(DocumentsToolbar actionBar, boolean isFullBarSearch) {
@@ -102,7 +105,7 @@
/**
* @param root Info about the current directory.
*/
- void update(RootInfo root) {
+ public void update(RootInfo root) {
if (mMenuItem == null) {
if (DEBUG) Log.d(TAG, "update called before Search MenuItem installed.");
return;
@@ -148,7 +151,7 @@
*
* @return True if it cancels search. False if it does not operate search currently.
*/
- boolean cancelSearch() {
+ public boolean cancelSearch() {
if (isExpanded() || isSearching()) {
// If the query string is not empty search view won't get iconified
mSearchView.setQuery("", false);
@@ -239,9 +242,15 @@
@Override
public boolean onQueryTextSubmit(String query) {
- mCurrentSearch = query;
- mSearchView.clearFocus();
- mListener.onSearchChanged(mCurrentSearch);
+
+ if (mCommandProcessor.accept(query)) {
+ cancelSearch();
+ } else {
+ mCurrentSearch = query;
+ mSearchView.clearFocus();
+ mListener.onSearchChanged(mCurrentSearch);
+ }
+
return true;
}
@@ -290,7 +299,13 @@
return mCurrentSearch != null;
}
- boolean isExpanded() {
+ public boolean isExpanded() {
return mSearchExpanded;
}
+
+ public interface SearchManagerListener {
+ void onSearchChanged(@Nullable String query);
+ void onSearchFinished();
+ void onSearchViewChanged(boolean opened);
+ }
}
diff --git a/src/com/android/documentsui/queries/SetQuickViewerCommand.java b/src/com/android/documentsui/queries/SetQuickViewerCommand.java
new file mode 100644
index 0000000..37fe0db
--- /dev/null
+++ b/src/com/android/documentsui/queries/SetQuickViewerCommand.java
@@ -0,0 +1,48 @@
+/*
+ * 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.queries;
+
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.documentsui.base.EventHandler;
+
+public class SetQuickViewerCommand implements EventHandler<String[]> {
+
+ // This is a quick/easy shortcut to sharing quick viewer debug settings
+ // with QuickViewIntent builder. Tried setting at a system property
+ // but got a native error. This being quick and easy, didn't investigate that err.
+ public static String sQuickViewer;
+ private static final String TAG = "SetQuickViewerCommand";
+
+ @Override
+ public boolean accept(String[] tokens) {
+ if ("setqv".equals(tokens[0])) {
+ if (tokens.length == 2 && !TextUtils.isEmpty(tokens[1])) {
+ sQuickViewer = tokens[1];
+ Log.i(TAG, "Set quick viewer to: " + sQuickViewer);
+ return true;
+ } else {
+ Log.w(TAG, "Invalid command structure: " + tokens);
+ }
+ } else if ("unsetqv".equals(tokens[0])) {
+ Log.i(TAG, "Unset quick viewer");
+ sQuickViewer = null;
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/tests/common/com/android/documentsui/testing/TestSearchViewManager.java b/tests/common/com/android/documentsui/testing/TestSearchViewManager.java
index 3be8f6a..560c783 100644
--- a/tests/common/com/android/documentsui/testing/TestSearchViewManager.java
+++ b/tests/common/com/android/documentsui/testing/TestSearchViewManager.java
@@ -16,10 +16,10 @@
package com.android.documentsui.testing;
-import com.android.documentsui.SearchViewManager;
+import com.android.documentsui.queries.SearchViewManager;
/**
- * Test copy of {@link com.android.documentsui.SearchViewManager}
+ * Test copy of {@link com.android.documentsui.queries.SearchViewManager}
*
* Specficially used to test whether {@link #showMenu(boolean)}
* and {@link #updateMenu()} are called.
diff --git a/tests/functional/com/android/documentsui/BandSelectionUiTest.java b/tests/functional/com/android/documentsui/BandSelectionUiTest.java
index 61bb442..c1b44b4 100644
--- a/tests/functional/com/android/documentsui/BandSelectionUiTest.java
+++ b/tests/functional/com/android/documentsui/BandSelectionUiTest.java
@@ -18,7 +18,7 @@
import android.graphics.Point;
import android.graphics.Rect;
-import android.test.suitebuilder.annotation.LargeTest;
+import android.support.test.filters.LargeTest;
import com.android.documentsui.files.FilesActivity;
diff --git a/tests/functional/com/android/documentsui/FileManagementUiTest.java b/tests/functional/com/android/documentsui/FileManagementUiTest.java
index dd186cb..bd62550 100644
--- a/tests/functional/com/android/documentsui/FileManagementUiTest.java
+++ b/tests/functional/com/android/documentsui/FileManagementUiTest.java
@@ -21,11 +21,10 @@
import android.net.Uri;
import android.os.RemoteException;
+import android.support.test.filters.LargeTest;
import android.support.test.filters.Suppress;
-import android.test.suitebuilder.annotation.LargeTest;
import android.view.KeyEvent;
-import com.android.documentsui.R;
import com.android.documentsui.files.FilesActivity;
@LargeTest
diff --git a/tests/functional/com/android/documentsui/FilesActivityDefaultsUiTest.java b/tests/functional/com/android/documentsui/FilesActivityDefaultsUiTest.java
index 8fc6d27..ff86a7f 100644
--- a/tests/functional/com/android/documentsui/FilesActivityDefaultsUiTest.java
+++ b/tests/functional/com/android/documentsui/FilesActivityDefaultsUiTest.java
@@ -21,7 +21,7 @@
import android.content.Intent;
import android.provider.DocumentsContract;
-import android.test.suitebuilder.annotation.LargeTest;
+import android.support.test.filters.LargeTest;
import com.android.documentsui.base.RootInfo;
import com.android.documentsui.base.Shared;
diff --git a/tests/functional/com/android/documentsui/FilesActivityUiTest.java b/tests/functional/com/android/documentsui/FilesActivityUiTest.java
index 4f0ce13..a798f16 100644
--- a/tests/functional/com/android/documentsui/FilesActivityUiTest.java
+++ b/tests/functional/com/android/documentsui/FilesActivityUiTest.java
@@ -18,7 +18,7 @@
import android.net.Uri;
import android.os.RemoteException;
-import android.test.suitebuilder.annotation.LargeTest;
+import android.support.test.filters.LargeTest;
import com.android.documentsui.files.FilesActivity;
diff --git a/tests/functional/com/android/documentsui/GestureSelectionUiTest.java b/tests/functional/com/android/documentsui/GestureSelectionUiTest.java
index 16c92f3..a8a1aec 100644
--- a/tests/functional/com/android/documentsui/GestureSelectionUiTest.java
+++ b/tests/functional/com/android/documentsui/GestureSelectionUiTest.java
@@ -16,7 +16,7 @@
package com.android.documentsui;
-import android.test.suitebuilder.annotation.LargeTest;
+import android.support.test.filters.LargeTest;
import com.android.documentsui.files.FilesActivity;
diff --git a/tests/functional/com/android/documentsui/IntegratedDownloadsUiTest.java b/tests/functional/com/android/documentsui/IntegratedDownloadsUiTest.java
index da340c2..62e5fb6 100644
--- a/tests/functional/com/android/documentsui/IntegratedDownloadsUiTest.java
+++ b/tests/functional/com/android/documentsui/IntegratedDownloadsUiTest.java
@@ -20,10 +20,10 @@
import android.app.DownloadManager.Request;
import android.content.Context;
import android.net.Uri;
+import android.support.test.filters.LargeTest;
+import android.support.test.filters.Suppress;
import android.support.test.uiautomator.Configurator;
import android.support.test.uiautomator.UiObject;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.Suppress;
import android.view.MotionEvent;
import com.android.documentsui.files.FilesActivity;
diff --git a/tests/functional/com/android/documentsui/KeyboardNavigationUiTest.java b/tests/functional/com/android/documentsui/KeyboardNavigationUiTest.java
index f70918d..d9e2065 100644
--- a/tests/functional/com/android/documentsui/KeyboardNavigationUiTest.java
+++ b/tests/functional/com/android/documentsui/KeyboardNavigationUiTest.java
@@ -16,10 +16,9 @@
package com.android.documentsui;
-import android.net.Uri;
import android.os.RemoteException;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.Suppress;
+import android.support.test.filters.LargeTest;
+import android.support.test.filters.Suppress;
import android.view.KeyEvent;
import com.android.documentsui.files.FilesActivity;
diff --git a/tests/functional/com/android/documentsui/RenameDocumentUiTest.java b/tests/functional/com/android/documentsui/RenameDocumentUiTest.java
index 0330ac3..9848bd5 100644
--- a/tests/functional/com/android/documentsui/RenameDocumentUiTest.java
+++ b/tests/functional/com/android/documentsui/RenameDocumentUiTest.java
@@ -16,10 +16,9 @@
package com.android.documentsui;
+import android.support.test.filters.LargeTest;
import android.support.test.uiautomator.UiObjectNotFoundException;
-import android.test.suitebuilder.annotation.LargeTest;
-import com.android.documentsui.R;
import com.android.documentsui.files.FilesActivity;
@LargeTest
diff --git a/tests/functional/com/android/documentsui/SearchViewUiTest.java b/tests/functional/com/android/documentsui/SearchViewUiTest.java
index 1b248a9..8e54512 100644
--- a/tests/functional/com/android/documentsui/SearchViewUiTest.java
+++ b/tests/functional/com/android/documentsui/SearchViewUiTest.java
@@ -19,9 +19,9 @@
import static com.android.documentsui.StubProvider.ROOT_0_ID;
import static com.android.documentsui.StubProvider.ROOT_1_ID;
+import android.support.test.filters.LargeTest;
import android.support.test.filters.Suppress;
import android.support.v7.recyclerview.R;
-import android.test.suitebuilder.annotation.LargeTest;
import com.android.documentsui.files.FilesActivity;
diff --git a/tests/functional/com/android/documentsui/SidebarUiTest.java b/tests/functional/com/android/documentsui/SidebarUiTest.java
index 79dacea..c21c853 100644
--- a/tests/functional/com/android/documentsui/SidebarUiTest.java
+++ b/tests/functional/com/android/documentsui/SidebarUiTest.java
@@ -19,8 +19,8 @@
import static com.android.documentsui.StubProvider.ROOT_0_ID;
import static com.android.documentsui.StubProvider.ROOT_1_ID;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.Suppress;
+import android.support.test.filters.LargeTest;
+import android.support.test.filters.Suppress;
import com.android.documentsui.files.FilesActivity;
diff --git a/tests/unit/com/android/documentsui/queries/DebugCommandProcessorTest.java b/tests/unit/com/android/documentsui/queries/DebugCommandProcessorTest.java
new file mode 100644
index 0000000..0f6e996
--- /dev/null
+++ b/tests/unit/com/android/documentsui/queries/DebugCommandProcessorTest.java
@@ -0,0 +1,71 @@
+/*
+ * 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.queries;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.documentsui.testing.TestEventHandler;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public final class DebugCommandProcessorTest {
+
+ private TestEventHandler<String[]> mCommand0;
+ private TestEventHandler<String[]> mCommand1;
+ private DebugCommandProcessor mProcessor;
+
+ @Before
+ public void setUp() {
+ mCommand0 = new TestEventHandler<>();
+ mCommand1 = new TestEventHandler<>();
+ mProcessor = new DebugCommandProcessor(mCommand0, mCommand1);
+ }
+
+ @Test
+ public void testTriesAllCommands() {
+ mProcessor.accept("#debug poodles");
+ mCommand0.assertCalled();
+ mCommand1.assertCalled();
+ }
+
+ @Test
+ public void testStopsAfterCommandHandled() {
+ mCommand0.nextReturn(true);
+ mProcessor.accept("#debug poodles");
+ mCommand0.assertCalled();
+ mCommand1.assertNotCalled();
+ }
+
+ @Test
+ public void testMissingCommand() {
+ mProcessor.accept("#debug");
+ mCommand0.assertNotCalled();
+ mCommand1.assertNotCalled();
+ }
+
+ @Test
+ public void testEmptyInput() {
+ mProcessor.accept("#debug");
+ mCommand0.assertNotCalled();
+ mCommand1.assertNotCalled();
+ }
+}