Add DEBUG build support for runtime flags/commands...
Using the search view as input mechanism.
When a command intercepts search input, we immediately cancel search mode.
Change-Id: Ida43ee2a49d504c9f0a0040e67224aa26b5b9964
diff --git a/src/com/android/documentsui/AbstractActionHandler.java b/src/com/android/documentsui/AbstractActionHandler.java
index 390dd00..131d2f7 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 a81b0ca..3820db5 100644
--- a/src/com/android/documentsui/BaseActivity.java
+++ b/src/com/android/documentsui/BaseActivity.java
@@ -47,7 +47,6 @@
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;
@@ -61,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;
diff --git a/src/com/android/documentsui/MenuManager.java b/src/com/android/documentsui/MenuManager.java
index f7685e1..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;
diff --git a/src/com/android/documentsui/RootsMonitor.java b/src/com/android/documentsui/RootsMonitor.java
index feead7a..da48794 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/files/ActionHandler.java b/src/com/android/documentsui/files/ActionHandler.java
index 09f90d4..9a9e05f 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;
@@ -52,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;
diff --git a/src/com/android/documentsui/files/MenuManager.java b/src/com/android/documentsui/files/MenuManager.java
index d0fd570..839c245 100644
--- a/src/com/android/documentsui/files/MenuManager.java
+++ b/src/com/android/documentsui/files/MenuManager.java
@@ -26,10 +26,10 @@
import android.view.View;
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 906b26a..d37e34c 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;
@@ -45,6 +44,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/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;
+ }
+}