Commit 81528881 authored by Vladislav Kaznacheev's avatar Vladislav Kaznacheev Committed by Commit Bot

Remove dead code for WebStore search

Bug: 873486
Test: Chrome builds and runs
Change-Id: I507b97aa1bb0c894599037c5a8cc85286ebc9bd9
Reviewed-on: https://chromium-review.googlesource.com/c/1292249Reviewed-by: default avatarElijah Taylor <elijahtaylor@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Commit-Queue: Vladislav Kaznacheev <kaznacheev@chromium.org>
Cr-Commit-Position: refs/heads/master@{#601740}
parent 9b5c9d9b
......@@ -513,10 +513,6 @@ Chromium is unable to recover your settings.
</if>
<!-- Extension/App install prompt -->
<message name="IDS_EXTENSION_INLINE_INSTALL_PROMPT_TITLE" desc="Titlebar of the extension or app inline installation prompt window">
Add to Chromium
</message>
<if expr="enable_extensions">
<!-- Extension installed bubble -->
<message name="IDS_EXTENSION_INSTALLED_HEADING" desc="Title of the extension-installed bubble. Instructs that the extension was installed.">
......
......@@ -524,10 +524,6 @@ Google Chrome is unable to recover your settings.
</if>
<!-- Extension/App install prompt -->
<message name="IDS_EXTENSION_INLINE_INSTALL_PROMPT_TITLE" desc="Titlebar of the extension or app inline installation prompt window">
Add to Chrome
</message>
<if expr="enable_extensions">
<!-- Extension installed bubble -->
<message name="IDS_EXTENSION_INSTALLED_HEADING" desc="Title of the extension-installed bubble. Instructs that the extension was installed.">
......
......@@ -3127,12 +3127,6 @@ jumbo_split_static_library("ui") {
"app_list/search/common/json_response_fetcher.h",
"app_list/search/common/url_icon_source.cc",
"app_list/search/common/url_icon_source.h",
"app_list/search/common/webservice_cache.cc",
"app_list/search/common/webservice_cache.h",
"app_list/search/common/webservice_cache_factory.cc",
"app_list/search/common/webservice_cache_factory.h",
"app_list/search/common/webservice_search_provider.cc",
"app_list/search/common/webservice_search_provider.h",
"app_list/search/dictionary_data_store.cc",
"app_list/search/dictionary_data_store.h",
"app_list/search/extension_app_result.cc",
......@@ -3157,20 +3151,12 @@ jumbo_split_static_library("ui") {
"app_list/search/search_result_ranker/app_search_result_ranker.h",
"app_list/search/search_util.cc",
"app_list/search/search_util.h",
"app_list/search/search_webstore_result.cc",
"app_list/search/search_webstore_result.h",
"app_list/search/settings_shortcut/settings_shortcut_metadata.cc",
"app_list/search/settings_shortcut/settings_shortcut_metadata.h",
"app_list/search/settings_shortcut/settings_shortcut_provider.cc",
"app_list/search/settings_shortcut/settings_shortcut_provider.h",
"app_list/search/settings_shortcut/settings_shortcut_result.cc",
"app_list/search/settings_shortcut/settings_shortcut_result.h",
"app_list/search/webstore/webstore_installer.cc",
"app_list/search/webstore/webstore_installer.h",
"app_list/search/webstore/webstore_provider.cc",
"app_list/search/webstore/webstore_provider.h",
"app_list/search/webstore/webstore_result.cc",
"app_list/search/webstore/webstore_result.h",
]
deps += [
# TODO(wutao): Put new icons resources to ash/public/cpp/vector_icons/
......
// Copyright 2013 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.
#include "chrome/browser/ui/app_list/search/common/webservice_cache.h"
#include <stddef.h>
#include <stdint.h>
#include "base/memory/ptr_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/values.h"
#include "content/public/browser/browser_context.h"
namespace app_list {
namespace {
const unsigned int kWebserviceCacheMaxSize = 1000;
const unsigned int kWebserviceCacheTimeLimitInMinutes = 1;
const char kKeyResultTime[] = "time";
const char kKeyResult[] = "result";
const char kWebstoreQueryPrefix[] = "webstore:";
const char kPeopleQueryPrefix[] = "people:";
} // namespace
WebserviceCache::WebserviceCache(content::BrowserContext* context)
: cache_(Cache::NO_AUTO_EVICT),
cache_loaded_(false) {
const char kStoreDataFileName[] = "Webservice Search Cache";
const base::FilePath data_file =
context->GetPath().AppendASCII(kStoreDataFileName);
data_store_ = new DictionaryDataStore(data_file);
data_store_->Load(base::Bind(&WebserviceCache::OnCacheLoaded, AsWeakPtr()));
}
WebserviceCache::~WebserviceCache() {
}
const CacheResult WebserviceCache::Get(QueryType type,
const std::string& query) {
std::string typed_query = PrependType(type, query);
Cache::iterator iter = cache_.Get(typed_query);
if (iter != cache_.end()) {
if (base::Time::Now() - iter->second->time <=
base::TimeDelta::FromMinutes(kWebserviceCacheTimeLimitInMinutes)) {
return std::make_pair(FRESH, iter->second->result.get());
} else {
return std::make_pair(STALE, iter->second->result.get());
}
}
return std::make_pair(STALE, static_cast<base::DictionaryValue*>(NULL));
}
void WebserviceCache::Put(QueryType type,
const std::string& query,
std::unique_ptr<base::DictionaryValue> result) {
if (result) {
std::string typed_query = PrependType(type, query);
std::unique_ptr<Payload> scoped_payload =
std::make_unique<Payload>(base::Time::Now(), std::move(result));
Payload* payload = scoped_payload.get();
cache_.Put(typed_query, std::move(scoped_payload));
// If the cache isn't loaded yet, we're fine with losing queries since
// a 1000 entry cache should load really quickly so the chance of a user
// already having typed a 3 character search before the cache has loaded is
// very unlikely.
if (cache_loaded_) {
data_store_->cached_dict()->Set(typed_query, DictFromPayload(*payload));
data_store_->ScheduleWrite();
if (cache_.size() > kWebserviceCacheMaxSize)
TrimCache();
}
}
}
void WebserviceCache::OnCacheLoaded(std::unique_ptr<base::DictionaryValue>) {
if (!data_store_->cached_dict())
return;
std::vector<std::string> cleanup_keys;
for (base::DictionaryValue::Iterator it(*data_store_->cached_dict());
!it.IsAtEnd();
it.Advance()) {
const base::DictionaryValue* payload_dict;
std::unique_ptr<Payload> payload = std::make_unique<Payload>();
if (!it.value().GetAsDictionary(&payload_dict) ||
!payload_dict ||
!PayloadFromDict(payload_dict, payload.get())) {
// In case we don't have a valid payload associated with a given query,
// clean up that query from our data store.
cleanup_keys.push_back(it.key());
continue;
}
cache_.Put(it.key(), std::move(payload));
}
if (!cleanup_keys.empty()) {
for (size_t i = 0; i < cleanup_keys.size(); ++i)
data_store_->cached_dict()->Remove(cleanup_keys[i], NULL);
data_store_->ScheduleWrite();
}
cache_loaded_ = true;
}
bool WebserviceCache::PayloadFromDict(const base::DictionaryValue* dict,
Payload* payload) {
std::string time_string;
if (!dict->GetString(kKeyResultTime, &time_string))
return false;
const base::DictionaryValue* result;
if (!dict->GetDictionary(kKeyResult, &result))
return false;
int64_t time_val;
base::StringToInt64(time_string, &time_val);
// The result dictionary will be owned by the cache, hence create a copy
// instead of returning the original reference. The new dictionary will be
// owned by our MRU cache.
*payload = Payload(base::Time::FromInternalValue(time_val),
base::WrapUnique(result->DeepCopy()));
return true;
}
std::unique_ptr<base::DictionaryValue> WebserviceCache::DictFromPayload(
const Payload& payload) {
auto dict = std::make_unique<base::DictionaryValue>();
dict->SetString(kKeyResultTime, base::Int64ToString(
payload.time.ToInternalValue()));
// The payload will still keep ownership of it's result dict, hence put a
// a copy of the result dictionary here. This dictionary will be owned by
// data_store_->cached_dict().
dict->SetKey(kKeyResult, payload.result->Clone());
return dict;
}
void WebserviceCache::TrimCache() {
for (Cache::size_type i = cache_.size(); i > kWebserviceCacheMaxSize; i--) {
Cache::reverse_iterator rbegin = cache_.rbegin();
data_store_->cached_dict()->Remove(rbegin->first, NULL);
cache_.Erase(rbegin);
}
data_store_->ScheduleWrite();
}
std::string WebserviceCache::PrependType(
QueryType type, const std::string& query) {
switch (type) {
case WEBSTORE:
return kWebstoreQueryPrefix + query;
case PEOPLE:
return kPeopleQueryPrefix + query;
default:
return query;
}
}
WebserviceCache::Payload::Payload(const base::Time& time,
std::unique_ptr<base::DictionaryValue> result)
: time(time), result(std::move(result)) {}
WebserviceCache::Payload::Payload() = default;
WebserviceCache::Payload::~Payload() = default;
WebserviceCache::Payload& WebserviceCache::Payload::operator=(Payload&& other) {
time = std::move(other.time);
result = std::move(other.result);
return *this;
}
} // namespace app_list
// Copyright 2013 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.
#ifndef CHROME_BROWSER_UI_APP_LIST_SEARCH_COMMON_WEBSERVICE_CACHE_H_
#define CHROME_BROWSER_UI_APP_LIST_SEARCH_COMMON_WEBSERVICE_CACHE_H_
#include <memory>
#include <string>
#include <utility>
#include "base/containers/mru_cache.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "chrome/browser/ui/app_list/search/dictionary_data_store.h"
#include "components/keyed_service/core/keyed_service.h"
namespace base {
class DictionaryValue;
}
namespace content {
class BrowserContext;
}
namespace app_list {
enum ResultStatus {
FRESH = 0,
STALE = 1
};
// Pair of values, first indicating whether this is a fresh result or stale,
// the second holding the actual value.
typedef std::pair<ResultStatus, const base::DictionaryValue*> CacheResult;
// WebserviceCache manages a cache of search results which should be valid
// during an input session. This will reduce unnecessary queries for typing
// backspace or so on. This is not meant to hold cache entries across multiple
// search sessions.
class WebserviceCache : public KeyedService,
public base::SupportsWeakPtr<WebserviceCache> {
public:
enum QueryType {
WEBSTORE = 0,
PEOPLE = 1
};
explicit WebserviceCache(content::BrowserContext* context);
~WebserviceCache() override;
// Checks the current cache and returns the value for the |query| if it's
// valid. Otherwise an CacheResult object with the result field set to NULL.
// A query consists of a query 'type' and the query itself. The two current
// types of queries supported are webstore queries and people search queries.
// The type silos the query into it's own separate domain, preventing any
// mixing of the queries.
const CacheResult Get(QueryType type, const std::string& query);
// Puts the new result to the query.
void Put(QueryType type,
const std::string& query,
std::unique_ptr<base::DictionaryValue> result);
private:
struct Payload {
Payload(const base::Time& time,
std::unique_ptr<base::DictionaryValue> result);
Payload();
~Payload();
Payload& operator=(Payload&& other);
base::Time time;
std::unique_ptr<base::DictionaryValue> result;
};
using Cache = base::MRUCache<std::string, std::unique_ptr<Payload>>;
// Callback for when the cache is loaded from the dictionary data store.
void OnCacheLoaded(std::unique_ptr<base::DictionaryValue>);
// Populates the payload parameter with the corresponding payload stored
// in the given dictionary. If the dictionary is invalid for any reason,
// this method will return false.
bool PayloadFromDict(const base::DictionaryValue* dict, Payload* payload);
// Returns a dictionary value for a given payload. The returned dictionary
// will be owned by the data_store_ cached_dict, and freed on the destruction
// of our dictionary datastore.
std::unique_ptr<base::DictionaryValue> DictFromPayload(
const Payload& payload);
// Trims our MRU cache, making sure that any element that is removed is also
// removed from the dictionary data store.
void TrimCache();
// Prepends a type string to the given query and returns a new query string.
std::string PrependType(QueryType type, const std::string& query);
Cache cache_;
scoped_refptr<DictionaryDataStore> data_store_;
bool cache_loaded_;
DISALLOW_COPY_AND_ASSIGN(WebserviceCache);
};
} // namespace app_list
#endif // CHROME_BROWSER_UI_APP_LIST_SEARCH_COMMON_WEBSERVICE_CACHE_H_
// Copyright 2013 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.
#include "chrome/browser/ui/app_list/search/common/webservice_cache_factory.h"
#include "base/memory/singleton.h"
#include "chrome/browser/ui/app_list/search/common/webservice_cache.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
namespace app_list {
// static
WebserviceCacheFactory* WebserviceCacheFactory::GetInstance() {
return base::Singleton<WebserviceCacheFactory>::get();
}
// static
WebserviceCache* WebserviceCacheFactory::GetForBrowserContext(
content::BrowserContext* context) {
return static_cast<WebserviceCache*>(
GetInstance()->GetServiceForBrowserContext(context, true));
}
WebserviceCacheFactory::WebserviceCacheFactory()
: BrowserContextKeyedServiceFactory(
"app_list::WebserviceCache",
BrowserContextDependencyManager::GetInstance()) {}
WebserviceCacheFactory::~WebserviceCacheFactory() {}
KeyedService* WebserviceCacheFactory::BuildServiceInstanceFor(
content::BrowserContext* context) const {
return new WebserviceCache(context);
}
} // namespace app_list
// Copyright 2013 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.
#ifndef CHROME_BROWSER_UI_APP_LIST_SEARCH_COMMON_WEBSERVICE_CACHE_FACTORY_H_
#define CHROME_BROWSER_UI_APP_LIST_SEARCH_COMMON_WEBSERVICE_CACHE_FACTORY_H_
#include "base/macros.h"
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
namespace base {
template<typename T> struct DefaultSingletonTraits;
}
namespace content {
class BrowserContext;
}
namespace app_list {
class WebserviceCache;
// Singleton that owns the WebserviceCaches and associates them with profiles;
class WebserviceCacheFactory : public BrowserContextKeyedServiceFactory {
public:
// Returns singleton instance of WebserviceCacheFactory.
static WebserviceCacheFactory* GetInstance();
// Returns the Webservice cache associated with |context|.
static WebserviceCache* GetForBrowserContext(
content::BrowserContext* context);
private:
friend struct base::DefaultSingletonTraits<WebserviceCacheFactory>;
WebserviceCacheFactory();
~WebserviceCacheFactory() override;
// BrowserContextKeyedServiceFactory overrides:
KeyedService* BuildServiceInstanceFor(
content::BrowserContext* context) const override;
DISALLOW_COPY_AND_ASSIGN(WebserviceCacheFactory);
};
} // namespace app_list
#endif // CHROME_BROWSER_UI_APP_LIST_SEARCH_COMMON_WEBSERVICE_CACHE_FACTORY_H_
// Copyright 2013 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.
#include "chrome/browser/ui/app_list/search/common/webservice_search_provider.h"
#include <stddef.h>
#include <string>
#include "base/callback.h"
#include "base/strings/string_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search/search.h"
#include "chrome/browser/ui/app_list/search/common/webservice_cache.h"
#include "chrome/browser/ui/app_list/search/common/webservice_cache_factory.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "url/gurl.h"
#include "url/url_constants.h"
namespace app_list {
namespace {
const int kWebserviceQueryThrottleIntrevalInMs = 100;
const size_t kMinimumQueryLength = 3u;
bool IsSuggestPrefEnabled(Profile* profile) {
return profile && !profile->IsOffTheRecord() && profile->GetPrefs() &&
profile->GetPrefs()->GetBoolean(prefs::kSearchSuggestEnabled);
}
} // namespace
WebserviceSearchProvider::WebserviceSearchProvider(Profile* profile)
: profile_(profile),
cache_(WebserviceCacheFactory::GetForBrowserContext(profile)),
use_throttling_(true) {}
WebserviceSearchProvider::~WebserviceSearchProvider() {}
void WebserviceSearchProvider::StartThrottledQuery(
const base::Closure& start_query) {
base::TimeDelta interval =
base::TimeDelta::FromMilliseconds(kWebserviceQueryThrottleIntrevalInMs);
if (!use_throttling_ || base::Time::Now() - last_keytyped_ > interval) {
query_throttler_.Stop();
start_query.Run();
} else {
query_throttler_.Start(FROM_HERE, interval, start_query);
}
last_keytyped_ = base::Time::Now();
}
bool WebserviceSearchProvider::IsValidQuery(const base::string16& query) {
// If |query| contains sensitive data, bail out and do not create the place
// holder "search-web-store" result.
if (IsSensitiveInput(query) || (query.size() < kMinimumQueryLength) ||
!IsSuggestPrefEnabled(profile_)) {
return false;
}
return true;
}
// Returns whether or not the user's input string, |query|, might contain any
// sensitive information, based purely on its value and not where it came from.
bool WebserviceSearchProvider::IsSensitiveInput(const base::string16& query) {
const GURL query_as_url(query);
if (!query_as_url.is_valid())
return false;
// The input can be interpreted as a URL. Check to see if it is potentially
// sensitive. (Code shamelessly copied from search_provider.cc's
// IsQuerySuitableForSuggest function.)
// First we check the scheme: if this looks like a URL with a scheme that is
// file, we shouldn't send it. Sending such things is a waste of time and a
// disclosure of potentially private, local data. If the scheme is OK, we
// still need to check other cases below.
if (base::LowerCaseEqualsASCII(query_as_url.scheme(), url::kFileScheme))
return true;
// Don't send URLs with usernames, queries or refs. Some of these are
// private, and the Suggest server is unlikely to have any useful results
// for any of them. Also don't send URLs with ports, as we may initially
// think that a username + password is a host + port (and we don't want to
// send usernames/passwords), and even if the port really is a port, the
// server is once again unlikely to have and useful results.
if (!query_as_url.username().empty() ||
!query_as_url.port().empty() ||
!query_as_url.query().empty() ||
!query_as_url.ref().empty()) {
return true;
}
// Don't send anything for https except the hostname. Hostnames are OK
// because they are visible when the TCP connection is established, but the
// specific path may reveal private information.
if (base::LowerCaseEqualsASCII(query_as_url.scheme(), url::kHttpsScheme) &&
!query_as_url.path().empty() && query_as_url.path() != "/") {
return true;
}
return false;
}
} // namespace app_list
// Copyright 2013 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.
#ifndef CHROME_BROWSER_UI_APP_LIST_SEARCH_COMMON_WEBSERVICE_SEARCH_PROVIDER_H_
#define CHROME_BROWSER_UI_APP_LIST_SEARCH_COMMON_WEBSERVICE_SEARCH_PROVIDER_H_
#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/strings/string16.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chrome/browser/ui/app_list/search/common/webservice_cache.h"
#include "chrome/browser/ui/app_list/search/search_provider.h"
class Profile;
namespace app_list {
class WebserviceCache;
// Helper class for webservice based searches.
class WebserviceSearchProvider : public SearchProvider {
public:
explicit WebserviceSearchProvider(Profile* profile);
~WebserviceSearchProvider() override;
// Validate the query for privacy and size.
bool IsValidQuery(const base::string16& query);
// Start a query with throttling enabled.
void StartThrottledQuery(const base::Closure& start_query);
void set_use_throttling(bool use) { use_throttling_ = use; }
protected:
Profile* profile_;
WebserviceCache* cache_; // KeyedService, not owned.
private:
bool IsSensitiveInput(const base::string16& query);
// The timestamp when the last key event happened.
base::Time last_keytyped_;
// The timer to throttle QPS.
base::OneShotTimer query_throttler_;
// The flag for tests. It prevents the throttling If set to false.
bool use_throttling_;
DISALLOW_COPY_AND_ASSIGN(WebserviceSearchProvider);
};
} // namespace app_list
#endif // CHROME_BROWSER_UI_APP_LIST_SEARCH_COMMON_WEBSERVICE_SEARCH_PROVIDER_H_
......@@ -24,7 +24,6 @@
#include "chrome/browser/ui/app_list/search/omnibox_provider.h"
#include "chrome/browser/ui/app_list/search/search_controller.h"
#include "chrome/browser/ui/app_list/search/settings_shortcut/settings_shortcut_provider.h"
#include "chrome/browser/ui/app_list/search/webstore/webstore_provider.h"
#include "chrome/common/chrome_switches.h"
#include "components/arc/arc_util.h"
......@@ -39,7 +38,6 @@ namespace {
// number of results to be displayed in UI.
constexpr size_t kMaxAppsGroupResults = 7;
constexpr size_t kMaxOmniboxResults = 4;
constexpr size_t kMaxWebstoreResults = 2;
constexpr size_t kMaxLauncherSearchResults = 2;
// We show up to 6 Play Store results. However, part of Play Store results may
// be filtered out because they may correspond to already installed Web apps. So
......@@ -68,7 +66,7 @@ std::unique_ptr<SearchController> CreateSearchController(
std::unique_ptr<SearchController> controller =
std::make_unique<SearchController>(model_updater, list_controller);
// Add mixer groups. There are four main groups: answer card, apps, webstore
// Add mixer groups. There are four main groups: answer card, apps
// and omnibox. Each group has a "soft" maximum number of results. However, if
// a query turns up very few results, the mixer may take more than this
// maximum from a particular group.
......@@ -80,8 +78,6 @@ std::unique_ptr<SearchController> CreateSearchController(
size_t apps_group_id =
controller->AddGroup(kMaxAppsGroupResults, 1.0, kBoostOfApps);
size_t omnibox_group_id = controller->AddGroup(kMaxOmniboxResults, 1.0, 0.0);
size_t webstore_group_id =
controller->AddGroup(kMaxWebstoreResults, 0.4, 0.0);
// Add search providers.
controller->AddProvider(
......@@ -90,11 +86,6 @@ std::unique_ptr<SearchController> CreateSearchController(
base::DefaultClock::GetInstance(), model_updater));
controller->AddProvider(omnibox_group_id, std::make_unique<OmniboxProvider>(
profile, list_controller));
if (arc::IsWebstoreSearchEnabled()) {
controller->AddProvider(
webstore_group_id,
std::make_unique<WebstoreProvider>(profile, list_controller));
}
if (app_list_features::IsAnswerCardEnabled()) {
controller->AddProvider(
answer_card_group_id,
......
......@@ -14,10 +14,10 @@ enum SearchResultType {
OMNIBOX_SEARCH_RESULT,
// An app result.
APP_SEARCH_RESULT,
// A search result from the webstore.
WEBSTORE_SEARCH_RESULT,
// A result that opens a webstore search.
SEARCH_WEBSTORE_SEARCH_RESULT,
// A search result from the webstore (Deprecated).
WEBSTORE_SEARCH_RESULT_DEPRECATED,
// A result that opens a webstore search (Deprecated)
SEARCH_WEBSTORE_SEARCH_RESULT_DEPRECATED,
// A result that opens a people search (Deprecated).
SEARCH_PEOPLE_SEARCH_RESULT_DEPRECATED,
// A result that opens a suggestion.
......
// Copyright 2013 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.
#include "chrome/browser/ui/app_list/search/search_webstore_result.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
#include "chrome/browser/ui/app_list/search/search_util.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/grit/theme_resources.h"
#include "extensions/common/extension_urls.h"
#include "net/base/url_util.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
namespace app_list {
SearchWebstoreResult::SearchWebstoreResult(
Profile* profile,
AppListControllerDelegate* controller,
const std::string& query)
: profile_(profile),
controller_(controller),
query_(query),
launch_url_(extension_urls::GetWebstoreSearchPageUrl(query)) {
set_id(launch_url_.spec());
set_relevance(0.0);
SetResultType(ash::SearchResultType::kWebStoreApp);
SetTitle(base::UTF8ToUTF16(query));
const base::string16 details =
l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE);
Tags details_tags;
details_tags.push_back(Tag(ash::SearchResultTag::DIM, 0, details.length()));
SetDetails(details);
SetDetailsTags(details_tags);
SetIcon(*ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
IDR_WEBSTORE_ICON_32));
}
SearchWebstoreResult::~SearchWebstoreResult() {}
void SearchWebstoreResult::Open(int event_flags) {
RecordHistogram(WEBSTORE_SEARCH_RESULT);
const GURL store_url = net::AppendQueryParameter(
launch_url_,
extension_urls::kWebstoreSourceField,
extension_urls::kLaunchSourceAppListSearch);
controller_->OpenURL(profile_,
store_url,
ui::PAGE_TRANSITION_LINK,
ui::DispositionFromEventFlags(event_flags));
}
} // namespace app_list
// Copyright 2013 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.
#ifndef CHROME_BROWSER_UI_APP_LIST_SEARCH_SEARCH_WEBSTORE_RESULT_H_
#define CHROME_BROWSER_UI_APP_LIST_SEARCH_SEARCH_WEBSTORE_RESULT_H_
#include <memory>
#include <string>
#include "base/macros.h"
#include "chrome/browser/ui/app_list/search/chrome_search_result.h"
#include "url/gurl.h"
class AppListControllerDelegate;
class Profile;
namespace app_list {
// A "search in webstore" result.
class SearchWebstoreResult : public ChromeSearchResult {
public:
SearchWebstoreResult(Profile* profile,
AppListControllerDelegate* controller,
const std::string& query);
~SearchWebstoreResult() override;
// ChromeSearchResult overrides:
void Open(int event_flags) override;
private:
Profile* profile_;
AppListControllerDelegate* controller_;
const std::string query_;
GURL launch_url_;
DISALLOW_COPY_AND_ASSIGN(SearchWebstoreResult);
};
} // namespace app_list
#endif // CHROME_BROWSER_UI_APP_LIST_SEARCH_SEARCH_WEBSTORE_RESULT_H_
// Copyright 2013 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.
#include "chrome/browser/ui/app_list/search/webstore/webstore_installer.h"
namespace app_list {
WebstoreInstaller::WebstoreInstaller(const std::string& webstore_item_id,
Profile* profile,
const Callback& callback)
: WebstoreInstallWithPrompt(webstore_item_id,
profile,
callback) {
set_install_source(
extensions::WebstoreInstaller::INSTALL_SOURCE_APP_LAUNCHER);
set_show_post_install_ui(false);
}
WebstoreInstaller::~WebstoreInstaller() {}
} // namespace app_list
// Copyright 2013 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.
#ifndef CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_WEBSTORE_INSTALLER_H_
#define CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_WEBSTORE_INSTALLER_H_
#include <string>
#include "base/macros.h"
#include "chrome/browser/extensions/webstore_install_with_prompt.h"
class Profile;
namespace app_list {
// WebstoreInstaller handles install for web store search results.
class WebstoreInstaller : public extensions::WebstoreInstallWithPrompt {
public:
typedef WebstoreStandaloneInstaller::Callback Callback;
WebstoreInstaller(const std::string& webstore_item_id,
Profile* profile,
const Callback& callback);
private:
friend class base::RefCountedThreadSafe<WebstoreInstaller>;
~WebstoreInstaller() override;
DISALLOW_COPY_AND_ASSIGN(WebstoreInstaller);
};
} // namespace app_list
#endif // CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_WEBSTORE_INSTALLER_H_
// Copyright 2013 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.
#include "chrome/browser/ui/app_list/search/webstore/webstore_provider.h"
#include <string>
#include <utility>
#include "ash/public/cpp/app_list/tokenized_string.h"
#include "ash/public/cpp/app_list/tokenized_string_match.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search/search.h"
#include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
#include "chrome/browser/ui/app_list/search/common/json_response_fetcher.h"
#include "chrome/browser/ui/app_list/search/search_webstore_result.h"
#include "chrome/browser/ui/app_list/search/webstore/webstore_result.h"
#include "extensions/common/extension_urls.h"
#include "url/gurl.h"
namespace app_list {
namespace {
const char kKeyResults[] = "results";
const char kKeyId[] = "id";
const char kKeyLocalizedName[] = "localized_name";
const char kKeyIconUrl[] = "icon_url";
const char kKeyIsPaid[] = "is_paid";
const char kKeyItemType[] = "item_type";
const char kPlatformAppType[] = "platform_app";
const char kHostedAppType[] = "hosted_app";
const char kLegacyPackagedAppType[] = "legacy_packaged_app";
// Converts the item type string from the web store to an
// extensions::Manifest::Type.
extensions::Manifest::Type ParseItemType(const std::string& item_type_str) {
if (base::LowerCaseEqualsASCII(item_type_str, kPlatformAppType))
return extensions::Manifest::TYPE_PLATFORM_APP;
if (base::LowerCaseEqualsASCII(item_type_str, kLegacyPackagedAppType))
return extensions::Manifest::TYPE_LEGACY_PACKAGED_APP;
if (base::LowerCaseEqualsASCII(item_type_str, kHostedAppType))
return extensions::Manifest::TYPE_HOSTED_APP;
return extensions::Manifest::TYPE_UNKNOWN;
}
} // namespace
WebstoreProvider::WebstoreProvider(Profile* profile,
AppListControllerDelegate* controller)
: WebserviceSearchProvider(profile),
controller_(controller),
query_pending_(false) {
}
WebstoreProvider::~WebstoreProvider() {}
void WebstoreProvider::Start(const base::string16& query) {
if (webstore_search_)
webstore_search_->Stop();
ClearResults();
if (!IsValidQuery(query)) {
query_.clear();
return;
}
query_ = base::UTF16ToUTF8(query);
const CacheResult result = cache_->Get(WebserviceCache::WEBSTORE, query_);
if (result.second) {
ProcessWebstoreSearchResults(result.second);
if (!webstore_search_fetched_callback_.is_null())
webstore_search_fetched_callback_.Run();
if (result.first == FRESH)
return;
}
if (!webstore_search_) {
webstore_search_ = std::make_unique<JSONResponseFetcher>(
base::Bind(&WebstoreProvider::OnWebstoreSearchFetched,
base::Unretained(this)),
profile_);
}
query_pending_ = true;
StartThrottledQuery(base::Bind(&WebstoreProvider::StartQuery,
base::Unretained(this)));
// Add a placeholder result which when clicked will run the user's query in a
// browser. This placeholder is removed when the search results arrive.
Add(std::make_unique<SearchWebstoreResult>(profile_, controller_, query_));
}
void WebstoreProvider::StartQuery() {
// |query_| can be NULL when the query is scheduled but then canceled.
if (!webstore_search_ || query_.empty())
return;
webstore_search_->Start(extension_urls::GetWebstoreJsonSearchUrl(
query_, g_browser_process->GetApplicationLocale()));
}
void WebstoreProvider::OnWebstoreSearchFetched(
std::unique_ptr<base::DictionaryValue> json) {
ProcessWebstoreSearchResults(json.get());
cache_->Put(WebserviceCache::WEBSTORE, query_, std::move(json));
query_pending_ = false;
if (!webstore_search_fetched_callback_.is_null())
webstore_search_fetched_callback_.Run();
}
void WebstoreProvider::ProcessWebstoreSearchResults(
const base::DictionaryValue* json) {
const base::ListValue* result_list = NULL;
if (!json ||
!json->GetList(kKeyResults, &result_list) ||
!result_list ||
result_list->empty()) {
return;
}
bool first_result = true;
TokenizedString query(base::UTF8ToUTF16(query_));
for (base::ListValue::const_iterator it = result_list->begin();
it != result_list->end();
++it) {
const base::DictionaryValue* dict;
if (!it->GetAsDictionary(&dict))
continue;
std::unique_ptr<ChromeSearchResult> result(CreateResult(query, *dict));
if (!result)
continue;
if (first_result) {
// Clears "search in webstore" place holder results.
ClearResults();
first_result = false;
}
Add(std::move(result));
}
}
std::unique_ptr<ChromeSearchResult> WebstoreProvider::CreateResult(
const TokenizedString& query,
const base::DictionaryValue& dict) {
std::string app_id;
std::string localized_name;
std::string icon_url_string;
bool is_paid = false;
if (!dict.GetString(kKeyId, &app_id) ||
!dict.GetString(kKeyLocalizedName, &localized_name) ||
!dict.GetString(kKeyIconUrl, &icon_url_string) ||
!dict.GetBoolean(kKeyIsPaid, &is_paid)) {
return nullptr;
}
// If an app is already installed, don't show it in results.
if (controller_->IsExtensionInstalled(profile_, app_id))
return nullptr;
GURL icon_url(icon_url_string);
if (!icon_url.is_valid())
return nullptr;
std::string item_type_string;
dict.GetString(kKeyItemType, &item_type_string);
extensions::Manifest::Type item_type = ParseItemType(item_type_string);
// Calculate the relevance score by matching the query with the title. Results
// with a match score of 0 are discarded. This will also be used to set the
// title tags (highlighting which parts of the title matched the search
// query).
TokenizedString title(base::UTF8ToUTF16(localized_name));
TokenizedStringMatch match;
if (!match.Calculate(query, title))
return nullptr;
std::unique_ptr<ChromeSearchResult> result = std::make_unique<WebstoreResult>(
profile_, app_id, icon_url, is_paid, item_type, controller_);
result->UpdateFromMatch(title, match);
return result;
}
} // namespace app_list
// Copyright 2013 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.
#ifndef CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_WEBSTORE_PROVIDER_H_
#define CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_WEBSTORE_PROVIDER_H_
#include <memory>
#include <string>
#include "base/callback_forward.h"
#include "base/macros.h"
#include "chrome/browser/ui/app_list/search/common/webservice_search_provider.h"
class AppListControllerDelegate;
class ChromeSearchResult;
namespace base {
class DictionaryValue;
}
namespace app_list {
namespace test {
class WebstoreProviderTest;
}
class JSONResponseFetcher;
class TokenizedString;
// WebstoreProvider fetches search results from the web store server.
// A "Search in web store" result will be returned if the server does not
// return any results.
class WebstoreProvider : public WebserviceSearchProvider{
public:
WebstoreProvider(Profile* profile, AppListControllerDelegate* controller);
~WebstoreProvider() override;
// SearchProvider overrides:
void Start(const base::string16& query) override;
private:
friend class app_list::test::WebstoreProviderTest;
// Start the search request with |query_|.
void StartQuery();
void OnWebstoreSearchFetched(std::unique_ptr<base::DictionaryValue> json);
void ProcessWebstoreSearchResults(const base::DictionaryValue* json);
std::unique_ptr<ChromeSearchResult> CreateResult(
const TokenizedString& query,
const base::DictionaryValue& dict);
void set_webstore_search_fetched_callback(const base::Closure& callback) {
webstore_search_fetched_callback_ = callback;
}
AppListControllerDelegate* controller_;
std::unique_ptr<JSONResponseFetcher> webstore_search_;
base::Closure webstore_search_fetched_callback_;
// The current query.
std::string query_;
// Whether there is currently a query pending.
bool query_pending_;
DISALLOW_COPY_AND_ASSIGN(WebstoreProvider);
};
} // namespace app_list
#endif // CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_WEBSTORE_PROVIDER_H_
// Copyright 2013 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.
#include "chrome/browser/ui/app_list/search/webstore/webstore_result.h"
#include <stddef.h>
#include <algorithm>
#include <vector>
#include "ash/public/cpp/app_list/app_list_config.h"
#include "base/bind.h"
#include "base/memory/ref_counted.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/install_tracker.h"
#include "chrome/browser/extensions/install_tracker_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
#include "chrome/browser/ui/app_list/search/common/url_icon_source.h"
#include "chrome/browser/ui/app_list/search/search_util.h"
#include "chrome/browser/ui/app_list/search/webstore/webstore_installer.h"
#include "chrome/browser/ui/extensions/application_launch.h"
#include "chrome/grit/chromium_strings.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/grit/theme_resources.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/extension_urls.h"
#include "net/base/url_util.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
namespace app_list {
WebstoreResult::WebstoreResult(Profile* profile,
const std::string& app_id,
const GURL& icon_url,
bool is_paid,
extensions::Manifest::Type item_type,
AppListControllerDelegate* controller)
: profile_(profile),
app_id_(app_id),
icon_url_(icon_url),
is_paid_(is_paid),
item_type_(item_type),
controller_(controller),
install_tracker_(NULL),
extension_registry_(NULL),
weak_factory_(this) {
set_id(GetResultIdFromExtensionId(app_id));
SetResultType(ash::SearchResultType::kWebStoreSearch);
SetDefaultDetails();
InitAndStartObserving();
UpdateActions();
int icon_dimension =
AppListConfig::instance().GetPreferredIconDimension(display_type());
icon_ = gfx::ImageSkia(
std::make_unique<UrlIconSource>(
base::Bind(&WebstoreResult::OnIconLoaded, weak_factory_.GetWeakPtr()),
profile_, icon_url_, icon_dimension, IDR_WEBSTORE_ICON_32),
gfx::Size(icon_dimension, icon_dimension));
SetIcon(icon_);
}
WebstoreResult::~WebstoreResult() {
StopObservingInstall();
StopObservingRegistry();
}
// static
std::string WebstoreResult::GetResultIdFromExtensionId(
const std::string& extension_id) {
return extension_urls::GetWebstoreItemDetailURLPrefix() + extension_id;
}
void WebstoreResult::Open(int event_flags) {
RecordHistogram(SEARCH_WEBSTORE_SEARCH_RESULT);
const GURL store_url = net::AppendQueryParameter(
GURL(extension_urls::GetWebstoreItemDetailURLPrefix() + app_id_),
extension_urls::kWebstoreSourceField,
extension_urls::kLaunchSourceAppListSearch);
controller_->OpenURL(profile_, store_url, ui::PAGE_TRANSITION_LINK,
ui::DispositionFromEventFlags(event_flags));
}
void WebstoreResult::InvokeAction(int action_index, int event_flags) {
if (is_paid_) {
// Paid apps cannot be installed directly from the launcher. Instead, open
// the webstore page for the app.
Open(event_flags);
return;
}
StartInstall();
}
void WebstoreResult::InitAndStartObserving() {
DCHECK(!install_tracker_ && !extension_registry_);
install_tracker_ =
extensions::InstallTrackerFactory::GetForBrowserContext(profile_);
extension_registry_ = extensions::ExtensionRegistry::Get(profile_);
const extensions::ActiveInstallData* install_data =
install_tracker_->GetActiveInstall(app_id_);
if (install_data) {
SetPercentDownloaded(install_data->percent_downloaded);
SetIsInstalling(true);
}
install_tracker_->AddObserver(this);
extension_registry_->AddObserver(this);
}
void WebstoreResult::UpdateActions() {
Actions actions;
const bool is_otr = profile_->IsOffTheRecord();
const bool is_installed =
extension_registry_->GetExtensionById(
app_id_, extensions::ExtensionRegistry::EVERYTHING) != nullptr;
if (!is_otr && !is_installed && !is_installing()) {
actions.push_back(Action(
l10n_util::GetStringUTF16(IDS_EXTENSION_INLINE_INSTALL_PROMPT_TITLE),
base::string16()));
}
SetActions(actions);
}
void WebstoreResult::SetDefaultDetails() {
const base::string16 details =
l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE);
Tags details_tags;
details_tags.push_back(Tag(ash::SearchResultTag::DIM, 0, details.length()));
SetDetails(details);
SetDetailsTags(details_tags);
}
void WebstoreResult::OnIconLoaded() {
// Set webstore badge.
SetBadgeIcon(*ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
IDR_WEBSTORE_ICON_16));
// Remove the existing image reps since the icon data is loaded and they
// need to be re-created.
const std::vector<gfx::ImageSkiaRep>& image_reps = icon_.image_reps();
for (size_t i = 0; i < image_reps.size(); ++i)
icon_.RemoveRepresentation(image_reps[i].scale());
SetIcon(icon_);
}
void WebstoreResult::StartInstall() {
SetPercentDownloaded(0);
SetIsInstalling(true);
scoped_refptr<WebstoreInstaller> installer = new WebstoreInstaller(
app_id_, profile_,
base::Bind(&WebstoreResult::InstallCallback, weak_factory_.GetWeakPtr()));
installer->BeginInstall();
}
void WebstoreResult::InstallCallback(
bool success,
const std::string& error,
extensions::webstore_install::Result result) {
if (!success) {
LOG(ERROR) << "Failed to install app, error=" << error;
SetIsInstalling(false);
return;
}
// Success handling is continued in OnExtensionInstalled.
SetPercentDownloaded(100);
}
void WebstoreResult::LaunchCallback(extensions::webstore_install::Result result,
const std::string& error) {
if (result != extensions::webstore_install::SUCCESS)
LOG(ERROR) << "Failed to launch app, error=" << error;
SetIsInstalling(false);
}
void WebstoreResult::StopObservingInstall() {
if (install_tracker_)
install_tracker_->RemoveObserver(this);
install_tracker_ = NULL;
}
void WebstoreResult::StopObservingRegistry() {
if (extension_registry_)
extension_registry_->RemoveObserver(this);
extension_registry_ = NULL;
}
void WebstoreResult::OnDownloadProgress(const std::string& extension_id,
int percent_downloaded) {
if (extension_id != app_id_ || percent_downloaded < 0)
return;
SetPercentDownloaded(percent_downloaded);
}
void WebstoreResult::OnExtensionInstalled(
content::BrowserContext* browser_context,
const extensions::Extension* extension,
bool is_update) {
if (extension->id() != app_id_)
return;
SetIsInstalling(false);
UpdateActions();
if (extension_registry_->GetExtensionById(
app_id_, extensions::ExtensionRegistry::EVERYTHING)) {
NotifyItemInstalled();
}
}
void WebstoreResult::OnShutdown() {
StopObservingInstall();
}
void WebstoreResult::OnShutdown(extensions::ExtensionRegistry* registry) {
StopObservingRegistry();
}
} // namespace app_list
// Copyright 2013 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.
#ifndef CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_WEBSTORE_RESULT_H_
#define CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_WEBSTORE_RESULT_H_
#include <memory>
#include <string>
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/extensions/install_observer.h"
#include "chrome/browser/ui/app_list/search/chrome_search_result.h"
#include "chrome/common/extensions/webstore_install_result.h"
#include "extensions/browser/extension_registry_observer.h"
#include "extensions/common/manifest.h"
#include "url/gurl.h"
class AppListControllerDelegate;
class Profile;
namespace extensions {
class ExtensionRegistry;
class InstallTracker;
}
namespace app_list {
class WebstoreResult : public ChromeSearchResult,
public extensions::InstallObserver,
public extensions::ExtensionRegistryObserver {
public:
WebstoreResult(Profile* profile,
const std::string& app_id,
const GURL& icon_url,
bool is_paid,
extensions::Manifest::Type item_type,
AppListControllerDelegate* controller);
~WebstoreResult() override;
static std::string GetResultIdFromExtensionId(
const std::string& extension_id);
const std::string& app_id() const { return app_id_; }
const GURL& icon_url() const { return icon_url_; }
extensions::Manifest::Type item_type() const { return item_type_; }
bool is_paid() const { return is_paid_; }
// ChromeSearchResult overrides:
void Open(int event_flags) override;
void InvokeAction(int action_index, int event_flags) override;
private:
// Set the initial state and start observing both InstallObserver and
// ExtensionRegistryObserver.
void InitAndStartObserving();
void UpdateActions();
void SetDefaultDetails();
void OnIconLoaded();
void StartInstall();
void InstallCallback(bool success,
const std::string& error,
extensions::webstore_install::Result result);
void LaunchCallback(extensions::webstore_install::Result result,
const std::string& error);
void StopObservingInstall();
void StopObservingRegistry();
// extensions::InstallObserver overrides:
void OnDownloadProgress(const std::string& extension_id,
int percent_downloaded) override;
void OnShutdown() override;
// extensions::ExtensionRegistryObserver overides:
void OnExtensionInstalled(content::BrowserContext* browser_context,
const extensions::Extension* extension,
bool is_update) override;
void OnShutdown(extensions::ExtensionRegistry* registry) override;
Profile* profile_;
const std::string app_id_;
const GURL icon_url_;
const bool is_paid_;
extensions::Manifest::Type item_type_;
gfx::ImageSkia icon_;
AppListControllerDelegate* controller_;
extensions::InstallTracker* install_tracker_; // Not owned.
extensions::ExtensionRegistry* extension_registry_; // Not owned.
base::WeakPtrFactory<WebstoreResult> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(WebstoreResult);
};
} // namespace app_list
#endif // CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_WEBSTORE_RESULT_H_
......@@ -2055,7 +2055,6 @@ test("browser_tests") {
sources += [
"../browser/ui/app_list/app_list_client_impl_browsertest.cc",
"../browser/ui/app_list/chrome_app_list_model_updater_browsertest.cc",
"../browser/ui/app_list/search/webstore/webstore_provider_browsertest.cc",
]
}
if (enable_service_discovery) {
......
......@@ -71,10 +71,6 @@ bool IsArcAvailable() {
base::FeatureList::IsEnabled(kEnableArcFeature));
}
bool IsWebstoreSearchEnabled() {
return false;
}
bool ShouldArcAlwaysStart() {
const auto* command_line = base::CommandLine::ForCurrentProcess();
if (!command_line->HasSwitch(chromeos::switches::kArcStartMode))
......
......@@ -36,10 +36,6 @@ namespace arc {
// check, so it is ok to access them directly.
bool IsArcAvailable();
// Returns true if ARC is not installed and the current device is not supported
// to run ARC.
bool IsWebstoreSearchEnabled();
// Returns true if ARC should always start within the primary user session
// (opted in user or not), and other supported mode such as guest and Kiosk
// mode.
......
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