Commit 374c7b23 authored by rkc@chromium.org's avatar rkc@chromium.org

Implement people search.

Implement a people search provider that uses the Google+ People Search endpoint.

R=xiyuan@chromium.org
BUG=267208

Review URL: https://chromiumcodereview.appspot.com/23874015

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@221642 0039d316-1c4b-4281-b951-d872f2087c98
parent 28124e2b
...@@ -6373,6 +6373,12 @@ Keep your key file in a safe place. You will need it to create new versions of y ...@@ -6373,6 +6373,12 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_FLAGS_PASSWORD_AUTOFILL_PUBLIC_SUFFIX_DOMAIN_MATCHING_DESCRIPTION" desc="Description of flag to enable or disable public suffix domain matching for autofill of passwords."> <message name="IDS_FLAGS_PASSWORD_AUTOFILL_PUBLIC_SUFFIX_DOMAIN_MATCHING_DESCRIPTION" desc="Description of flag to enable or disable public suffix domain matching for autofill of passwords.">
Enable or disable a feature which allows the user to select username/password combinations for domains that match the same public suffix registry domain. Enable or disable a feature which allows the user to select username/password combinations for domains that match the same public suffix registry domain.
</message> </message>
<message name="IDS_FLAGS_ENABLE_PEOPLE_SEARCH_NAME" desc="Name of the flag to enable people search.">
Enable people search.
</message>
<message name="IDS_FLAGS_ENABLE_PEOPLE_SEARCH_DESCRIPTION" desc="Description of flag to enable people search.">
Enable searching for people directly from the apps list search.
</message>
<message name="IDS_FLAGS_PERFORMANCE_MONITOR_GATHERING_NAME" desc="Name for the flag to enable Performance Monitor."> <message name="IDS_FLAGS_PERFORMANCE_MONITOR_GATHERING_NAME" desc="Name for the flag to enable Performance Monitor.">
Enable performance monitoring Enable performance monitoring
</message> </message>
......
...@@ -1205,6 +1205,13 @@ const Experiment kExperiments[] = { ...@@ -1205,6 +1205,13 @@ const Experiment kExperiments[] = {
kOsDesktop, kOsDesktop,
SINGLE_VALUE_TYPE(switches::kEnablePasswordGeneration) SINGLE_VALUE_TYPE(switches::kEnablePasswordGeneration)
}, },
{
"enable-people-search",
IDS_FLAGS_ENABLE_PEOPLE_SEARCH_NAME,
IDS_FLAGS_ENABLE_PEOPLE_SEARCH_DESCRIPTION,
kOsMac | kOsWin | kOsCrOS,
SINGLE_VALUE_TYPE(switches::kEnablePeopleSearch)
},
{ {
"password-autofill-public-suffix-domain-matching", "password-autofill-public-suffix-domain-matching",
IDS_FLAGS_PASSWORD_AUTOFILL_PUBLIC_SUFFIX_DOMAIN_MATCHING_NAME, IDS_FLAGS_PASSWORD_AUTOFILL_PUBLIC_SUFFIX_DOMAIN_MATCHING_NAME,
......
...@@ -23,6 +23,8 @@ enum ChromeSearchResultType { ...@@ -23,6 +23,8 @@ enum ChromeSearchResultType {
WEBSTORE_SEARCH_RESULT, WEBSTORE_SEARCH_RESULT,
// A result that opens a webstore search. // A result that opens a webstore search.
SEARCH_WEBSTORE_SEARCH_RESULT, SEARCH_WEBSTORE_SEARCH_RESULT,
// A result that opens a people search.
SEARCH_PEOPLE_SEARCH_RESULT,
SEARCH_RESULT_TYPE_BOUNDARY SEARCH_RESULT_TYPE_BOUNDARY
}; };
......
...@@ -72,11 +72,11 @@ void JSONResponseFetcher::OnURLFetchComplete( ...@@ -72,11 +72,11 @@ void JSONResponseFetcher::OnURLFetchComplete(
return; return;
} }
std::string webstore_json_data; std::string json_data;
fetcher->GetResponseAsString(&webstore_json_data); fetcher->GetResponseAsString(&json_data);
scoped_refptr<SafeJsonParser> parser = scoped_refptr<SafeJsonParser> parser =
new SafeJsonParser(webstore_json_data, new SafeJsonParser(json_data,
base::Bind( base::Bind(
&JSONResponseFetcher::OnJsonParseSuccess, &JSONResponseFetcher::OnJsonParseSuccess,
weak_factory_.GetWeakPtr()), weak_factory_.GetWeakPtr()),
......
...@@ -29,6 +29,8 @@ namespace app_list { ...@@ -29,6 +29,8 @@ namespace app_list {
// A class that fetches a JSON formatted response from a server and uses a // A class that fetches a JSON formatted response from a server and uses a
// sandboxed utility process to parse it to a DictionaryValue. // sandboxed utility process to parse it to a DictionaryValue.
// TODO(rkc): Add the ability to give control of handling http failures to
// the consumers of this class.
class JSONResponseFetcher : public net::URLFetcherDelegate { class JSONResponseFetcher : public net::URLFetcherDelegate {
public: public:
// Callback to pass back the parsed json dictionary returned from the server. // Callback to pass back the parsed json dictionary returned from the server.
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "chrome/browser/search/search.h"
#include "chrome/common/url_constants.h" #include "chrome/common/url_constants.h"
#include "url/gurl.h" #include "url/gurl.h"
...@@ -16,10 +17,12 @@ namespace app_list { ...@@ -16,10 +17,12 @@ namespace app_list {
namespace { namespace {
const int kWebserviceQueryThrottleIntrevalInMs = 100; const int kWebserviceQueryThrottleIntrevalInMs = 100;
const size_t kMinimumQueryLength = 3u;
} // namespace } // namespace
WebserviceSearchProvider::WebserviceSearchProvider() : use_throttling_(true) {} WebserviceSearchProvider::WebserviceSearchProvider(Profile* profile)
: profile_(profile), use_throttling_(true) {}
WebserviceSearchProvider::~WebserviceSearchProvider() {} WebserviceSearchProvider::~WebserviceSearchProvider() {}
...@@ -36,6 +39,18 @@ void WebserviceSearchProvider::StartThrottledQuery( ...@@ -36,6 +39,18 @@ void WebserviceSearchProvider::StartThrottledQuery(
last_keytyped_ = base::Time::Now(); last_keytyped_ = base::Time::Now();
} }
bool WebserviceSearchProvider::IsValidQuery(const 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) ||
!chrome::IsSuggestPrefEnabled(profile_)) {
return false;
}
return true;
}
// Returns whether or not the user's input string, |query|, might contain any // 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. // sensitive information, based purely on its value and not where it came from.
bool WebserviceSearchProvider::IsSensitiveInput(const string16& query) { bool WebserviceSearchProvider::IsSensitiveInput(const string16& query) {
......
...@@ -11,24 +11,34 @@ ...@@ -11,24 +11,34 @@
#include "base/timer/timer.h" #include "base/timer/timer.h"
#include "chrome/browser/ui/app_list/search/search_provider.h" #include "chrome/browser/ui/app_list/search/search_provider.h"
class Profile;
namespace app_list { namespace app_list {
// Helper class for webservice based searches. // Helper class for webservice based searches.
class WebserviceSearchProvider : public SearchProvider { class WebserviceSearchProvider : public SearchProvider {
public: public:
WebserviceSearchProvider(); explicit WebserviceSearchProvider(Profile* profile);
virtual ~WebserviceSearchProvider(); virtual ~WebserviceSearchProvider();
// Validate the query for privacy and size.
bool IsValidQuery(const string16& query);
// Start a query with throttling enabled.
void StartThrottledQuery(const base::Closure& start_query); void StartThrottledQuery(const base::Closure& start_query);
bool IsSensitiveInput(const string16& query);
void set_use_throttling(bool use) { use_throttling_ = use; } void set_use_throttling(bool use) { use_throttling_ = use; }
protected:
Profile* profile_;
private: private:
bool IsSensitiveInput(const string16& query);
// The timestamp when the last key event happened. // The timestamp when the last key event happened.
base::Time last_keytyped_; base::Time last_keytyped_;
// The timer to throttle QPS to the webstore search . // The timer to throttle QPS.
base::OneShotTimer<WebserviceSearchProvider> query_throttler_; base::OneShotTimer<WebserviceSearchProvider> query_throttler_;
// The flag for tests. It prevents the throttling If set to false. // The flag for tests. It prevents the throttling If set to false.
......
...@@ -20,6 +20,7 @@ namespace { ...@@ -20,6 +20,7 @@ namespace {
const size_t kMaxResults = 6; const size_t kMaxResults = 6;
const size_t kMaxMainGroupResults = 4; const size_t kMaxMainGroupResults = 4;
const size_t kMaxWebstoreResults = 2; const size_t kMaxWebstoreResults = 2;
const size_t kMaxPeopleResults = 2;
// A value to indicate no max number of results limit. // A value to indicate no max number of results limit.
const size_t kNoMaxResultsLimit = 0; const size_t kNoMaxResultsLimit = 0;
...@@ -171,9 +172,10 @@ Mixer::Mixer(AppListModel::SearchResults* ui_results) ...@@ -171,9 +172,10 @@ Mixer::Mixer(AppListModel::SearchResults* ui_results)
Mixer::~Mixer() {} Mixer::~Mixer() {}
void Mixer::Init() { void Mixer::Init() {
groups_.push_back(new Group(kMaxMainGroupResults, 2.0)); groups_.push_back(new Group(kMaxMainGroupResults, 3.0));
groups_.push_back(new Group(kNoMaxResultsLimit, 1.0)); groups_.push_back(new Group(kNoMaxResultsLimit, 2.0));
groups_.push_back(new Group(kMaxWebstoreResults, 0.0)); groups_.push_back(new Group(kMaxWebstoreResults, 1.0));
groups_.push_back(new Group(kMaxPeopleResults, 0.0));
} }
void Mixer::AddProviderToGroup(GroupId group, SearchProvider* provider) { void Mixer::AddProviderToGroup(GroupId group, SearchProvider* provider) {
...@@ -194,6 +196,9 @@ void Mixer::MixAndPublish(const KnownResults& known_results) { ...@@ -194,6 +196,9 @@ void Mixer::MixAndPublish(const KnownResults& known_results) {
results.insert(results.end(), results.insert(results.end(),
groups_[WEBSTORE_GROUP]->results().begin(), groups_[WEBSTORE_GROUP]->results().begin(),
groups_[WEBSTORE_GROUP]->results().end()); groups_[WEBSTORE_GROUP]->results().end());
results.insert(results.end(),
groups_[PEOPLE_GROUP]->results().begin(),
groups_[PEOPLE_GROUP]->results().end());
// Collapse duplicate apps from local and web store. // Collapse duplicate apps from local and web store.
RemoveDuplicates(&results); RemoveDuplicates(&results);
......
...@@ -28,6 +28,7 @@ class Mixer { ...@@ -28,6 +28,7 @@ class Mixer {
MAIN_GROUP = 0, MAIN_GROUP = 0,
OMNIBOX_GROUP = 1, OMNIBOX_GROUP = 1,
WEBSTORE_GROUP = 2, WEBSTORE_GROUP = 2,
PEOPLE_GROUP = 3,
}; };
explicit Mixer(AppListModel::SearchResults* ui_results); explicit Mixer(AppListModel::SearchResults* ui_results);
......
...@@ -84,12 +84,14 @@ class MixerTest : public testing::Test { ...@@ -84,12 +84,14 @@ class MixerTest : public testing::Test {
providers_.push_back(new TestSearchProvider("app")); providers_.push_back(new TestSearchProvider("app"));
providers_.push_back(new TestSearchProvider("omnibox")); providers_.push_back(new TestSearchProvider("omnibox"));
providers_.push_back(new TestSearchProvider("webstore")); providers_.push_back(new TestSearchProvider("webstore"));
providers_.push_back(new TestSearchProvider("people"));
mixer_.reset(new Mixer(results_.get())); mixer_.reset(new Mixer(results_.get()));
mixer_->Init(); mixer_->Init();
mixer_->AddProviderToGroup(Mixer::MAIN_GROUP, providers_[0]); mixer_->AddProviderToGroup(Mixer::MAIN_GROUP, providers_[0]);
mixer_->AddProviderToGroup(Mixer::OMNIBOX_GROUP, providers_[1]); mixer_->AddProviderToGroup(Mixer::OMNIBOX_GROUP, providers_[1]);
mixer_->AddProviderToGroup(Mixer::WEBSTORE_GROUP, providers_[2]); mixer_->AddProviderToGroup(Mixer::WEBSTORE_GROUP, providers_[2]);
mixer_->AddProviderToGroup(Mixer::PEOPLE_GROUP, providers_[3]);
} }
void RunQuery() { void RunQuery() {
......
// 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/people/people_provider.h"
#include <string>
#include "base/bind.h"
#include "base/callback.h"
#include "base/metrics/field_trial.h"
#include "base/strings/string_number_conversions.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/signin/profile_oauth2_token_service.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/ui/app_list/search/common/json_response_fetcher.h"
#include "chrome/browser/ui/app_list/search/people/people_result.h"
#include "google_apis/gaia/gaia_constants.h"
#include "net/base/url_util.h"
#include "url/gurl.h"
namespace app_list {
namespace {
const char kKeyItems[] = "items";
const char kKeyId[] = "person.id";
const char kKeyNames[] = "person.names";
const char kKeyDisplayName[] = "displayName";
const char kKeySortKeys[] = "person.sortKeys";
const char kKeyInteractionRank[] = "interactionRank";
const char kKeyImages[] = "person.images";
const char kKeyUrl[] = "url";
const char kAccessTokenField[] = "access_token";
const char kQueryField[] = "query";
const char kPeopleSearchUrl[] =
"https://www.googleapis.com/plus/v2whitelisted/people/autocomplete";
// OAuth2 scope for access to the Google+ People Search API.
const char kPeopleSearchOAuth2Scope[] =
"https://www.googleapis.com/auth/plus.peopleapi.readwrite";
// Get's the value associated with the key in the first dictionary in the list.
std::string GetFirstValue(const ListValue& list, const char key[]) {
ListValue::const_iterator it = list.begin();
if (it == list.end())
return std::string();
base::DictionaryValue* dict;
if (!(*it)->GetAsDictionary(&dict))
return std::string();
std::string value;
if (!dict || !dict->GetString(key, &value))
return std::string();
return value;
}
} // namespace
PeopleProvider::PeopleProvider(Profile* profile)
: WebserviceSearchProvider(profile),
people_search_url_(kPeopleSearchUrl),
skip_request_token_for_test_(false) {
oauth2_scope_.insert(kPeopleSearchOAuth2Scope);
}
PeopleProvider::~PeopleProvider() {}
void PeopleProvider::Start(const base::string16& query) {
ClearResults();
if (!IsValidQuery(query)) {
query_.clear();
return;
}
query_ = UTF16ToUTF8(query);
if (!people_search_) {
people_search_.reset(new JSONResponseFetcher(
base::Bind(&PeopleProvider::OnPeopleSearchFetched,
base::Unretained(this)),
profile_->GetRequestContext()));
}
if (!skip_request_token_for_test_) {
// We start with reqesting the access token. Once the token is fetched,
// we'll create the full query URL and fetch it.
StartThrottledQuery(base::Bind(&PeopleProvider::RequestAccessToken,
base::Unretained(this)));
} else {
// Running in a test, skip requesting the access token, straight away
// start our query.
StartThrottledQuery(base::Bind(&PeopleProvider::StartQuery,
base::Unretained(this)));
}
}
void PeopleProvider::Stop() {
if (people_search_)
people_search_->Stop();
}
void PeopleProvider::OnGetTokenSuccess(
const OAuth2TokenService::Request* request,
const std::string& access_token,
const base::Time& expiration_time) {
DCHECK_EQ(access_token_request_, request);
access_token_request_.reset();
access_token_ = access_token;
StartQuery();
}
void PeopleProvider::OnGetTokenFailure(
const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) {
DCHECK_EQ(access_token_request_, request);
access_token_request_.reset();
}
void PeopleProvider::RequestAccessToken() {
// Only one active request at a time.
if (access_token_request_ != NULL)
return;
OAuth2TokenService* token_service =
ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
access_token_request_ = token_service->StartRequest(oauth2_scope_, this);
}
GURL PeopleProvider::GetQueryUrl(const std::string& query) {
GURL people_search_url = people_search_url_;
people_search_url = net::AppendQueryParameter(people_search_url,
kAccessTokenField,
access_token_);
people_search_url = net::AppendQueryParameter(people_search_url,
kQueryField,
query);
return people_search_url;
}
void PeopleProvider::StartQuery() {
// |query_| can be NULL when the query is scheduled but then canceled.
if (!people_search_ || query_.empty())
return;
GURL url = GetQueryUrl(query_);
people_search_->Start(url);
}
void PeopleProvider::OnPeopleSearchFetched(
scoped_ptr<base::DictionaryValue> json) {
ProcessPeopleSearchResults(json.get());
if (!people_search_fetched_callback_.is_null())
people_search_fetched_callback_.Run();
}
void PeopleProvider::ProcessPeopleSearchResults(
const base::DictionaryValue* json) {
const base::ListValue* item_list = NULL;
if (!json ||
!json->GetList(kKeyItems, &item_list) ||
!item_list ||
item_list->empty()) {
return;
}
ClearResults();
for (ListValue::const_iterator it = item_list->begin();
it != item_list->end();
++it) {
const base::DictionaryValue* dict;
if (!(*it)->GetAsDictionary(&dict))
continue;
scoped_ptr<ChromeSearchResult> result(CreateResult(*dict));
if (!result)
continue;
Add(result.Pass());
}
}
scoped_ptr<ChromeSearchResult> PeopleProvider::CreateResult(
const base::DictionaryValue& dict) {
scoped_ptr<ChromeSearchResult> result;
std::string id;
if (!dict.GetString(kKeyId, &id))
return result.Pass();
// Get the display name.
const base::ListValue* names;
if (!dict.GetList(kKeyNames, &names))
return result.Pass();
std::string display_name;
display_name = GetFirstValue(*names, kKeyDisplayName);
// Get the interaction rank.
const base::DictionaryValue* sort_keys;
if (!dict.GetDictionary(kKeySortKeys, &sort_keys))
return result.Pass();
std::string interaction_rank_string;
if (!sort_keys->GetString(kKeyInteractionRank, &interaction_rank_string))
return result.Pass();
double interaction_rank;
if (!base::StringToDouble(interaction_rank_string, &interaction_rank))
return result.Pass();
// If there has been no interaction with this user, the result
// is meaningless, hence discard it.
if (interaction_rank == 0.0)
return result.Pass();
// Get the image URL.
const base::ListValue* images;
if (!dict.GetList(kKeyImages, &images))
return result.Pass();
std::string image_url_string;
image_url_string = GetFirstValue(*images, kKeyUrl);
if (id.empty() ||
display_name.empty() ||
interaction_rank_string.empty() ||
image_url_string.empty()) {
return result.Pass();
}
GURL image_url(image_url_string);
if (!image_url.is_valid())
return result.Pass();
result.reset(new PeopleResult(
profile_, id, display_name, interaction_rank, image_url));
return result.Pass();
}
void PeopleProvider::SetupForTest(
const base::Closure& people_search_fetched_callback,
const GURL& people_search_url) {
people_search_fetched_callback_ = people_search_fetched_callback;
people_search_url_ = people_search_url;
skip_request_token_for_test_ = true;
}
} // 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_PEOPLE_PEOPLE_PROVIDER_H_
#define CHROME_BROWSER_UI_APP_LIST_SEARCH_PEOPLE_PEOPLE_PROVIDER_H_
#include "base/basictypes.h"
#include "base/callback_forward.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/ui/app_list/search/common/webservice_search_provider.h"
#include "google_apis/gaia/oauth2_token_service.h"
#include "url/gurl.h"
class AppListControllerDelegate;
namespace base {
class DictionaryValue;
}
namespace app_list {
namespace test {
class PeopleProviderTest;
}
class ChromeSearchResult;
class JSONResponseFetcher;
// PeopleProvider 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 PeopleProvider : public WebserviceSearchProvider,
public OAuth2TokenService::Consumer {
public:
explicit PeopleProvider(Profile* profile);
virtual ~PeopleProvider();
// SearchProvider overrides:
virtual void Start(const base::string16& query) OVERRIDE;
virtual void Stop() OVERRIDE;
// OAuth2TokenService::Consumer overrides:
virtual void OnGetTokenSuccess(
const OAuth2TokenService::Request* request,
const std::string& access_token,
const base::Time& expiration_time) OVERRIDE;
virtual void OnGetTokenFailure(
const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) OVERRIDE;
private:
friend class app_list::test::PeopleProviderTest;
// Start a request for getting the access token for people search.
void RequestAccessToken();
// Invalidate our existing token so a new one can be fetched.
void InvalidateToken();
// Get the full people search query URL. This URL includes the OAuth refresh
// token for authenticating the current user.
GURL GetQueryUrl(const std::string& query);
// Start the search request with |query_|.
void StartQuery();
void OnPeopleSearchFetched(scoped_ptr<base::DictionaryValue> json);
void ProcessPeopleSearchResults(const base::DictionaryValue* json);
scoped_ptr<ChromeSearchResult> CreateResult(
const base::DictionaryValue& dict);
// Setup the various variables that we override for testing.
void SetupForTest(const base::Closure& people_search_fetched_callback,
const GURL& people_search_url);
scoped_ptr<JSONResponseFetcher> people_search_;
base::Closure people_search_fetched_callback_;
std::string access_token_;
scoped_ptr<OAuth2TokenService::Request> access_token_request_;
OAuth2TokenService::ScopeSet oauth2_scope_;
// The current query.
std::string query_;
GURL people_search_url_;
bool skip_request_token_for_test_;
DISALLOW_COPY_AND_ASSIGN(PeopleProvider);
};
} // namespace app_list
#endif // CHROME_BROWSER_UI_APP_LIST_SEARCH_PEOPLE_PEOPLE_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 <string>
#include "base/basictypes.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/app_list/search/chrome_search_result.h"
#include "chrome/browser/ui/app_list/search/people/people_provider.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "content/public/browser/browser_thread.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
using content::BrowserThread;
using net::test_server::BasicHttpResponse;
using net::test_server::HttpRequest;
using net::test_server::HttpResponse;
using net::test_server::EmbeddedTestServer;
namespace app_list {
namespace test {
namespace {
// Mock results.
const char kOneResult[] = "{"
"\"items\":["
"{"
"\"person\" : {"
"\"id\": \"1\","
"\"names\" : [{"
"\"displayName\": \"first person\""
"}],"
"\"images\" : [{"
"\"url\": \"http://host/icon\""
"}],"
"\"sortKeys\" : {"
"\"interactionRank\": \"0.98\""
"}"
"}"
"}"
"]}";
const char kThreeValidResults[] = "{"
"\"items\":["
"{"
"\"person\" : {"
"\"id\": \"1\","
"\"names\" : [{"
"\"displayName\": \"first person\""
"}],"
"\"images\" : [{"
"\"url\": \"http://host/icon\""
"}],"
"\"sortKeys\" : {"
"\"interactionRank\": \"0.98\""
"}"
"}"
"},"
"{"
"\"person\" : {"
"\"id\": \"2\","
"\"names\" : [{"
"\"displayName\": \"second person\""
"}],"
"\"images\" : [{"
"\"url\": \"http://host/icon\""
"}],"
"\"sortKeys\" : {"
"\"interactionRank\": \"0.84\""
"}"
"}"
"},"
"{"
"\"person\" : {"
"\"id\": \"3\","
"\"names\" : [{"
"\"displayName\": \"third person\""
"}],"
"\"images\" : [{"
"\"url\": \"http://host/icon\""
"}],"
"\"sortKeys\" : {"
"\"interactionRank\": \"0.67\""
"}"
"}"
"},"
"{"
"\"person\" : {"
"\"id\": \"4\","
"\"names\" : [{"
"\"displayName\": \"fourth person\""
"}],"
"\"images\" : [{"
"\"url\": \"http://host/icon\""
"}],"
"\"sortKeys\" : {"
"\"interactionRank\": \"0.0\""
"}"
"}"
"},"
"{"
"\"person\" : {"
"\"id\": \"5\","
"\"names\" : [{"
"\"displayName\": \"fifth person\""
"}],"
// Images field is missing on purpose.
"\"sortKeys\" : {"
"\"interactionRank\": \"0.98\""
"}"
"}"
"}"
"]}";
} // namespace
class PeopleProviderTest : public InProcessBrowserTest {
public:
PeopleProviderTest() {}
virtual ~PeopleProviderTest() {}
// InProcessBrowserTest overrides:
virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
command_line->AppendSwitch(switches::kEnablePeopleSearch);
}
virtual void SetUpOnMainThread() OVERRIDE {
test_server_.reset(new EmbeddedTestServer(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)));
ASSERT_TRUE(test_server_->InitializeAndWaitUntilReady());
test_server_->RegisterRequestHandler(
base::Bind(&PeopleProviderTest::HandleRequest,
base::Unretained(this)));
people_provider_.reset(new PeopleProvider(
ProfileManager::GetDefaultProfile()));
people_provider_->SetupForTest(
base::Bind(&PeopleProviderTest::OnSearchResultsFetched,
base::Unretained(this)),
test_server_->base_url());
people_provider_->set_use_throttling(false);
}
virtual void CleanUpOnMainThread() OVERRIDE {
EXPECT_TRUE(test_server_->ShutdownAndWaitUntilComplete());
test_server_.reset();
}
std::string RunQuery(const std::string& query,
const std::string& mock_server_response) {
people_provider_->Start(UTF8ToUTF16(query));
if (people_provider_->people_search_ && !mock_server_response.empty()) {
mock_server_response_ = mock_server_response;
DCHECK(!run_loop_);
run_loop_.reset(new base::RunLoop);
run_loop_->Run();
run_loop_.reset();
mock_server_response_.clear();
}
people_provider_->Stop();
return GetResults();
}
std::string GetResults() const {
std::string results;
for (SearchProvider::Results::const_iterator it =
people_provider_->results().begin();
it != people_provider_->results().end();
++it) {
if (!results.empty())
results += ',';
results += UTF16ToUTF8((*it)->title());
}
return results;
}
PeopleProvider* people_provider() { return people_provider_.get(); }
private:
scoped_ptr<HttpResponse> HandleRequest(const HttpRequest& request) {
scoped_ptr<BasicHttpResponse> response(new BasicHttpResponse);
response->set_code(net::HTTP_OK);
response->set_content(mock_server_response_);
return response.PassAs<HttpResponse>();
}
void OnSearchResultsFetched() {
if (run_loop_)
run_loop_->Quit();
}
scoped_ptr<EmbeddedTestServer> test_server_;
scoped_ptr<base::RunLoop> run_loop_;
std::string mock_server_response_;
scoped_ptr<PeopleProvider> people_provider_;
DISALLOW_COPY_AND_ASSIGN(PeopleProviderTest);
};
IN_PROC_BROWSER_TEST_F(PeopleProviderTest, Basic) {
struct {
const char* query;
const char* mock_server_response;
const char* expected_results_content;
} kTestCases[] = {
{"first", kOneResult, "first person" },
{"person", kThreeValidResults, "first person,second person,third person" },
};
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
EXPECT_EQ(kTestCases[i].expected_results_content,
RunQuery(kTestCases[i].query,
kTestCases[i].mock_server_response))
<< "Case " << i << ": q=" << kTestCases[i].query;
}
}
IN_PROC_BROWSER_TEST_F(PeopleProviderTest, NoSearchForSensitiveData) {
// None of the following input strings should be accepted because they may
// contain private data.
const char* inputs[] = {
// file: scheme is bad.
"file://filename",
"FILE://filename",
// URLs with usernames, ports, queries or refs are bad.
"http://username:password@hostname/",
"http://www.example.com:1000",
"http://foo:1000",
"http://hostname/?query=q",
"http://hostname/path#ref",
// A https URL with path is bad.
"https://hostname/path",
};
for (size_t i = 0; i < arraysize(inputs); ++i)
EXPECT_EQ("", RunQuery(inputs[i], kOneResult));
}
IN_PROC_BROWSER_TEST_F(PeopleProviderTest, NoSearchForShortQueries) {
EXPECT_EQ("", RunQuery("f", kOneResult));
EXPECT_EQ("", RunQuery("fi", kOneResult));
EXPECT_EQ("first person", RunQuery("fir", kOneResult));
}
} // namespace test
} // 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.
#include "chrome/browser/ui/app_list/search/people/people_result.h"
#include <vector>
#include "base/bind.h"
#include "base/memory/ref_counted.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/app_list/search/common/url_icon_source.h"
#include "grit/theme_resources.h"
#include "ui/base/l10n/l10n_util.h"
namespace {
const int kIconSize = 32;
} // namespace
namespace app_list {
PeopleResult::PeopleResult(Profile* profile,
const std::string& id,
const std::string& display_name,
double interaction_rank,
const GURL& image_url)
: profile_(profile),
id_(id),
display_name_(display_name),
interaction_rank_(interaction_rank),
image_url_(image_url),
weak_factory_(this) {
set_id(id_);
set_title(UTF8ToUTF16(display_name_));
set_relevance(interaction_rank_);
image_ = gfx::ImageSkia(
new UrlIconSource(base::Bind(&PeopleResult::OnIconLoaded,
weak_factory_.GetWeakPtr()),
profile_->GetRequestContext(),
image_url_,
kIconSize,
IDR_PROFILE_PICTURE_LOADING),
gfx::Size(kIconSize, kIconSize));
SetIcon(image_);
}
PeopleResult::~PeopleResult() {
}
void PeopleResult::Open(int event_flags) {
// TODO(rkc): Navigate to the person's profile?
}
void PeopleResult::InvokeAction(int action_index, int event_flags) {
DCHECK_EQ(0, action_index);
// TODO(rkc): Decide what to do here.
}
scoped_ptr<ChromeSearchResult> PeopleResult::Duplicate() {
return scoped_ptr<ChromeSearchResult>(new PeopleResult(profile_, id_,
display_name_,
interaction_rank_,
image_url_)).Pass();
}
void PeopleResult::OnIconLoaded() {
// 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 = image_.image_reps();
for (size_t i = 0; i < image_reps.size(); ++i)
image_.RemoveRepresentation(image_reps[i].scale_factor());
SetIcon(image_);
}
ChromeSearchResultType PeopleResult::GetType() {
return SEARCH_PEOPLE_SEARCH_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_PEOPLE_PEOPLE_RESULT_H_
#define CHROME_BROWSER_UI_APP_LIST_SEARCH_PEOPLE_PEOPLE_RESULT_H_
#include <string>
#include "base/basictypes.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/ui/app_list/search/chrome_search_result.h"
#include "url/gurl.h"
class Profile;
namespace app_list {
class PeopleResult : public ChromeSearchResult {
public:
PeopleResult(Profile* profile,
const std::string& id,
const std::string& display_name,
double interaction_rank,
const GURL& image_url);
virtual ~PeopleResult();
// ChromeSearchResult overides:
virtual void Open(int event_flags) OVERRIDE;
virtual void InvokeAction(int action_index, int event_flags) OVERRIDE;
virtual scoped_ptr<ChromeSearchResult> Duplicate() OVERRIDE;
virtual ChromeSearchResultType GetType() OVERRIDE;
private:
void SetDefaultDetails();
void OnIconLoaded();
Profile* profile_;
const std::string id_;
const std::string display_name_;
const double interaction_rank_;
const GURL image_url_;
gfx::ImageSkia image_;
base::WeakPtrFactory<PeopleResult> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(PeopleResult);
};
} // namespace app_list
#endif // CHROME_BROWSER_UI_APP_LIST_SEARCH_PEOPLE_PEOPLE_RESULT_H_
...@@ -19,8 +19,10 @@ ...@@ -19,8 +19,10 @@
#include "chrome/browser/ui/app_list/search/history.h" #include "chrome/browser/ui/app_list/search/history.h"
#include "chrome/browser/ui/app_list/search/history_factory.h" #include "chrome/browser/ui/app_list/search/history_factory.h"
#include "chrome/browser/ui/app_list/search/omnibox_provider.h" #include "chrome/browser/ui/app_list/search/omnibox_provider.h"
#include "chrome/browser/ui/app_list/search/people/people_provider.h"
#include "chrome/browser/ui/app_list/search/search_provider.h" #include "chrome/browser/ui/app_list/search/search_provider.h"
#include "chrome/browser/ui/app_list/search/webstore_provider.h" #include "chrome/browser/ui/app_list/search/webstore/webstore_provider.h"
#include "chrome/common/chrome_switches.h"
#include "content/public/browser/user_metrics.h" #include "content/public/browser/user_metrics.h"
#include "grit/generated_resources.h" #include "grit/generated_resources.h"
#include "grit/theme_resources.h" #include "grit/theme_resources.h"
...@@ -64,6 +66,11 @@ void SearchController::Init() { ...@@ -64,6 +66,11 @@ void SearchController::Init() {
new OmniboxProvider(profile_)).Pass()); new OmniboxProvider(profile_)).Pass());
AddProvider(Mixer::WEBSTORE_GROUP, scoped_ptr<SearchProvider>( AddProvider(Mixer::WEBSTORE_GROUP, scoped_ptr<SearchProvider>(
new WebstoreProvider(profile_, list_controller_)).Pass()); new WebstoreProvider(profile_, list_controller_)).Pass());
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnablePeopleSearch)) {
AddProvider(Mixer::PEOPLE_GROUP, scoped_ptr<SearchProvider>(
new PeopleProvider(profile_)).Pass());
}
} }
void SearchController::Start() { void SearchController::Start() {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chrome/browser/ui/app_list/search/webstore_cache.h" #include "chrome/browser/ui/app_list/search/webstore/webstore_cache.h"
#include "base/values.h" #include "base/values.h"
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_CACHE_H_ #ifndef CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_WEBSTORE_CACHE_H_
#define CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_CACHE_H_ #define CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_WEBSTORE_CACHE_H_
#include <utility> #include <utility>
...@@ -48,4 +48,4 @@ class WebstoreCache { ...@@ -48,4 +48,4 @@ class WebstoreCache {
} // namespace app_list } // namespace app_list
#endif // CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_CACHE_H_ #endif // CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_WEBSTORE_CACHE_H_
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chrome/browser/ui/app_list/search/webstore_installer.h" #include "chrome/browser/ui/app_list/search/webstore/webstore_installer.h"
#include "chrome/browser/extensions/extension_install_prompt.h" #include "chrome/browser/extensions/extension_install_prompt.h"
#include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_finder.h"
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_INSTALLER_H_ #ifndef CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_WEBSTORE_INSTALLER_H_
#define CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_INSTALLER_H_ #define CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_WEBSTORE_INSTALLER_H_
#include <string> #include <string>
...@@ -46,4 +46,4 @@ class WebstoreInstaller : public extensions::WebstoreStartupInstaller, ...@@ -46,4 +46,4 @@ class WebstoreInstaller : public extensions::WebstoreStartupInstaller,
} // namespace app_list } // namespace app_list
#endif // CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_INSTALLER_H_ #endif // CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_WEBSTORE_INSTALLER_H_
...@@ -2,11 +2,12 @@ ...@@ -2,11 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chrome/browser/ui/app_list/search/webstore_provider.h" #include "chrome/browser/ui/app_list/search/webstore/webstore_provider.h"
#include <string> #include <string>
#include "base/bind.h" #include "base/bind.h"
#include "base/callback.h"
#include "base/metrics/field_trial.h" #include "base/metrics/field_trial.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/values.h" #include "base/values.h"
...@@ -15,7 +16,7 @@ ...@@ -15,7 +16,7 @@
#include "chrome/browser/search/search.h" #include "chrome/browser/search/search.h"
#include "chrome/browser/ui/app_list/search/common/json_response_fetcher.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/search_webstore_result.h"
#include "chrome/browser/ui/app_list/search/webstore_result.h" #include "chrome/browser/ui/app_list/search/webstore/webstore_result.h"
#include "chrome/common/extensions/extension_constants.h" #include "chrome/common/extensions/extension_constants.h"
#include "url/gurl.h" #include "url/gurl.h"
...@@ -40,29 +41,19 @@ bool UseWebstoreSearch() { ...@@ -40,29 +41,19 @@ bool UseWebstoreSearch() {
WebstoreProvider::WebstoreProvider(Profile* profile, WebstoreProvider::WebstoreProvider(Profile* profile,
AppListControllerDelegate* controller) AppListControllerDelegate* controller)
: profile_(profile), : WebserviceSearchProvider(profile),
controller_(controller) {} controller_(controller){}
WebstoreProvider::~WebstoreProvider() {} WebstoreProvider::~WebstoreProvider() {}
void WebstoreProvider::Start(const base::string16& query) { void WebstoreProvider::Start(const base::string16& query) {
ClearResults(); ClearResults();
if (!IsValidQuery(query)) {
// If |query| contains sensitive data, bail out and do not create the place
// holder "search-web-store" result.
if (IsSensitiveInput(query)) {
query_.clear();
return;
}
const std::string query_utf8 = UTF16ToUTF8(query);
if (query_utf8.size() < kMinimumQueryLength) {
query_.clear(); query_.clear();
return; return;
} }
query_ = query_utf8; query_ = UTF16ToUTF8(query);
const base::DictionaryValue* cached_result = cache_.Get(query_); const base::DictionaryValue* cached_result = cache_.Get(query_);
if (cached_result) { if (cached_result) {
ProcessWebstoreSearchResults(cached_result); ProcessWebstoreSearchResults(cached_result);
...@@ -71,7 +62,7 @@ void WebstoreProvider::Start(const base::string16& query) { ...@@ -71,7 +62,7 @@ void WebstoreProvider::Start(const base::string16& query) {
return; return;
} }
if (UseWebstoreSearch() && chrome::IsSuggestPrefEnabled(profile_)) { if (UseWebstoreSearch()) {
if (!webstore_search_) { if (!webstore_search_) {
webstore_search_.reset(new JSONResponseFetcher( webstore_search_.reset(new JSONResponseFetcher(
base::Bind(&WebstoreProvider::OnWebstoreSearchFetched, base::Bind(&WebstoreProvider::OnWebstoreSearchFetched,
...@@ -86,7 +77,7 @@ void WebstoreProvider::Start(const base::string16& query) { ...@@ -86,7 +77,7 @@ void WebstoreProvider::Start(const base::string16& query) {
// Add a placeholder result which when clicked will run the user's query in a // 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. // browser. This placeholder is removed when the search results arrive.
Add(scoped_ptr<ChromeSearchResult>( Add(scoped_ptr<ChromeSearchResult>(
new SearchWebstoreResult(profile_, query_utf8)).Pass()); new SearchWebstoreResult(profile_, query_)).Pass());
} }
void WebstoreProvider::Stop() { void WebstoreProvider::Stop() {
......
...@@ -2,19 +2,16 @@ ...@@ -2,19 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_PROVIDER_H_ #ifndef CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_WEBSTORE_PROVIDER_H_
#define CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_PROVIDER_H_ #define CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_WEBSTORE_PROVIDER_H_
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/callback.h" #include "base/callback_forward.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chrome/browser/ui/app_list/search/common/webservice_search_provider.h" #include "chrome/browser/ui/app_list/search/common/webservice_search_provider.h"
#include "chrome/browser/ui/app_list/search/webstore_cache.h" #include "chrome/browser/ui/app_list/search/webstore/webstore_cache.h"
class AppListControllerDelegate; class AppListControllerDelegate;
class Profile;
namespace base { namespace base {
class DictionaryValue; class DictionaryValue;
...@@ -56,7 +53,6 @@ class WebstoreProvider : public WebserviceSearchProvider{ ...@@ -56,7 +53,6 @@ class WebstoreProvider : public WebserviceSearchProvider{
webstore_search_fetched_callback_ = callback; webstore_search_fetched_callback_ = callback;
} }
Profile* profile_;
AppListControllerDelegate* controller_; AppListControllerDelegate* controller_;
scoped_ptr<JSONResponseFetcher> webstore_search_; scoped_ptr<JSONResponseFetcher> webstore_search_;
base::Closure webstore_search_fetched_callback_; base::Closure webstore_search_fetched_callback_;
...@@ -65,12 +61,6 @@ class WebstoreProvider : public WebserviceSearchProvider{ ...@@ -65,12 +61,6 @@ class WebstoreProvider : public WebserviceSearchProvider{
// input session. // input session.
WebstoreCache cache_; WebstoreCache cache_;
// The timestamp when the last key event happened.
base::Time last_keytyped_;
// The timer to throttle QPS to the webstore search .
base::OneShotTimer<WebstoreProvider> query_throttler_;
// The current query. // The current query.
std::string query_; std::string query_;
...@@ -79,4 +69,4 @@ class WebstoreProvider : public WebserviceSearchProvider{ ...@@ -79,4 +69,4 @@ class WebstoreProvider : public WebserviceSearchProvider{
} // namespace app_list } // namespace app_list
#endif // CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_PROVIDER_H_ #endif // CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_WEBSTORE_PROVIDER_H_
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/app_list/search/chrome_search_result.h" #include "chrome/browser/ui/app_list/search/chrome_search_result.h"
#include "chrome/browser/ui/app_list/search/webstore_provider.h" #include "chrome/browser/ui/app_list/search/webstore/webstore_provider.h"
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
#include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/in_process_browser_test.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chrome/browser/ui/app_list/search/webstore_result.h" #include "chrome/browser/ui/app_list/search/webstore/webstore_result.h"
#include <vector> #include <vector>
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/app_list/app_list_controller_delegate.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/common/url_icon_source.h"
#include "chrome/browser/ui/app_list/search/webstore_installer.h" #include "chrome/browser/ui/app_list/search/webstore/webstore_installer.h"
#include "chrome/browser/ui/browser_navigator.h" #include "chrome/browser/ui/browser_navigator.h"
#include "chrome/browser/ui/extensions/application_launch.h" #include "chrome/browser/ui/extensions/application_launch.h"
#include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension.h"
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_RESULT_H_ #ifndef CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_WEBSTORE_RESULT_H_
#define CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_RESULT_H_ #define CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_WEBSTORE_RESULT_H_
#include <string> #include <string>
...@@ -87,4 +87,4 @@ class WebstoreResult : public ChromeSearchResult, ...@@ -87,4 +87,4 @@ class WebstoreResult : public ChromeSearchResult,
} // namespace app_list } // namespace app_list
#endif // CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_RESULT_H_ #endif // CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_WEBSTORE_RESULT_H_
...@@ -153,6 +153,10 @@ ...@@ -153,6 +153,10 @@
'browser/ui/app_list/search/mixer.h', 'browser/ui/app_list/search/mixer.h',
'browser/ui/app_list/search/omnibox_provider.cc', 'browser/ui/app_list/search/omnibox_provider.cc',
'browser/ui/app_list/search/omnibox_provider.h', 'browser/ui/app_list/search/omnibox_provider.h',
'browser/ui/app_list/search/people/people_provider.cc',
'browser/ui/app_list/search/people/people_provider.h',
'browser/ui/app_list/search/people/people_result.cc',
'browser/ui/app_list/search/people/people_result.h',
'browser/ui/app_list/search/search_controller.cc', 'browser/ui/app_list/search/search_controller.cc',
'browser/ui/app_list/search/search_controller.h', 'browser/ui/app_list/search/search_controller.h',
'browser/ui/app_list/search/search_provider.cc', 'browser/ui/app_list/search/search_provider.cc',
...@@ -167,14 +171,14 @@ ...@@ -167,14 +171,14 @@
'browser/ui/app_list/search/tokenized_string_char_iterator.h', 'browser/ui/app_list/search/tokenized_string_char_iterator.h',
'browser/ui/app_list/search/tokenized_string_match.cc', 'browser/ui/app_list/search/tokenized_string_match.cc',
'browser/ui/app_list/search/tokenized_string_match.h', 'browser/ui/app_list/search/tokenized_string_match.h',
'browser/ui/app_list/search/webstore_cache.cc', 'browser/ui/app_list/search/webstore/webstore_cache.cc',
'browser/ui/app_list/search/webstore_cache.h', 'browser/ui/app_list/search/webstore/webstore_cache.h',
'browser/ui/app_list/search/webstore_installer.cc', 'browser/ui/app_list/search/webstore/webstore_installer.cc',
'browser/ui/app_list/search/webstore_installer.h', 'browser/ui/app_list/search/webstore/webstore_installer.h',
'browser/ui/app_list/search/webstore_provider.cc', 'browser/ui/app_list/search/webstore/webstore_provider.cc',
'browser/ui/app_list/search/webstore_provider.h', 'browser/ui/app_list/search/webstore/webstore_provider.h',
'browser/ui/app_list/search/webstore_result.cc', 'browser/ui/app_list/search/webstore/webstore_result.cc',
'browser/ui/app_list/search/webstore_result.h', 'browser/ui/app_list/search/webstore/webstore_result.h',
'browser/ui/app_modal_dialogs/app_modal_dialog.cc', 'browser/ui/app_modal_dialogs/app_modal_dialog.cc',
'browser/ui/app_modal_dialogs/app_modal_dialog.h', 'browser/ui/app_modal_dialogs/app_modal_dialog.h',
'browser/ui/app_modal_dialogs/app_modal_dialog_queue.cc', 'browser/ui/app_modal_dialogs/app_modal_dialog_queue.cc',
......
...@@ -1576,7 +1576,8 @@ ...@@ -1576,7 +1576,8 @@
'browser/translate/translate_manager_browsertest.cc', 'browser/translate/translate_manager_browsertest.cc',
'browser/ui/app_list/app_list_controller_browsertest.cc', 'browser/ui/app_list/app_list_controller_browsertest.cc',
'browser/ui/app_list/app_list_service_mac_browsertest.mm', 'browser/ui/app_list/app_list_service_mac_browsertest.mm',
'browser/ui/app_list/search/webstore_provider_browsertest.cc', 'browser/ui/app_list/search/people/people_provider_browsertest.cc',
'browser/ui/app_list/search/webstore/webstore_provider_browsertest.cc',
'browser/ui/ash/caps_lock_delegate_chromeos_browsertest.cc', 'browser/ui/ash/caps_lock_delegate_chromeos_browsertest.cc',
'browser/ui/ash/chrome_shell_delegate_browsertest.cc', 'browser/ui/ash/chrome_shell_delegate_browsertest.cc',
'browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc', 'browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc',
......
...@@ -659,6 +659,9 @@ const char kEnablePanels[] = "enable-panels"; ...@@ -659,6 +659,9 @@ const char kEnablePanels[] = "enable-panels";
// account creation. // account creation.
const char kEnablePasswordGeneration[] = "enable-password-generation"; const char kEnablePasswordGeneration[] = "enable-password-generation";
// Enables searching for people from the apps list search box.
const char kEnablePeopleSearch[] = "enable-people-search";
// Disables the usage of Portable Native Client. // Disables the usage of Portable Native Client.
const char kDisablePnacl[] = "disable-pnacl"; const char kDisablePnacl[] = "disable-pnacl";
......
...@@ -192,6 +192,7 @@ extern const char kEnableOmniboxAutoCompletionForIme[]; ...@@ -192,6 +192,7 @@ extern const char kEnableOmniboxAutoCompletionForIme[];
extern const char kEnablePanels[]; extern const char kEnablePanels[];
extern const char kEnablePasswordAutofillPublicSuffixDomainMatching[]; extern const char kEnablePasswordAutofillPublicSuffixDomainMatching[];
extern const char kEnablePasswordGeneration[]; extern const char kEnablePasswordGeneration[];
extern const char kEnablePeopleSearch[];
extern const char kEnableProfiling[]; extern const char kEnableProfiling[];
extern const char kEnableQuic[]; extern const char kEnableQuic[];
extern const char kEnableQuicHttps[]; extern const char kEnableQuicHttps[];
......
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