Commit 933974b7 authored by Satoshi Niwa's avatar Satoshi Niwa Committed by Commit Bot

Files app: Initial impl of launchParams.searchQuery

If launchParams.searchQuery is set,
1) Performs a search at Files app start up.
2) Select the first root directory that contains one or more query-matched files.

Also did refactoring around DirectoryModel.createDirectoryContents_(...)
- Split createDirectoryContents_ into 2 functions
  isSearchDirectory(...) and createScannerFactory()
- Removed all DirectoryContents.createFor*(...) functions.

For now we expect that the searchQuery param is used only when Files app is launched as Android file picker.
1) and 2) are required by DocumentsUI CTS (See go/arc-r-documents-ui)

Bug: 1126742
Test: atest DocumentsTest#testGetContentWithQuery_matchingFileShowing
Change-Id: I1a76a93ee7fbf7ce7ae3fdd2a3dc408311bbd12a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2408502Reviewed-by: default avatarNaoki Fukino <fukino@chromium.org>
Reviewed-by: default avatarLuciano Pacheco <lucmult@chromium.org>
Auto-Submit: Satoshi Niwa <niwa@chromium.org>
Commit-Queue: Satoshi Niwa <niwa@chromium.org>
Cr-Commit-Position: refs/heads/master@{#811043}
parent 6a851cfc
......@@ -30,6 +30,7 @@ js_type_check("closure_compile_module") {
":closure_compile_externs",
":column_visibility_controller",
":constants",
":crossover_search_utils",
":crostini_controller",
":dialog_action_controller",
":dialog_type",
......@@ -235,6 +236,9 @@ js_library("column_visibility_controller") {
js_library("constants") {
}
js_library("crossover_search_utils") {
}
js_library("crostini_controller") {
deps = [
":directory_model",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* Namespace for crossover search utility functions.
* @namespace
*/
const crossoverSearchUtils = {};
/**
* Return DirectoryEntry of the first root directory that contains one or more
* query-matched files.
* @param {NavigationListModel} navListModel
* @param {DirectoryModel} dirModel
* @param {string} searchQuery Search query.
* @return {!Promise<DirectoryEntry>} DirectoryEntry of the first root
* directory (of type ENTRY_LIST or VOLUME) containing one or more files
* that match the search query.
* Returns null if no such directory is found.
*/
crossoverSearchUtils.findQueryMatchedDirectoryEntry =
async (navListModel, dirModel, searchQuery) => {
for (let i = 0; i < navListModel.length; i++) {
const item = navListModel.item(i);
let dirEntry;
switch (item.type) {
case NavigationModelItemType.ENTRY_LIST: // My files, Removable, etc.
dirEntry = /** @type {NavigationModelFakeItem} */
(item).entry.getNativeEntry();
break;
case NavigationModelItemType.VOLUME: // Drive, DocumentsProvider, etc.
dirEntry = /** @type {NavigationModelVolumeItem} */
(item).volumeInfo.displayRoot;
break;
default:
continue;
}
if (!dirEntry) {
continue;
}
let isMatchedEntryFound;
function entriesCallback(entries) {
isMatchedEntryFound = true;
}
function errorCallback(error) {
console.warn(error.stack || error);
}
const scanner = dirModel.createScannerFactory(dirEntry, searchQuery)();
await new Promise(
resolve => scanner.scan(
entriesCallback.bind(this), resolve, errorCallback.bind(this)));
if (isMatchedEntryFound) {
return dirEntry;
}
}
return null;
};
......@@ -1268,6 +1268,22 @@ class FileManager extends cr.EventTarget {
}
}
// If searchQuery param is set, find the first directory that matches the
// query, and select it if exists.
const searchQuery = this.launchParams_.searchQuery;
if (searchQuery) {
this.searchController_.setSearchQuery(searchQuery);
// Show a spinner, as the crossover search function call could be slow.
const hideSpinnerCallback = this.spinnerController_.show();
const queryMatchedDirEntry =
await crossoverSearchUtils.findQueryMatchedDirectoryEntry(
this.directoryTree.dataModel_, this.directoryModel_, searchQuery);
if (queryMatchedDirEntry) {
nextCurrentDirEntry = queryMatchedDirEntry;
}
hideSpinnerCallback();
}
// Resolve the currentDirectoryURL to currentDirectoryEntry (if not done by
// the previous step).
if (!nextCurrentDirEntry && this.launchParams_.currentDirectoryURL) {
......@@ -1392,6 +1408,9 @@ class FileManager extends cr.EventTarget {
if (opt_selectionEntry) {
this.directoryModel_.selectEntry(opt_selectionEntry);
}
if (this.launchParams_.searchQuery) {
this.searchController_.setSearchQuery(this.launchParams_.searchQuery);
}
} else {
console.warn('No entry for finishSetupCurrentDirectory_');
}
......
......@@ -80,6 +80,12 @@ class LaunchParam {
overrideCwsContainerOriginForTest: ''
};
/**
* @type {string}
* @const
*/
this.searchQuery = unformatted['searchQuery'] || '';
/**
* @type {boolean}
* @const
......
......@@ -88,6 +88,7 @@
// <include src="../../common/js/importer_common.js">
//
// <include src="constants.js">
// <include src="crossover_search_utils.js">
// <include src="web_store_utils.js">
// <include src="ui/multi_menu.js">
// <include src="ui/multi_menu_button.js">
......
......@@ -87,6 +87,16 @@ class SearchController {
}
}
/**
* Sets search query on the search box and performs a search.
* @param {string} searchQuery Search query string to be searched with.
*/
setSearchQuery(searchQuery) {
this.searchBox_.inputElement.focus();
this.searchBox_.inputElement.value = searchQuery;
this.onTextChange_();
}
/**
* Handles text change event.
* @private
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment