diff options
author | Ben Murdoch <benm@google.com> | 2013-07-31 10:55:33 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2013-07-31 10:55:33 +0100 |
commit | d3868032626d59662ff73b372b5d584c1d144c53 (patch) | |
tree | b53968078879cdade155a2e869a58b2ec568a06d /chrome/browser | |
parent | e5b4422c968a7a35d5d4fbae38f8786f61e98bc8 (diff) | |
download | chromium_org-d3868032626d59662ff73b372b5d584c1d144c53.tar.gz |
Merge from Chromium at DEPS revision r214391
This commit was generated by merge_to_master.py.
Change-Id: Iad15fada300ebc6cf9cbcebfc484b1a5f5f372e5
Diffstat (limited to 'chrome/browser')
82 files changed, 1384 insertions, 631 deletions
diff --git a/chrome/browser/autocomplete/autocomplete_browsertest.cc b/chrome/browser/autocomplete/autocomplete_browsertest.cc index 1f43df561f..c38c19d64a 100644 --- a/chrome/browser/autocomplete/autocomplete_browsertest.cc +++ b/chrome/browser/autocomplete/autocomplete_browsertest.cc @@ -139,8 +139,9 @@ IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, MAYBE_Autocomplete) { OmniboxView* location_entry = location_bar->GetLocationEntry(); location_entry->model()->SetInputInProgress(true); autocomplete_controller->Start(AutocompleteInput( - ASCIIToUTF16("chrome"), string16::npos, string16(), GURL(), true, false, - true, AutocompleteInput::SYNCHRONOUS_MATCHES)); + ASCIIToUTF16("chrome"), string16::npos, string16(), GURL(), + AutocompleteInput::NEW_TAB_PAGE, true, false, true, + AutocompleteInput::SYNCHRONOUS_MATCHES)); EXPECT_TRUE(autocomplete_controller->done()); EXPECT_TRUE(location_bar->GetInputString().empty()); diff --git a/chrome/browser/autocomplete/autocomplete_classifier.cc b/chrome/browser/autocomplete/autocomplete_classifier.cc index 4eff86aa02..ae2f036bf7 100644 --- a/chrome/browser/autocomplete/autocomplete_classifier.cc +++ b/chrome/browser/autocomplete/autocomplete_classifier.cc @@ -54,7 +54,8 @@ void AutocompleteClassifier::Classify(const string16& text, DCHECK(!inside_classify_); base::AutoReset<bool> reset(&inside_classify_, true); controller_->Start(AutocompleteInput( - text, string16::npos, string16(), GURL(), true, prefer_keyword, + text, string16::npos, string16(), GURL(), + AutocompleteInput::INVALID_SPEC, true, prefer_keyword, allow_exact_keyword_match, AutocompleteInput::BEST_MATCH)); DCHECK(controller_->done()); const AutocompleteResult& result = controller_->result(); diff --git a/chrome/browser/autocomplete/autocomplete_controller.cc b/chrome/browser/autocomplete/autocomplete_controller.cc index 77f53f8040..ee39845872 100644 --- a/chrome/browser/autocomplete/autocomplete_controller.cc +++ b/chrome/browser/autocomplete/autocomplete_controller.cc @@ -303,12 +303,15 @@ void AutocompleteController::Stop(bool clear_result) { } } -void AutocompleteController::StartZeroSuggest(const GURL& url, - const string16& permanent_text) { +void AutocompleteController::StartZeroSuggest( + const GURL& url, + AutocompleteInput::PageClassification page_classification, + const string16& permanent_text) { if (zero_suggest_provider_ != NULL) { DCHECK(!in_start_); // We should not be already running a query. in_zero_suggest_ = true; - zero_suggest_provider_->StartZeroSuggest(url, permanent_text); + zero_suggest_provider_->StartZeroSuggest( + url, page_classification, permanent_text); } } diff --git a/chrome/browser/autocomplete/autocomplete_controller.h b/chrome/browser/autocomplete/autocomplete_controller.h index 5b06749fe7..8ae503af30 100644 --- a/chrome/browser/autocomplete/autocomplete_controller.h +++ b/chrome/browser/autocomplete/autocomplete_controller.h @@ -77,14 +77,13 @@ class AutocompleteController : public AutocompleteProviderListener { // If |clear_result| is true, the controller will also erase the result set. void Stop(bool clear_result); - // Begin asynchronously fetching zero-suggest suggestions for |url|. - // |user_text| is the text entered in the omnibox, which may be non-empty if - // the user previously focused in the omnibox during this interaction. - // |permanent_text| is the omnibox text for the current page. - // TODO(jered): Rip out |user_text| once the first match is decoupled from - // the current typing in the omnibox. - void StartZeroSuggest(const GURL& url, - const string16& permanent_text); + // Begin asynchronously fetching zero-suggest suggestions for |url| of + // classification |page_classification|. |permanent_text| is the omnibox + // text for the current page. + void StartZeroSuggest( + const GURL& url, + AutocompleteInput::PageClassification page_classification, + const string16& permanent_text); // Cancels any pending zero-suggest fetch. void StopZeroSuggest(); diff --git a/chrome/browser/autocomplete/autocomplete_input.cc b/chrome/browser/autocomplete/autocomplete_input.cc index 718cd9bd84..0edb4d9fa4 100644 --- a/chrome/browser/autocomplete/autocomplete_input.cc +++ b/chrome/browser/autocomplete/autocomplete_input.cc @@ -30,6 +30,7 @@ void AdjustCursorPositionIfNecessary(size_t num_leading_chars_removed, AutocompleteInput::AutocompleteInput() : cursor_position_(string16::npos), + current_page_classification_(AutocompleteInput::INVALID_SPEC), type_(INVALID), prevent_inline_autocomplete_(false), prefer_keyword_(false), @@ -37,16 +38,19 @@ AutocompleteInput::AutocompleteInput() matches_requested_(ALL_MATCHES) { } -AutocompleteInput::AutocompleteInput(const string16& text, - size_t cursor_position, - const string16& desired_tld, - const GURL& current_url, - bool prevent_inline_autocomplete, - bool prefer_keyword, - bool allow_exact_keyword_match, - MatchesRequested matches_requested) +AutocompleteInput::AutocompleteInput( + const string16& text, + size_t cursor_position, + const string16& desired_tld, + const GURL& current_url, + AutocompleteInput::PageClassification current_page_classification, + bool prevent_inline_autocomplete, + bool prefer_keyword, + bool allow_exact_keyword_match, + MatchesRequested matches_requested) : cursor_position_(cursor_position), current_url_(current_url), + current_page_classification_(current_page_classification), prevent_inline_autocomplete_(prevent_inline_autocomplete), prefer_keyword_(prefer_keyword), allow_exact_keyword_match_(allow_exact_keyword_match), @@ -507,6 +511,7 @@ void AutocompleteInput::Clear() { text_.clear(); cursor_position_ = string16::npos; current_url_ = GURL(); + current_page_classification_ = AutocompleteInput::INVALID_SPEC; type_ = INVALID; parts_ = url_parse::Parsed(); scheme_.clear(); diff --git a/chrome/browser/autocomplete/autocomplete_input.h b/chrome/browser/autocomplete/autocomplete_input.h index 9f9788464b..00708724e8 100644 --- a/chrome/browser/autocomplete/autocomplete_input.h +++ b/chrome/browser/autocomplete/autocomplete_input.h @@ -82,6 +82,11 @@ class AutocompleteInput { // Query refinement is only used by mobile ports, so only these set // |current_url| to a non-empty string. // + // |current_page_classification| represents the type of page the user is + // viewing and manner in which the user is accessing the omnibox; it's + // more than simply the URL. It includes, for example, whether the page + // is a search result page doing search term replacement or not. + // // |prevent_inline_autocomplete| is true if the generated result set should // not require inline autocomplete for the default match. This is difficult // to explain in the abstract; the practical use case is that after the user @@ -96,7 +101,7 @@ class AutocompleteInput { // the input string would be surprising or wrong, e.g. when highlighting text // in a page and telling the browser to search for it or navigate to it. This // parameter only applies to substituting keywords. - + // // If |matches_requested| is BEST_MATCH or SYNCHRONOUS_MATCHES the controller // asks the providers to only return matches which are synchronously // available, which should mean that all providers will be done immediately. @@ -104,6 +109,7 @@ class AutocompleteInput { size_t cursor_position, const string16& desired_tld, const GURL& current_url, + PageClassification current_page_classification, bool prevent_inline_autocomplete, bool prefer_keyword, bool allow_exact_keyword_match, @@ -166,6 +172,12 @@ class AutocompleteInput { // The current URL, or an invalid GURL if query refinement is not desired. const GURL& current_url() const { return current_url_; } + // The type of page that is currently behind displayed and how it is + // displayed (e.g., with search term replacement or without). + AutocompleteInput::PageClassification current_page_classification() const { + return current_page_classification_; + } + // The type of input supplied. Type type() const { return type_; } @@ -205,6 +217,7 @@ class AutocompleteInput { string16 text_; size_t cursor_position_; GURL current_url_; + AutocompleteInput::PageClassification current_page_classification_; Type type_; url_parse::Parsed parts_; string16 scheme_; diff --git a/chrome/browser/autocomplete/autocomplete_input_unittest.cc b/chrome/browser/autocomplete/autocomplete_input_unittest.cc index db7a1dd64d..9d7fcfd9d9 100644 --- a/chrome/browser/autocomplete/autocomplete_input_unittest.cc +++ b/chrome/browser/autocomplete/autocomplete_input_unittest.cc @@ -122,8 +122,8 @@ TEST(AutocompleteInputTest, InputType) { for (size_t i = 0; i < ARRAYSIZE_UNSAFE(input_cases); ++i) { SCOPED_TRACE(input_cases[i].input); AutocompleteInput input(input_cases[i].input, string16::npos, string16(), - GURL(), true, false, true, - AutocompleteInput::ALL_MATCHES); + GURL(), AutocompleteInput::INVALID_SPEC, true, + false, true, AutocompleteInput::ALL_MATCHES); EXPECT_EQ(input_cases[i].type, input.type()); } } @@ -150,7 +150,8 @@ TEST(AutocompleteInputTest, InputTypeWithDesiredTLD) { for (size_t i = 0; i < ARRAYSIZE_UNSAFE(input_cases); ++i) { SCOPED_TRACE(input_cases[i].input); AutocompleteInput input(input_cases[i].input, string16::npos, - ASCIIToUTF16("com"), GURL(), true, false, true, + ASCIIToUTF16("com"), GURL(), + AutocompleteInput::INVALID_SPEC, true, false, true, AutocompleteInput::ALL_MATCHES); EXPECT_EQ(input_cases[i].type, input.type()); if (input_cases[i].type == AutocompleteInput::URL) @@ -162,8 +163,8 @@ TEST(AutocompleteInputTest, InputTypeWithDesiredTLD) { // crash. As long as the test completes without crashing, we're fine. TEST(AutocompleteInputTest, InputCrash) { AutocompleteInput input(WideToUTF16(L"\uff65@s"), string16::npos, string16(), - GURL(), true, false, true, - AutocompleteInput::ALL_MATCHES); + GURL(), AutocompleteInput::INVALID_SPEC, true, false, + true, AutocompleteInput::ALL_MATCHES); } TEST(AutocompleteInputTest, ParseForEmphasizeComponent) { @@ -205,8 +206,8 @@ TEST(AutocompleteInputTest, ParseForEmphasizeComponent) { &scheme, &host); AutocompleteInput input(input_cases[i].input, string16::npos, string16(), - GURL(), true, false, true, - AutocompleteInput::ALL_MATCHES); + GURL(), AutocompleteInput::INVALID_SPEC, true, + false, true, AutocompleteInput::ALL_MATCHES); EXPECT_EQ(input_cases[i].scheme.begin, scheme.begin); EXPECT_EQ(input_cases[i].scheme.len, scheme.len); EXPECT_EQ(input_cases[i].host.begin, host.begin); @@ -243,8 +244,8 @@ TEST(AutocompleteInputTest, InputTypeWithCursorPosition) { SCOPED_TRACE(input_cases[i].input); AutocompleteInput input(input_cases[i].input, input_cases[i].cursor_position, - string16(), GURL(), true, false, true, - AutocompleteInput::ALL_MATCHES); + string16(), GURL(), AutocompleteInput::INVALID_SPEC, + true, false, true, AutocompleteInput::ALL_MATCHES); EXPECT_EQ(input_cases[i].normalized_input, input.text()); EXPECT_EQ(input_cases[i].normalized_cursor_position, input.cursor_position()); diff --git a/chrome/browser/autocomplete/autocomplete_provider_unittest.cc b/chrome/browser/autocomplete/autocomplete_provider_unittest.cc index 567c8888c2..8b56cbb5e7 100644 --- a/chrome/browser/autocomplete/autocomplete_provider_unittest.cc +++ b/chrome/browser/autocomplete/autocomplete_provider_unittest.cc @@ -391,7 +391,8 @@ void AutocompleteProviderTest::RunAssistedQueryStatsTest( void AutocompleteProviderTest::RunQuery(const string16 query) { result_.Reset(); controller_->Start(AutocompleteInput( - query, string16::npos, string16(), GURL(), true, false, true, + query, string16::npos, string16(), GURL(), + AutocompleteInput::INVALID_SPEC, true, false, true, AutocompleteInput::ALL_MATCHES)); if (!controller_->done()) @@ -409,8 +410,9 @@ void AutocompleteProviderTest::RunExactKeymatchTest( // be from SearchProvider. (It provides all verbatim search matches, // keyword or not.) controller_->Start(AutocompleteInput( - ASCIIToUTF16("k test"), string16::npos, string16(), GURL(), true, false, - allow_exact_keyword_match, AutocompleteInput::SYNCHRONOUS_MATCHES)); + ASCIIToUTF16("k test"), string16::npos, string16(), GURL(), + AutocompleteInput::INVALID_SPEC, true, false, allow_exact_keyword_match, + AutocompleteInput::SYNCHRONOUS_MATCHES)); EXPECT_TRUE(controller_->done()); EXPECT_EQ(AutocompleteProvider::TYPE_SEARCH, controller_->result().default_match()->provider->type()); diff --git a/chrome/browser/autocomplete/autocomplete_result_unittest.cc b/chrome/browser/autocomplete/autocomplete_result_unittest.cc index b105e8149c..3038c27a01 100644 --- a/chrome/browser/autocomplete/autocomplete_result_unittest.cc +++ b/chrome/browser/autocomplete/autocomplete_result_unittest.cc @@ -116,7 +116,8 @@ void AutocompleteResultTest::RunCopyOldMatchesTest( const TestData* current, size_t current_size, const TestData* expected, size_t expected_size) { AutocompleteInput input(ASCIIToUTF16("a"), string16::npos, string16(), GURL(), - false, false, false, AutocompleteInput::ALL_MATCHES); + AutocompleteInput::INVALID_SPEC, false, false, false, + AutocompleteInput::ALL_MATCHES); ACMatches last_matches; PopulateAutocompleteMatches(last, last_size, &last_matches); @@ -148,7 +149,8 @@ TEST_F(AutocompleteResultTest, Swap) { ACMatches matches; AutocompleteMatch match; AutocompleteInput input(ASCIIToUTF16("a"), string16::npos, string16(), GURL(), - false, false, false, AutocompleteInput::ALL_MATCHES); + AutocompleteInput::INVALID_SPEC, false, false, false, + AutocompleteInput::ALL_MATCHES); matches.push_back(match); r1.AppendMatches(matches); r1.SortAndCull(input, test_util_.profile()); @@ -228,8 +230,9 @@ TEST_F(AutocompleteResultTest, SortAndCullEmptyDestinationURLs) { AutocompleteResult result; result.AppendMatches(matches); - AutocompleteInput input(string16(), string16::npos, string16(), GURL(), false, - false, false, AutocompleteInput::ALL_MATCHES); + AutocompleteInput input(string16(), string16::npos, string16(), GURL(), + AutocompleteInput::INVALID_SPEC, false, false, false, + AutocompleteInput::ALL_MATCHES); result.SortAndCull(input, test_util_.profile()); // Of the two results with the same non-empty destination URL, the @@ -272,8 +275,9 @@ TEST_F(AutocompleteResultTest, SortAndCullDuplicateSearchURLs) { AutocompleteResult result; result.AppendMatches(matches); - AutocompleteInput input(string16(), string16::npos, string16(), GURL(), false, - false, false, AutocompleteInput::ALL_MATCHES); + AutocompleteInput input(string16(), string16::npos, string16(), GURL(), + AutocompleteInput::INVALID_SPEC, false, false, false, + AutocompleteInput::ALL_MATCHES); result.SortAndCull(input, test_util_.profile()); // We expect the 3rd and 4th results to be removed. diff --git a/chrome/browser/autocomplete/bookmark_provider_unittest.cc b/chrome/browser/autocomplete/bookmark_provider_unittest.cc index 34f33c2e2d..db0e6d2d13 100644 --- a/chrome/browser/autocomplete/bookmark_provider_unittest.cc +++ b/chrome/browser/autocomplete/bookmark_provider_unittest.cc @@ -243,7 +243,8 @@ TEST_F(BookmarkProviderTest, Positions) { for (size_t i = 0; i < ARRAYSIZE_UNSAFE(query_data); ++i) { AutocompleteInput input(ASCIIToUTF16(query_data[i].query), - string16::npos, string16(), GURL(), false, false, + string16::npos, string16(), GURL(), + AutocompleteInput::INVALID_SPEC, false, false, false, AutocompleteInput::ALL_MATCHES); provider_->Start(input, false); const ACMatches& matches(provider_->matches()); @@ -316,7 +317,8 @@ TEST_F(BookmarkProviderTest, Rankings) { for (size_t i = 0; i < ARRAYSIZE_UNSAFE(query_data); ++i) { AutocompleteInput input(ASCIIToUTF16(query_data[i].query), - string16::npos, string16(), GURL(), false, false, + string16::npos, string16(), GURL(), + AutocompleteInput::INVALID_SPEC, false, false, false, AutocompleteInput::ALL_MATCHES); provider_->Start(input, false); const ACMatches& matches(provider_->matches()); diff --git a/chrome/browser/autocomplete/builtin_provider_unittest.cc b/chrome/browser/autocomplete/builtin_provider_unittest.cc index 0315dc614b..014b042174 100644 --- a/chrome/browser/autocomplete/builtin_provider_unittest.cc +++ b/chrome/browser/autocomplete/builtin_provider_unittest.cc @@ -53,8 +53,8 @@ void BuiltinProviderTest::RunTest(test_data<ResultType>* builtin_cases, ACMatches matches; for (int i = 0; i < num_cases; ++i) { AutocompleteInput input(builtin_cases[i].input, string16::npos, string16(), - GURL(), true, false, true, - AutocompleteInput::ALL_MATCHES); + GURL(), AutocompleteInput::INVALID_SPEC, true, + false, true, AutocompleteInput::ALL_MATCHES); builtin_provider_->Start(input, false); EXPECT_TRUE(builtin_provider_->done()); matches = builtin_provider_->matches(); diff --git a/chrome/browser/autocomplete/contact_provider_chromeos_unittest.cc b/chrome/browser/autocomplete/contact_provider_chromeos_unittest.cc index fa879f6ce7..135693724f 100644 --- a/chrome/browser/autocomplete/contact_provider_chromeos_unittest.cc +++ b/chrome/browser/autocomplete/contact_provider_chromeos_unittest.cc @@ -66,12 +66,13 @@ class ContactProviderTest : public testing::Test { void StartQuery(const std::string& utf8_text) { contact_provider_->Start( AutocompleteInput(UTF8ToUTF16(utf8_text), - string16::npos, // cursor_position - string16(), // desired_tld - GURL(), // current_url - false, // prevent_inline_autocomplete - false, // prefer_keyword - false, // allow_exact_keyword_match + string16::npos, + string16(), + GURL(), + AutocompleteInput::INVALID_SPEC, + false, + false, + false, AutocompleteInput::ALL_MATCHES), false); // minimal_changes } diff --git a/chrome/browser/autocomplete/extension_app_provider_unittest.cc b/chrome/browser/autocomplete/extension_app_provider_unittest.cc index 7ccafc2be2..d66dcf74d1 100644 --- a/chrome/browser/autocomplete/extension_app_provider_unittest.cc +++ b/chrome/browser/autocomplete/extension_app_provider_unittest.cc @@ -87,8 +87,8 @@ void ExtensionAppProviderTest::RunTest( ACMatches matches; for (int i = 0; i < num_cases; ++i) { AutocompleteInput input(keyword_cases[i].input, string16::npos, string16(), - GURL(), true, false, true, - AutocompleteInput::ALL_MATCHES); + GURL(), AutocompleteInput::INVALID_SPEC, true, + false, true, AutocompleteInput::ALL_MATCHES); app_provider_->Start(input, false); EXPECT_TRUE(app_provider_->done()); matches = app_provider_->matches(); @@ -137,8 +137,8 @@ TEST_F(ExtensionAppProviderTest, CreateMatchSanitize) { }; AutocompleteInput input(ASCIIToUTF16("Test"), string16::npos, string16(), - GURL(), true, true, true, - AutocompleteInput::BEST_MATCH); + GURL(), AutocompleteInput::INVALID_SPEC, true, true, + true, AutocompleteInput::BEST_MATCH); string16 url(ASCIIToUTF16("http://example.com")); for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { ExtensionAppProvider::ExtensionApp extension_app = diff --git a/chrome/browser/autocomplete/history_quick_provider_unittest.cc b/chrome/browser/autocomplete/history_quick_provider_unittest.cc index 3b203cc528..1d57daf7e1 100644 --- a/chrome/browser/autocomplete/history_quick_provider_unittest.cc +++ b/chrome/browser/autocomplete/history_quick_provider_unittest.cc @@ -245,8 +245,9 @@ void HistoryQuickProviderTest::RunTest(const string16 text, string16 expected_fill_into_edit) { SCOPED_TRACE(text); // Minimal hint to query being run. base::MessageLoop::current()->RunUntilIdle(); - AutocompleteInput input(text, string16::npos, string16(), GURL(),false, false, - true, AutocompleteInput::ALL_MATCHES); + AutocompleteInput input(text, string16::npos, string16(), GURL(), + AutocompleteInput::INVALID_SPEC, false, false, true, + AutocompleteInput::ALL_MATCHES); provider_->Start(input, false); EXPECT_TRUE(provider_->done()); diff --git a/chrome/browser/autocomplete/history_url_provider_unittest.cc b/chrome/browser/autocomplete/history_url_provider_unittest.cc index 35a2873a0d..931ebd562b 100644 --- a/chrome/browser/autocomplete/history_url_provider_unittest.cc +++ b/chrome/browser/autocomplete/history_url_provider_unittest.cc @@ -261,6 +261,7 @@ void HistoryURLProviderTest::RunTest( size_t num_results, AutocompleteInput::Type* identified_input_type) { AutocompleteInput input(text, string16::npos, desired_tld, GURL(), + AutocompleteInput::INVALID_SPEC, prevent_inline_autocomplete, false, true, AutocompleteInput::ALL_MATCHES); *identified_input_type = input.type(); @@ -518,7 +519,8 @@ TEST_F(HistoryURLProviderTest, EmptyVisits) { profile_->BlockUntilHistoryProcessesPendingRequests(); AutocompleteInput input(ASCIIToUTF16("p"), string16::npos, string16(), GURL(), - false, false, true, AutocompleteInput::ALL_MATCHES); + AutocompleteInput::INVALID_SPEC, false, false, true, + AutocompleteInput::ALL_MATCHES); autocomplete_->Start(input, false); // HistoryURLProvider shouldn't be done (waiting on async results). EXPECT_FALSE(autocomplete_->done()); @@ -554,8 +556,8 @@ TEST_F(HistoryURLProviderTestNoDB, NavigateWithoutDB) { TEST_F(HistoryURLProviderTest, DontAutocompleteOnTrailingWhitespace) { AutocompleteInput input(ASCIIToUTF16("slash "), string16::npos, string16(), - GURL(), false, false, true, - AutocompleteInput::ALL_MATCHES); + GURL(), AutocompleteInput::INVALID_SPEC, false, false, + true, AutocompleteInput::ALL_MATCHES); autocomplete_->Start(input, false); if (!autocomplete_->done()) base::MessageLoop::current()->Run(); @@ -722,8 +724,8 @@ TEST_F(HistoryURLProviderTest, CrashDueToFixup) { }; for (size_t i = 0; i < arraysize(test_cases); ++i) { AutocompleteInput input(ASCIIToUTF16(test_cases[i]), string16::npos, - string16(), GURL(), false, false, true, - AutocompleteInput::ALL_MATCHES); + string16(), GURL(), AutocompleteInput::INVALID_SPEC, + false, false, true, AutocompleteInput::ALL_MATCHES); autocomplete_->Start(input, false); if (!autocomplete_->done()) base::MessageLoop::current()->Run(); @@ -837,7 +839,8 @@ TEST_F(HistoryURLProviderTest, SuggestExactInput) { AutocompleteInput input(ASCIIToUTF16(test_cases[i].input), string16::npos, string16(), GURL("about:blank"), - false, false, true, AutocompleteInput::ALL_MATCHES); + AutocompleteInput::INVALID_SPEC, false, false, true, + AutocompleteInput::ALL_MATCHES); AutocompleteMatch match = HistoryURLProvider::SuggestExactInput( autocomplete_.get(), input, test_cases[i].trim_http); EXPECT_EQ(ASCIIToUTF16(test_cases[i].contents), match.contents); diff --git a/chrome/browser/autocomplete/keyword_provider_unittest.cc b/chrome/browser/autocomplete/keyword_provider_unittest.cc index 411bc608f0..617811b450 100644 --- a/chrome/browser/autocomplete/keyword_provider_unittest.cc +++ b/chrome/browser/autocomplete/keyword_provider_unittest.cc @@ -70,8 +70,8 @@ void KeywordProviderTest::RunTest( ACMatches matches; for (int i = 0; i < num_cases; ++i) { AutocompleteInput input(keyword_cases[i].input, string16::npos, string16(), - GURL(), true, false, true, - AutocompleteInput::ALL_MATCHES); + GURL(), AutocompleteInput::INVALID_SPEC, true, + false, true, AutocompleteInput::ALL_MATCHES); kw_provider_->Start(input, false); EXPECT_TRUE(kw_provider_->done()); matches = kw_provider_->matches(); @@ -265,7 +265,8 @@ TEST_F(KeywordProviderTest, GetSubstitutingTemplateURLForInput) { for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); i++) { AutocompleteInput input(ASCIIToUTF16(cases[i].text), cases[i].cursor_position, string16(), GURL(), - false, false, cases[i].allow_exact_keyword_match, + AutocompleteInput::INVALID_SPEC, false, false, + cases[i].allow_exact_keyword_match, AutocompleteInput::ALL_MATCHES); const TemplateURL* url = KeywordProvider::GetSubstitutingTemplateURLForInput(model_.get(), diff --git a/chrome/browser/autocomplete/search_provider_unittest.cc b/chrome/browser/autocomplete/search_provider_unittest.cc index ef4bfa450b..28b8d67540 100644 --- a/chrome/browser/autocomplete/search_provider_unittest.cc +++ b/chrome/browser/autocomplete/search_provider_unittest.cc @@ -242,7 +242,8 @@ void SearchProviderTest::RunTest(TestData* cases, ACMatches matches; for (int i = 0; i < num_cases; ++i) { AutocompleteInput input(cases[i].input, string16::npos, string16(), GURL(), - false, prefer_keyword, true, + AutocompleteInput::INVALID_SPEC, false, + prefer_keyword, true, AutocompleteInput::ALL_MATCHES); provider_->Start(input, false); matches = provider_->matches(); @@ -285,8 +286,9 @@ void SearchProviderTest::QueryForInput(const string16& text, bool prefer_keyword) { // Start a query. AutocompleteInput input(text, string16::npos, string16(), GURL(), - prevent_inline_autocomplete, - prefer_keyword, true, AutocompleteInput::ALL_MATCHES); + AutocompleteInput::INVALID_SPEC, + prevent_inline_autocomplete, prefer_keyword, true, + AutocompleteInput::ALL_MATCHES); provider_->Start(input, false); // RunUntilIdle so that the task scheduled by SearchProvider to create the @@ -660,8 +662,9 @@ TEST_F(SearchProviderTest, KeywordOrderingAndDescriptions) { AutocompleteController controller(&profile_, NULL, AutocompleteProvider::TYPE_SEARCH); controller.Start(AutocompleteInput( - ASCIIToUTF16("k t"), string16::npos, string16(), GURL(), false, false, - true, AutocompleteInput::ALL_MATCHES)); + ASCIIToUTF16("k t"), string16::npos, string16(), GURL(), + AutocompleteInput::INVALID_SPEC, false, false, true, + AutocompleteInput::ALL_MATCHES)); const AutocompleteResult& result = controller.result(); // There should be three matches, one for the keyword history, one for @@ -2132,7 +2135,8 @@ TEST_F(SearchProviderTest, RemoveStaleResultsTest) { provider_->input_ = AutocompleteInput( ASCIIToUTF16(cases[i].omnibox_input), string16::npos, string16(), - GURL(), false, false, true, AutocompleteInput::ALL_MATCHES); + GURL(), AutocompleteInput::INVALID_SPEC, false, false, true, + AutocompleteInput::ALL_MATCHES); provider_->RemoveAllStaleResults(); // Check cached results. diff --git a/chrome/browser/autocomplete/shortcuts_provider_unittest.cc b/chrome/browser/autocomplete/shortcuts_provider_unittest.cc index bd700aa586..73699dbd4d 100644 --- a/chrome/browser/autocomplete/shortcuts_provider_unittest.cc +++ b/chrome/browser/autocomplete/shortcuts_provider_unittest.cc @@ -226,8 +226,9 @@ void ShortcutsProviderTest::RunTest(const string16 text, std::sort(expected_urls.begin(), expected_urls.end()); base::MessageLoop::current()->RunUntilIdle(); - AutocompleteInput input(text, string16::npos, string16(), GURL(), false, - false, true, AutocompleteInput::ALL_MATCHES); + AutocompleteInput input(text, string16::npos, string16(), GURL(), + AutocompleteInput::INVALID_SPEC, false, false, true, + AutocompleteInput::ALL_MATCHES); provider_->Start(input, false); EXPECT_TRUE(provider_->done()); diff --git a/chrome/browser/autocomplete/zero_suggest_provider.cc b/chrome/browser/autocomplete/zero_suggest_provider.cc index 1266eb0562..181a3d9254 100644 --- a/chrome/browser/autocomplete/zero_suggest_provider.cc +++ b/chrome/browser/autocomplete/zero_suggest_provider.cc @@ -149,8 +149,10 @@ void ZeroSuggestProvider::OnURLFetchComplete(const net::URLFetcher* source) { } } -void ZeroSuggestProvider::StartZeroSuggest(const GURL& url, - const string16& permanent_text) { +void ZeroSuggestProvider::StartZeroSuggest( + const GURL& url, + AutocompleteInput::PageClassification page_classification, + const string16& permanent_text) { Stop(true); field_trial_triggered_ = false; field_trial_triggered_in_session_ = false; @@ -160,6 +162,7 @@ void ZeroSuggestProvider::StartZeroSuggest(const GURL& url, done_ = false; permanent_text_ = permanent_text; current_query_ = url.spec(); + current_page_classification_ = page_classification; current_url_match_ = MatchForCurrentURL(); // TODO(jered): Consider adding locally-sourced zero-suggestions here too. // These may be useful on the NTP or more relevant to the user than server @@ -449,8 +452,8 @@ void ZeroSuggestProvider::ConvertResultsToAutocompleteMatches() { } AutocompleteMatch ZeroSuggestProvider::MatchForCurrentURL() { - AutocompleteInput input(permanent_text_, string16::npos, - string16(), GURL(current_query_), + AutocompleteInput input(permanent_text_, string16::npos, string16(), + GURL(current_query_), current_page_classification_, false, false, true, AutocompleteInput::ALL_MATCHES); AutocompleteMatch match( diff --git a/chrome/browser/autocomplete/zero_suggest_provider.h b/chrome/browser/autocomplete/zero_suggest_provider.h index 3d83a35e1f..c53c9eef31 100644 --- a/chrome/browser/autocomplete/zero_suggest_provider.h +++ b/chrome/browser/autocomplete/zero_suggest_provider.h @@ -70,14 +70,13 @@ class ZeroSuggestProvider : public AutocompleteProvider, // net::URLFetcherDelegate virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; - // Initiates a new fetch for the given |url|. |user_text| is the user input - // and may be non-empty if the user previously interacted with - // zero-suggest suggestions and then unfocused the omnibox. |permanent_text| - // is the omnibox text for the current page. - // TODO(jered): Rip out |user_text| once the first match is decoupled from - // the current typing in the omnibox. - void StartZeroSuggest(const GURL& url, - const string16& permanent_text); + // Initiates a new fetch for the given |url| of classification + // |page_classification|. |permanent_text| is the omnibox text + // for the current page. + void StartZeroSuggest( + const GURL& url, + AutocompleteInput::PageClassification page_classification, + const string16& permanent_text); private: ZeroSuggestProvider(AutocompleteProviderListener* listener, @@ -146,6 +145,10 @@ class ZeroSuggestProvider : public AutocompleteProvider, // The URL for which a suggestion fetch is pending. std::string current_query_; + // The type of page the user is viewing (a search results page doing search + // term replacement, an arbitrary URL, etc.). + AutocompleteInput::PageClassification current_page_classification_; + // Copy of OmniboxEditModel::permanent_text_. string16 permanent_text_; diff --git a/chrome/browser/chrome_browser_field_trials_desktop.cc b/chrome/browser/chrome_browser_field_trials_desktop.cc index 339ee6b654..92b664530d 100644 --- a/chrome/browser/chrome_browser_field_trials_desktop.cc +++ b/chrome/browser/chrome_browser_field_trials_desktop.cc @@ -62,9 +62,9 @@ void SetupInfiniteCacheFieldTrial() { base::FieldTrial::Probability infinite_cache_probability = 0; scoped_refptr<base::FieldTrial> trial( - base::FieldTrialList::FactoryGetFieldTrial("InfiniteCache", kDivisor, - "No", 2013, 12, 31, NULL)); - trial->UseOneTimeRandomization(); + base::FieldTrialList::FactoryGetFieldTrial( + "InfiniteCache", kDivisor, "No", 2013, 12, 31, + base::FieldTrial::ONE_TIME_RANDOMIZED, NULL)); trial->AppendGroup("Yes", infinite_cache_probability); trial->AppendGroup("Control", infinite_cache_probability); } @@ -106,9 +106,9 @@ void SetupCacheSensitivityAnalysisFieldTrial() { #endif scoped_refptr<base::FieldTrial> trial( - base::FieldTrialList::FactoryGetFieldTrial("CacheSensitivityAnalysis", - kDivisor, "No", - 2013, 06, 15, NULL)); + base::FieldTrialList::FactoryGetFieldTrial( + "CacheSensitivityAnalysis", kDivisor, "No", 2013, 06, 15, + base::FieldTrial::SESSION_RANDOMIZED, NULL)); trial->AppendGroup("ControlA", sensitivity_analysis_probability); trial->AppendGroup("ControlB", sensitivity_analysis_probability); trial->AppendGroup("100A", sensitivity_analysis_probability); @@ -130,8 +130,9 @@ void WindowsOverlappedTCPReadsFieldTrial( const base::FieldTrial::Probability kDivisor = 2; // 1 in 2 chance const base::FieldTrial::Probability kOverlappedReadProbability = 1; scoped_refptr<base::FieldTrial> overlapped_reads_trial( - base::FieldTrialList::FactoryGetFieldTrial("OverlappedReadImpact", - kDivisor, "OverlappedReadEnabled", 2013, 6, 1, NULL)); + base::FieldTrialList::FactoryGetFieldTrial( + "OverlappedReadImpact", kDivisor, "OverlappedReadEnabled", + 2013, 6, 1, base::FieldTrial::SESSION_RANDOMIZED, NULL)); int overlapped_reads_disabled_group = overlapped_reads_trial->AppendGroup("OverlappedReadDisabled", kOverlappedReadProbability); @@ -145,8 +146,8 @@ void WindowsOverlappedTCPReadsFieldTrial( void SetupLowLatencyFlashAudioFieldTrial() { scoped_refptr<base::FieldTrial> trial( base::FieldTrialList::FactoryGetFieldTrial( - content::kLowLatencyFlashAudioFieldTrialName, - 100, "Standard", 2013, 9, 1, NULL)); + content::kLowLatencyFlashAudioFieldTrialName, 100, "Standard", + 2013, 9, 1, base::FieldTrial::SESSION_RANDOMIZED, NULL)); // Trial is enabled for dev / beta / canary users only. if (chrome::VersionInfo::GetChannel() != chrome::VersionInfo::CHANNEL_STABLE) diff --git a/chrome/browser/chrome_browser_field_trials_mobile.cc b/chrome/browser/chrome_browser_field_trials_mobile.cc index 5e17ca7472..8d9140c52e 100644 --- a/chrome/browser/chrome_browser_field_trials_mobile.cc +++ b/chrome/browser/chrome_browser_field_trials_mobile.cc @@ -37,10 +37,8 @@ void DataCompressionProxyFieldTrial() { scoped_refptr<base::FieldTrial> trial( base::FieldTrialList::FactoryGetFieldTrial( kDataCompressionProxyFieldTrialName, kDataCompressionProxyDivisor, - kDisabled, 2015, 1, 1, NULL)); + kDisabled, 2015, 1, 1, base::FieldTrial::ONE_TIME_RANDOMIZED, NULL)); - // We want our trial results to be persistent. - trial->UseOneTimeRandomization(); // Non-stable channels will run with probability 1. const int kEnabledGroup = trial->AppendGroup( kEnabled, @@ -77,10 +75,8 @@ void NewTabButtonInToolbarFieldTrial(const CommandLine& parsed_command_line) { base::FieldTrialList::FactoryGetFieldTrial( kPhoneNewTabToolbarButtonFieldTrialName, kPhoneNewTabToolbarButtonDivisor, - kDisabled, 2015, 1, 1, NULL)); + kDisabled, 2015, 1, 1, base::FieldTrial::ONE_TIME_RANDOMIZED, NULL)); - // We want our trial results to be persistent. - trial->UseOneTimeRandomization(); const int kEnabledGroup = trial->AppendGroup( kEnabled, kIsStableChannel ? diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index badf609563..8b71ef337f 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc @@ -62,6 +62,7 @@ #include "chrome/browser/gpu/gl_string_manager.h" #include "chrome/browser/jankometer.h" #include "chrome/browser/language_usage_metrics.h" +#include "chrome/browser/media/media_capture_devices_dispatcher.h" #include "chrome/browser/metrics/field_trial_synchronizer.h" #include "chrome/browser/metrics/metrics_log.h" #include "chrome/browser/metrics/metrics_service.h" @@ -141,9 +142,7 @@ #include "ui/base/layout.h" #include "ui/base/resource/resource_bundle.h" -#if defined(OS_ANDROID) -#include "chrome/browser/media/media_capture_devices_dispatcher.h" -#else +#if !defined(OS_ANDROID) #include "chrome/browser/ui/active_tab_tracker.h" #endif @@ -821,15 +820,15 @@ int ChromeBrowserMainParts::PreCreateThreadsImpl() { user_data_dir_ = chrome::GetUserDataDir(parameters()); } + // Force MediaCaptureDevicesDispatcher to be created on UI thread. + MediaCaptureDevicesDispatcher::GetInstance(); + // Whether this is First Run. |do_first_run_tasks_| should be prefered to this // unless the desire is actually to know whether this is really First Run // (i.e., even if --no-first-run is passed). bool is_first_run = false; // Android's first run is done in Java instead of native. -#if defined(OS_ANDROID) - // Force MediaCaptureDevicesDispatcher created on UI thread. - MediaCaptureDevicesDispatcher::GetInstance(); -#else +#if !defined(OS_ANDROID) process_singleton_.reset(new ChromeProcessSingleton( user_data_dir_, base::Bind(&ProcessSingletonNotificationCallback))); diff --git a/chrome/browser/chromeos/external_metrics.cc b/chrome/browser/chromeos/external_metrics.cc index cabac245e9..5c6b329cf0 100644 --- a/chrome/browser/chromeos/external_metrics.cc +++ b/chrome/browser/chromeos/external_metrics.cc @@ -63,10 +63,10 @@ void SetupProgressiveScanFieldTrial() { const char path_to_group_file[] = "/home/chronos/.progressive_scan_variation"; const base::FieldTrial::Probability kDivisor = 1000; scoped_refptr<base::FieldTrial> trial = - base::FieldTrialList::FactoryGetFieldTrial(name_of_experiment, - kDivisor, - "Default", - 2013, 12, 31, NULL); + base::FieldTrialList::FactoryGetFieldTrial( + name_of_experiment, kDivisor, "Default", 2013, 12, 31, + base::FieldTrial::SESSION_RANDOMIZED, NULL); + // Announce the groups with 0 percentage; the actual percentages come from // the server configuration. std::map<int, std::string> group_to_char; @@ -113,10 +113,10 @@ void SetupSwapJankFieldTrial() { // All groups are either on or off. const base::FieldTrial::Probability kTotalProbability = 1; scoped_refptr<base::FieldTrial> trial = - base::FieldTrialList::FactoryGetFieldTrial(name_of_experiment, - kTotalProbability, - "default", - 2013, 12, 31, NULL); + base::FieldTrialList::FactoryGetFieldTrial( + name_of_experiment, kTotalProbability, "default", 2013, 12, 31, + base::FieldTrial::SESSION_RANDOMIZED, NULL); + // Assign probability of 1 to this Chrome's group. Assign 0 to all other // choices. trial->AppendGroup("kernel_64_chrome_64", diff --git a/chrome/browser/chromeos/login/default_pinned_apps_field_trial.cc b/chrome/browser/chromeos/login/default_pinned_apps_field_trial.cc index c75234a060..f6de0e0ce8 100644 --- a/chrome/browser/chromeos/login/default_pinned_apps_field_trial.cc +++ b/chrome/browser/chromeos/login/default_pinned_apps_field_trial.cc @@ -134,8 +134,8 @@ void SetupTrial() { const base::FieldTrial::Probability kDivisor = 100; scoped_refptr<base::FieldTrial> trial = base::FieldTrialList::FactoryGetFieldTrial( - kExperimentName, kDivisor, "Existing", 2013, 12, 31, NULL); - trial->UseOneTimeRandomization(); + kExperimentName, kDivisor, "Existing", 2013, 12, 31, + base::FieldTrial::ONE_TIME_RANDOMIZED, NULL); // Split 50/50 between "Control" and "Alternamte" group for new user. // Existing users already have their default pinned apps and have the trial diff --git a/chrome/browser/component_updater/test/component_updater_service_unittest.cc b/chrome/browser/component_updater/test/component_updater_service_unittest.cc index 7a66d55af0..b1cf78bfa3 100644 --- a/chrome/browser/component_updater/test/component_updater_service_unittest.cc +++ b/chrome/browser/component_updater/test/component_updater_service_unittest.cc @@ -755,7 +755,15 @@ TEST_F(ComponentUpdaterTest, DifferentialUpdate) { // 3- download full crx // 4- update check (loop 2 - no update available) // There should be one ping for the first attempted update. -TEST_F(ComponentUpdaterTest, DifferentialUpdateFails) { +// Fails on Window. http://crbug.com/265840 +#if defined(OS_WIN) +#define MAYBE_DifferentialUpdateFails DISABLED_DifferentialUpdateFails +#else +#define MAYBE_DifferentialUpdateFails DifferentialUpdateFails +#endif + +TEST_F(ComponentUpdaterTest, MAYBE_DifferentialUpdateFails) { + std::map<std::string, std::string> map; map.insert(std::pair<std::string, std::string>("eventtype", "\"3\"")); map.insert(std::pair<std::string, std::string>("eventresult", "\"1\"")); diff --git a/chrome/browser/extensions/api/omnibox/omnibox_api_browsertest.cc b/chrome/browser/extensions/api/omnibox/omnibox_api_browsertest.cc index 4c994c0c64..c831a811c7 100644 --- a/chrome/browser/extensions/api/omnibox/omnibox_api_browsertest.cc +++ b/chrome/browser/extensions/api/omnibox/omnibox_api_browsertest.cc @@ -33,8 +33,8 @@ IN_PROC_BROWSER_TEST_F(OmniboxApiTest, Basic) { { autocomplete_controller->Start( AutocompleteInput(ASCIIToUTF16("keywor"), string16::npos, string16(), - GURL(), true, false, true, - AutocompleteInput::ALL_MATCHES)); + GURL(), AutocompleteInput::NEW_TAB_PAGE, true, false, + true, AutocompleteInput::ALL_MATCHES)); WaitForAutocompleteDone(autocomplete_controller); EXPECT_TRUE(autocomplete_controller->done()); @@ -55,8 +55,8 @@ IN_PROC_BROWSER_TEST_F(OmniboxApiTest, Basic) { { autocomplete_controller->Start( AutocompleteInput(ASCIIToUTF16("keyword suggestio"), string16::npos, - string16(), GURL(), true, false, true, - AutocompleteInput::ALL_MATCHES)); + string16(), GURL(), AutocompleteInput::NEW_TAB_PAGE, + true, false, true, AutocompleteInput::ALL_MATCHES)); WaitForAutocompleteDone(autocomplete_controller); EXPECT_TRUE(autocomplete_controller->done()); @@ -165,8 +165,8 @@ IN_PROC_BROWSER_TEST_F(OmniboxApiTest, OnInputEntered) { autocomplete_controller->Start( AutocompleteInput(ASCIIToUTF16("keyword command"), string16::npos, - string16(), GURL(), true, false, true, - AutocompleteInput::ALL_MATCHES)); + string16(), GURL(), AutocompleteInput::NEW_TAB_PAGE, + true, false, true, AutocompleteInput::ALL_MATCHES)); location_bar->GetLocationEntry()->model()->AcceptInput( CURRENT_TAB, false); // Not for drop operation. @@ -182,8 +182,8 @@ IN_PROC_BROWSER_TEST_F(OmniboxApiTest, OnInputEntered) { autocomplete_controller->Start( AutocompleteInput(ASCIIToUTF16("keyword newtab"), string16::npos, - string16(), GURL(), true, false, true, - AutocompleteInput::ALL_MATCHES)); + string16(), GURL(), AutocompleteInput::NEW_TAB_PAGE, + true, false, true, AutocompleteInput::ALL_MATCHES)); location_bar->GetLocationEntry()->model()->AcceptInput( NEW_FOREGROUND_TAB, false); // Not for drop operation. @@ -221,8 +221,8 @@ IN_PROC_BROWSER_TEST_F(OmniboxApiTest, DISABLED_IncognitoSplitMode) { { autocomplete_controller->Start( AutocompleteInput(ASCIIToUTF16("keyword suggestio"), string16::npos, - string16(), GURL(), true, false, true, - AutocompleteInput::ALL_MATCHES)); + string16(), GURL(), AutocompleteInput::NEW_TAB_PAGE, + true, false, true, AutocompleteInput::ALL_MATCHES)); WaitForAutocompleteDone(autocomplete_controller); EXPECT_TRUE(autocomplete_controller->done()); @@ -243,7 +243,8 @@ IN_PROC_BROWSER_TEST_F(OmniboxApiTest, DISABLED_IncognitoSplitMode) { ResultCatcher catcher; autocomplete_controller->Start( AutocompleteInput(ASCIIToUTF16("keyword command incognito"), - string16::npos, string16(), GURL(), true, false, true, + string16::npos, string16(), GURL(), + AutocompleteInput::NEW_TAB_PAGE, true, false, true, AutocompleteInput::ALL_MATCHES)); location_bar->AcceptInput(); EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); diff --git a/chrome/browser/extensions/api/omnibox/omnibox_api_interactive_test.cc b/chrome/browser/extensions/api/omnibox/omnibox_api_interactive_test.cc index 7f0df5b72e..5454c830c7 100644 --- a/chrome/browser/extensions/api/omnibox/omnibox_api_interactive_test.cc +++ b/chrome/browser/extensions/api/omnibox/omnibox_api_interactive_test.cc @@ -42,8 +42,8 @@ IN_PROC_BROWSER_TEST_F(OmniboxApiTest, PopupStaysClosed) { // location_bar or location_bar->(). autocomplete_controller->Start( AutocompleteInput(ASCIIToUTF16("keyword command"), string16::npos, - string16(), GURL(), true, false, true, - AutocompleteInput::ALL_MATCHES)); + string16(), GURL(), AutocompleteInput::NEW_TAB_PAGE, + true, false, true, AutocompleteInput::ALL_MATCHES)); location_bar->AcceptInput(); WaitForAutocompleteDone(autocomplete_controller); EXPECT_TRUE(autocomplete_controller->done()); diff --git a/chrome/browser/extensions/notifications_apitest.cc b/chrome/browser/extensions/notifications_apitest.cc index 858c45eaf3..65cdc1d186 100644 --- a/chrome/browser/extensions/notifications_apitest.cc +++ b/chrome/browser/extensions/notifications_apitest.cc @@ -56,22 +56,6 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_NoHTMLNotifications) { ASSERT_TRUE(RunExtensionTest("notifications/no_html")) << message_; } -// This test verifies that on platforms other then RichNotification-enabled -// HTML notificaitons are enabled. -#if defined(RUN_MESSAGE_CENTER_TESTS) -#define MAYBE_HasHTMLNotificationsAndManifestPermission \ - DISABLED_HasHTMLNotificationsAndManifestPermission -#else -#define MAYBE_HasHTMLNotificationsAndManifestPermission \ - HasHTMLNotificationsAndManifestPermission -#endif -IN_PROC_BROWSER_TEST_F(ExtensionApiTest, - MAYBE_HasHTMLNotificationsAndManifestPermission) { - ASSERT_FALSE(message_center::IsRichNotificationEnabled()); - ASSERT_TRUE(RunExtensionTest("notifications/has_permission_manifest")) - << message_; -} - IN_PROC_BROWSER_TEST_F(ExtensionApiTest, NotificationsHasPermission) { #if defined(OS_MACOSX) // TODO(kbr): re-enable: http://crbug.com/222296 diff --git a/chrome/browser/gpu/chrome_gpu_util.cc b/chrome/browser/gpu/chrome_gpu_util.cc index 441cebc31d..61da773e24 100644 --- a/chrome/browser/gpu/chrome_gpu_util.cc +++ b/chrome/browser/gpu/chrome_gpu_util.cc @@ -99,11 +99,8 @@ void InitializeCompositingFieldTrial() { const base::FieldTrial::Probability kDivisor = 3; scoped_refptr<base::FieldTrial> trial( base::FieldTrialList::FactoryGetFieldTrial( - content::kGpuCompositingFieldTrialName, kDivisor, - "disable", 2013, 12, 31, NULL)); - - // Produce the same result on every run of this client. - trial->UseOneTimeRandomization(); + content::kGpuCompositingFieldTrialName, kDivisor, "disable", + 2013, 12, 31, base::FieldTrial::ONE_TIME_RANDOMIZED, NULL)); base::FieldTrial::Probability force_compositing_mode_probability = 0; base::FieldTrial::Probability threaded_compositing_probability = 0; @@ -131,5 +128,5 @@ void InitializeCompositingFieldTrial() { UMA_HISTOGRAM_BOOLEAN("GPU.InCompositorThreadFieldTrial", thread); } -} // namespace gpu_util; +} // namespace gpu_util diff --git a/chrome/browser/metrics/gzipped_protobufs_field_trial.cc b/chrome/browser/metrics/gzipped_protobufs_field_trial.cc index cd105becba..81c34f7817 100644 --- a/chrome/browser/metrics/gzipped_protobufs_field_trial.cc +++ b/chrome/browser/metrics/gzipped_protobufs_field_trial.cc @@ -39,8 +39,8 @@ void CreateGzippedProtobufsFieldTrial() { 2013, 10, 1, + base::FieldTrial::ONE_TIME_RANDOMIZED, NULL); - gzipped_protobufs_trial->UseOneTimeRandomization(); int gzipped_protobufs_group = gzipped_protobufs_trial->AppendGroup( kGroupName, kTrialQuotient); diff --git a/chrome/browser/metrics/thread_watcher.cc b/chrome/browser/metrics/thread_watcher.cc index c8ee4cfe75..4a140158a3 100644 --- a/chrome/browser/metrics/thread_watcher.cc +++ b/chrome/browser/metrics/thread_watcher.cc @@ -569,7 +569,7 @@ void ThreadWatcherList::ParseCommandLine( scoped_refptr<base::FieldTrial> field_trial( base::FieldTrialList::FactoryGetFieldTrial( "ThreadWatcher", 100, "default_hung_threads", - 2013, 10, 30, NULL)); + 2013, 10, 30, base::FieldTrial::SESSION_RANDOMIZED, NULL)); int hung_thread_group = field_trial->AppendGroup("hung_thread", 100); if (field_trial->group() == hung_thread_group) { for (CrashOnHangThreadMap::iterator it = crash_on_hang_threads->begin(); diff --git a/chrome/browser/metrics/variations/variations_seed_processor.cc b/chrome/browser/metrics/variations/variations_seed_processor.cc index 58161f2fe6..ef98d85dfd 100644 --- a/chrome/browser/metrics/variations/variations_seed_processor.cc +++ b/chrome/browser/metrics/variations/variations_seed_processor.cc @@ -181,21 +181,24 @@ void VariationsSeedProcessor::CreateTrialFromStudy( } } + uint32 randomization_seed = 0; + base::FieldTrial::RandomizationType randomization_type = + base::FieldTrial::SESSION_RANDOMIZED; + if (study.has_consistency() && + study.consistency() == Study_Consistency_PERMANENT) { + randomization_type = base::FieldTrial::ONE_TIME_RANDOMIZED; + if (study.has_randomization_seed()) + randomization_seed = study.randomization_seed(); + } + // The trial is created without specifying an expiration date because the // expiration check in field_trial.cc is based on the build date. Instead, // the expiration check using |reference_date| is done explicitly below. scoped_refptr<base::FieldTrial> trial( - base::FieldTrialList::FactoryGetFieldTrial( + base::FieldTrialList::FactoryGetFieldTrialWithRandomizationSeed( study.name(), total_probability, study.default_experiment_name(), - base::FieldTrialList::kNoExpirationYear, 1, 1, NULL)); - - if (study.has_consistency() && - study.consistency() == Study_Consistency_PERMANENT) { - if (study.has_randomization_seed()) - trial->UseOneTimeRandomizationWithCustomSeed(study.randomization_seed()); - else - trial->UseOneTimeRandomization(); - } + base::FieldTrialList::kNoExpirationYear, 1, 1, randomization_type, + randomization_seed, NULL)); for (int i = 0; i < study.experiment_size(); ++i) { const Study_Experiment& experiment = study.experiment(i); diff --git a/chrome/browser/net/http_pipelining_compatibility_client.cc b/chrome/browser/net/http_pipelining_compatibility_client.cc index 042a5a25f9..e90fb037fc 100644 --- a/chrome/browser/net/http_pipelining_compatibility_client.cc +++ b/chrome/browser/net/http_pipelining_compatibility_client.cc @@ -465,7 +465,8 @@ void CollectPipeliningCapabilityStatsOnIOThread( } // After May 4, 2012, the trial will disable itself. trial = base::FieldTrialList::FactoryGetFieldTrial( - kTrialName, kDivisor, "disable_test", 2012, 5, 4, NULL); + kTrialName, kDivisor, "disable_test", 2012, 5, 4, + base::FieldTrial::SESSION_RANDOMIZED, NULL); chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel(); if (channel == chrome::VersionInfo::CHANNEL_CANARY) { diff --git a/chrome/browser/net/network_stats.cc b/chrome/browser/net/network_stats.cc index f9a4f2e1b8..8a9fe1fe5f 100644 --- a/chrome/browser/net/network_stats.cc +++ b/chrome/browser/net/network_stats.cc @@ -806,13 +806,9 @@ void CollectNetworkStats(const std::string& network_stats_server, // After July 31, 2014 builds, it will always be in default group // (disable_network_stats). - trial = base::FieldTrialList::FactoryGetFieldTrial("NetworkConnectivity", - kDivisor, - "disable_network_stats", - 2014, - 7, - 31, - NULL); + trial = base::FieldTrialList::FactoryGetFieldTrial( + "NetworkConnectivity", kDivisor, "disable_network_stats", + 2014, 7, 31, base::FieldTrial::SESSION_RANDOMIZED, NULL); // Add option to collect_stats for NetworkConnectivity. int collect_stats_group = diff --git a/chrome/browser/omnibox/omnibox_field_trial.cc b/chrome/browser/omnibox/omnibox_field_trial.cc index 0fbf10d993..09c2d1a726 100644 --- a/chrome/browser/omnibox/omnibox_field_trial.cc +++ b/chrome/browser/omnibox/omnibox_field_trial.cc @@ -87,9 +87,8 @@ void OmniboxFieldTrial::ActivateStaticTrials() { // Make it expire on March 1, 2013. scoped_refptr<base::FieldTrial> trial( base::FieldTrialList::FactoryGetFieldTrial( - kHUPCullRedirectsFieldTrialName, kHUPCullRedirectsFieldTrialDivisor, - "Standard", 2013, 3, 1, NULL)); - trial->UseOneTimeRandomization(); + kHUPCullRedirectsFieldTrialName, kHUPCullRedirectsFieldTrialDivisor, + "Standard", 2013, 3, 1, base::FieldTrial::ONE_TIME_RANDOMIZED, NULL)); hup_dont_cull_redirects_experiment_group = trial->AppendGroup("DontCullRedirects", kHUPCullRedirectsFieldTrialExperimentFraction); @@ -98,8 +97,8 @@ void OmniboxFieldTrial::ActivateStaticTrials() { // Make it expire on March 1, 2013. trial = base::FieldTrialList::FactoryGetFieldTrial( kHUPCreateShorterMatchFieldTrialName, - kHUPCreateShorterMatchFieldTrialDivisor, "Standard", 2013, 3, 1, NULL); - trial->UseOneTimeRandomization(); + kHUPCreateShorterMatchFieldTrialDivisor, "Standard", 2013, 3, 1, + base::FieldTrial::ONE_TIME_RANDOMIZED, NULL); hup_dont_create_shorter_match_experiment_group = trial->AppendGroup("DontCreateShorterMatch", kHUPCreateShorterMatchFieldTrialExperimentFraction); diff --git a/chrome/browser/password_manager/password_manager.cc b/chrome/browser/password_manager/password_manager.cc index e1390aa09b..dbeec6b274 100644 --- a/chrome/browser/password_manager/password_manager.cc +++ b/chrome/browser/password_manager/password_manager.cc @@ -311,8 +311,8 @@ void PasswordManager::OnPasswordFormsRendered( if (provisional_save_manager_->HasGeneratedPassword()) UMA_HISTOGRAM_COUNTS("PasswordGeneration.Submitted", 1); - if(!CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableSavePasswordBubble)){ + if (!CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableSavePasswordBubble)) { if (ShouldShowSavePasswordInfoBar()) { delegate_->AddSavePasswordInfoBarIfPermitted( provisional_save_manager_.release()); @@ -344,8 +344,8 @@ void PasswordManager::PossiblyInitializeUsernamesExperiment( scoped_refptr<base::FieldTrial> trial( base::FieldTrialList::FactoryGetFieldTrial( kOtherPossibleUsernamesExperiment, - kDivisor, "Disabled", 2013, 12, 31, NULL)); - trial->UseOneTimeRandomization(); + kDivisor, "Disabled", 2013, 12, 31, + base::FieldTrial::ONE_TIME_RANDOMIZED, NULL)); base::FieldTrial::Probability enabled_probability = 0; switch (chrome::VersionInfo::GetChannel()) { diff --git a/chrome/browser/password_manager/password_manager.h b/chrome/browser/password_manager/password_manager.h index a0dbd7c3da..d65d1c7d44 100644 --- a/chrome/browser/password_manager/password_manager.h +++ b/chrome/browser/password_manager/password_manager.h @@ -134,9 +134,6 @@ class PasswordManager : public LoginModel, // containing WebContents. PasswordManagerDelegate* const delegate_; - // The LoginModelObserver (i.e LoginView) requiring autofill. - LoginModelObserver* observer_; - // Set to false to disable the password manager (will no longer ask if you // want to save passwords but will continue to fill passwords). BooleanPrefMember password_manager_enabled_; diff --git a/chrome/browser/policy/configuration_policy_handler_android.cc b/chrome/browser/policy/configuration_policy_handler_android.cc new file mode 100644 index 0000000000..3dca35fa2f --- /dev/null +++ b/chrome/browser/policy/configuration_policy_handler_android.cc @@ -0,0 +1,103 @@ +// Copyright (c) 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/policy/configuration_policy_handler_android.h" + +#include "base/prefs/pref_value_map.h" +#include "base/values.h" +#include "chrome/browser/policy/policy_error_map.h" +#include "chrome/browser/policy/policy_map.h" +#include "chrome/common/net/url_fixer_upper.h" +#include "chrome/common/pref_names.h" +#include "grit/generated_resources.h" +#include "policy/policy_constants.h" +#include "url/gurl.h" + +namespace policy { + +namespace { + +bool GetBookmark(const base::Value& value, + std::string* name, + std::string* url) { + const base::DictionaryValue* dict = NULL; + if (!value.GetAsDictionary(&dict)) + return false; + std::string url_string; + if (!dict->GetStringWithoutPathExpansion(ManagedBookmarksPolicyHandler::kName, + name) || + !dict->GetStringWithoutPathExpansion(ManagedBookmarksPolicyHandler::kUrl, + &url_string)) { + return false; + } + GURL gurl = URLFixerUpper::FixupURL(url_string, ""); + if (!gurl.is_valid()) + return false; + *url = gurl.spec(); + return true; +} + +} // namespace + +const char ManagedBookmarksPolicyHandler::kName[] = "name"; +const char ManagedBookmarksPolicyHandler::kUrl[] = "url"; + +ManagedBookmarksPolicyHandler::ManagedBookmarksPolicyHandler() + : TypeCheckingPolicyHandler(key::kManagedBookmarks, + base::Value::TYPE_LIST) {} + +ManagedBookmarksPolicyHandler::~ManagedBookmarksPolicyHandler() {} + +bool ManagedBookmarksPolicyHandler::CheckPolicySettings( + const PolicyMap& policies, + PolicyErrorMap* errors) { + const base::Value* value = NULL; + if (!CheckAndGetValue(policies, errors, &value)) + return false; + + if (!value) + return true; + + const base::ListValue* list = NULL; + value->GetAsList(&list); + DCHECK(list); + + for (base::ListValue::const_iterator it = list->begin(); + it != list->end(); ++it) { + std::string name; + std::string url; + if (!*it || !GetBookmark(**it, &name, &url)) { + size_t index = it - list->begin(); + errors->AddError(policy_name(), IDS_POLICY_INVALID_BOOKMARK, index); + } + } + + return true; +} + +void ManagedBookmarksPolicyHandler::ApplyPolicySettings( + const PolicyMap& policies, + PrefValueMap* prefs) { + const base::Value* value = policies.GetValue(policy_name()); + const base::ListValue* list = NULL; + if (!value || !value->GetAsList(&list)) + return; + + base::ListValue* bookmarks = new base::ListValue(); + for (base::ListValue::const_iterator it = list->begin(); + it != list->end(); ++it) { + std::string name; + std::string url; + if (*it && GetBookmark(**it, &name, &url)) { + base::DictionaryValue* dict = new base::DictionaryValue(); + dict->SetString(kName, name); + dict->SetString(kUrl, url); + bookmarks->Append(dict); + } + } + + prefs->SetValue(prefs::kManagedBookmarks, bookmarks); +} + +} // namespace policy diff --git a/chrome/browser/policy/configuration_policy_handler_android.h b/chrome/browser/policy/configuration_policy_handler_android.h new file mode 100644 index 0000000000..b0328d9a6e --- /dev/null +++ b/chrome/browser/policy/configuration_policy_handler_android.h @@ -0,0 +1,39 @@ +// Copyright (c) 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_POLICY_CONFIGURATION_POLICY_HANDLER_ANDROID_H_ +#define CHROME_BROWSER_POLICY_CONFIGURATION_POLICY_HANDLER_ANDROID_H_ + +#include <string> + +#include "chrome/browser/policy/configuration_policy_handler.h" + +namespace base { +class Value; +} + +namespace policy { + +// Handles the ManagedBookmarks policy. +class ManagedBookmarksPolicyHandler : public TypeCheckingPolicyHandler { + public: + static const char kName[]; + static const char kUrl[]; + + ManagedBookmarksPolicyHandler(); + virtual ~ManagedBookmarksPolicyHandler(); + + // ConfigurationPolicyHandler methods: + virtual bool CheckPolicySettings(const PolicyMap& policies, + PolicyErrorMap* errors) OVERRIDE; + virtual void ApplyPolicySettings(const PolicyMap& policies, + PrefValueMap* prefs) OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(ManagedBookmarksPolicyHandler); +}; + +} // namespace policy + +#endif // CHROME_BROWSER_POLICY_CONFIGURATION_POLICY_HANDLER_ANDROID_H_ diff --git a/chrome/browser/policy/configuration_policy_handler_list.cc b/chrome/browser/policy/configuration_policy_handler_list.cc index fec7efa412..47f3a7b7f1 100644 --- a/chrome/browser/policy/configuration_policy_handler_list.cc +++ b/chrome/browser/policy/configuration_policy_handler_list.cc @@ -23,6 +23,10 @@ #include "chromeos/dbus/power_policy_controller.h" #endif // defined(OS_CHROMEOS) +#if defined(OS_ANDROID) +#include "chrome/browser/policy/configuration_policy_handler_android.h" +#endif // defined(OS_ANDROID) + namespace policy { namespace { @@ -570,6 +574,10 @@ ConfigurationPolicyHandlerList::ConfigurationPolicyHandlerList() { NULL, 0, ash::MAGNIFIER_FULL, false)); #endif // defined(OS_CHROMEOS) + +#if defined(OS_ANDROID) + handlers_.push_back(new ManagedBookmarksPolicyHandler()); +#endif } ConfigurationPolicyHandlerList::~ConfigurationPolicyHandlerList() { diff --git a/chrome/browser/policy/profile_policy_connector_factory.cc b/chrome/browser/policy/profile_policy_connector_factory.cc index 774208cea0..9d052606f4 100644 --- a/chrome/browser/policy/profile_policy_connector_factory.cc +++ b/chrome/browser/policy/profile_policy_connector_factory.cc @@ -7,14 +7,14 @@ #include "base/logging.h" #include "chrome/browser/policy/profile_policy_connector.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/common/pref_names.h" #include "components/browser_context_keyed_service/browser_context_dependency_manager.h" +#include "components/user_prefs/pref_registry_syncable.h" #if defined(ENABLE_CONFIGURATION_POLICY) #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/login/user_manager.h" #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.h" -#include "chrome/common/pref_names.h" -#include "components/user_prefs/pref_registry_syncable.h" #else #include "chrome/browser/policy/cloud/user_cloud_policy_manager_factory.h" #endif @@ -116,6 +116,11 @@ void ProfilePolicyConnectorFactory::RegisterProfilePrefs( false, user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); #endif +#if defined(OS_ANDROID) + registry->RegisterListPref( + prefs::kManagedBookmarks, + user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); +#endif } void ProfilePolicyConnectorFactory::SetEmptyTestingFactory( diff --git a/chrome/browser/prerender/prerender_field_trial.cc b/chrome/browser/prerender/prerender_field_trial.cc index ca125228a9..4d04ff6136 100644 --- a/chrome/browser/prerender/prerender_field_trial.cc +++ b/chrome/browser/prerender/prerender_field_trial.cc @@ -56,7 +56,7 @@ void SetupPrefetchFieldTrial() { scoped_refptr<FieldTrial> trial( FieldTrialList::FactoryGetFieldTrial( "Prefetch", divisor, "ContentPrefetchPrefetchOff", - 2013, 12, 31, NULL)); + 2013, 12, 31, FieldTrial::SESSION_RANDOMIZED, NULL)); const int kPrefetchOnGroup = trial->AppendGroup("ContentPrefetchPrefetchOn", prefetch_probability); PrerenderManager::SetIsPrefetchEnabled(trial->group() == kPrefetchOnGroup); @@ -118,7 +118,8 @@ void SetupPrerenderFieldTrial() { scoped_refptr<FieldTrial> trial( FieldTrialList::FactoryGetFieldTrial( "Prerender", divisor, "PrerenderEnabled", - 2013, 12, 31, &prerender_enabled_group)); + 2013, 12, 31, FieldTrial::SESSION_RANDOMIZED, + &prerender_enabled_group)); const int control_group = trial->AppendGroup("PrerenderControl", control_probability); @@ -229,7 +230,8 @@ void ConfigureOmniboxPrerender() { scoped_refptr<FieldTrial> omnibox_prerender_trial( FieldTrialList::FactoryGetFieldTrial( kOmniboxTrialName, kDivisor, "OmniboxPrerenderEnabled", - 2013, 12, 31, &g_omnibox_trial_default_group_number)); + 2013, 12, 31, FieldTrial::SESSION_RANDOMIZED, + &g_omnibox_trial_default_group_number)); omnibox_prerender_trial->AppendGroup("OmniboxPrerenderDisabled", kDisabledProbability); } @@ -242,7 +244,8 @@ void ConfigureLocalPredictor() { } scoped_refptr<FieldTrial> local_predictor_trial( FieldTrialList::FactoryGetFieldTrial( - kLocalPredictorTrialName, 100, kDisabledGroup, 2013, 12, 31, NULL)); + kLocalPredictorTrialName, 100, kDisabledGroup, 2013, 12, 31, + FieldTrial::SESSION_RANDOMIZED, NULL)); local_predictor_trial->AppendGroup(kEnabledGroup, 100); } diff --git a/chrome/browser/profile_resetter/profile_resetter_unittest.cc b/chrome/browser/profile_resetter/profile_resetter_unittest.cc index 0c3b5294a3..b427be9c0d 100644 --- a/chrome/browser/profile_resetter/profile_resetter_unittest.cc +++ b/chrome/browser/profile_resetter/profile_resetter_unittest.cc @@ -4,6 +4,7 @@ #include "chrome/browser/profile_resetter/profile_resetter.h" +#include "base/json/json_string_value_serializer.h" #include "base/prefs/pref_service.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/content_settings/host_content_settings_map.h" @@ -14,6 +15,7 @@ #include "chrome/browser/prefs/session_startup_pref.h" #include "chrome/browser/profile_resetter/brandcode_config_fetcher.h" #include "chrome/browser/profile_resetter/profile_resetter_test_base.h" +#include "chrome/browser/profile_resetter/resettable_settings_snapshot.h" #include "chrome/browser/search_engines/template_url_service.h" #include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/browser/themes/theme_service.h" @@ -613,8 +615,96 @@ TEST_F(ConfigParserTest, ParseConfig) { EXPECT_TRUE((*i)->GetAsString(&url)); startup_pages.push_back(url); } + ASSERT_EQ(2u, startup_pages.size()); EXPECT_EQ("http://goo.gl", startup_pages[0]); EXPECT_EQ("http://foo.de", startup_pages[1]); } +TEST_F(ProfileResetterTest, CheckSnapshots) { + ResettableSettingsSnapshot empty_snap(profile()); + EXPECT_EQ(0, empty_snap.FindDifferentFields(empty_snap)); + + // Reset to non organic defaults. + ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE | + ProfileResetter::HOMEPAGE | + ProfileResetter::STARTUP_PAGES, kDistributionConfig); + + ResettableSettingsSnapshot nonorganic_snap(profile()); + EXPECT_EQ(ResettableSettingsSnapshot::STARTUP_URLS | + ResettableSettingsSnapshot::STARTUP_TYPE | + ResettableSettingsSnapshot::HOMEPAGE | + ResettableSettingsSnapshot::HOMEPAGE_IS_NTP | + ResettableSettingsSnapshot::DSE_URL, + empty_snap.FindDifferentFields(nonorganic_snap)); + empty_snap.SubtractStartupURLs(nonorganic_snap); + EXPECT_TRUE(empty_snap.startup_urls().empty()); + EXPECT_EQ(SessionStartupPref::GetDefaultStartupType(), + empty_snap.startup_type()); + EXPECT_TRUE(empty_snap.homepage().empty()); + EXPECT_TRUE(empty_snap.homepage_is_ntp()); + EXPECT_NE(std::string::npos, empty_snap.dse_url().find("{google:baseURL}")); + + // Reset to organic defaults. + ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE | + ProfileResetter::HOMEPAGE | + ProfileResetter::STARTUP_PAGES); + + ResettableSettingsSnapshot organic_snap(profile()); + EXPECT_EQ(ResettableSettingsSnapshot::STARTUP_URLS | + ResettableSettingsSnapshot::STARTUP_TYPE | + ResettableSettingsSnapshot::HOMEPAGE | + ResettableSettingsSnapshot::HOMEPAGE_IS_NTP | + ResettableSettingsSnapshot::DSE_URL, + nonorganic_snap.FindDifferentFields(organic_snap)); + nonorganic_snap.SubtractStartupURLs(organic_snap); + const GURL urls[] = {GURL("http://foo.de"), GURL("http://goo.gl")}; + EXPECT_EQ(std::vector<GURL>(urls, urls + arraysize(urls)), + nonorganic_snap.startup_urls()); + EXPECT_EQ(SessionStartupPref::URLS, nonorganic_snap.startup_type()); + EXPECT_EQ("http://www.foo.com", nonorganic_snap.homepage()); + EXPECT_FALSE(nonorganic_snap.homepage_is_ntp()); + EXPECT_EQ("http://www.foo.com/s?q={searchTerms}", nonorganic_snap.dse_url()); +} + +TEST_F(ProfileResetterTest, FeedbackSerializtionTest) { + // Reset to non organic defaults. + ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE | + ProfileResetter::HOMEPAGE | + ProfileResetter::STARTUP_PAGES, kDistributionConfig); + + const ResettableSettingsSnapshot nonorganic_snap(profile()); + + COMPILE_ASSERT(ResettableSettingsSnapshot::ALL_FIELDS == 31, + expand_this_test); + for (int field_mask = 0; field_mask <= ResettableSettingsSnapshot::ALL_FIELDS; + ++field_mask) { + std::string report = SerializeSettingsReport(nonorganic_snap, field_mask); + JSONStringValueSerializer json(report); + std::string error; + scoped_ptr<base::Value> root(json.Deserialize(NULL, &error)); + ASSERT_TRUE(root) << error; + ASSERT_TRUE(root->IsType(base::Value::TYPE_DICTIONARY)) << error; + + base::DictionaryValue* dict = + static_cast<base::DictionaryValue*>(root.get()); + + ListValue* startup_urls = NULL; + int startup_type = 0; + std::string homepage; + bool homepage_is_ntp = true; + std::string default_search_engine; + + EXPECT_EQ(!!(field_mask & ResettableSettingsSnapshot::STARTUP_URLS), + dict->GetList("startup_urls", &startup_urls)); + EXPECT_EQ(!!(field_mask & ResettableSettingsSnapshot::STARTUP_TYPE), + dict->GetInteger("startup_type", &startup_type)); + EXPECT_EQ(!!(field_mask & ResettableSettingsSnapshot::HOMEPAGE), + dict->GetString("homepage", &homepage)); + EXPECT_EQ(!!(field_mask & ResettableSettingsSnapshot::HOMEPAGE_IS_NTP), + dict->GetBoolean("homepage_is_ntp", &homepage_is_ntp)); + EXPECT_EQ(!!(field_mask & ResettableSettingsSnapshot::DSE_URL), + dict->GetString("default_search_engine", &default_search_engine)); + } +} + } // namespace diff --git a/chrome/browser/profile_resetter/resettable_settings_snapshot.cc b/chrome/browser/profile_resetter/resettable_settings_snapshot.cc new file mode 100644 index 0000000000..f6892ba30f --- /dev/null +++ b/chrome/browser/profile_resetter/resettable_settings_snapshot.cc @@ -0,0 +1,131 @@ +// Copyright (c) 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/profile_resetter/resettable_settings_snapshot.h" + +#include "base/json/json_writer.h" +#include "base/prefs/pref_service.h" +#include "chrome/browser/feedback/feedback_data.h" +#include "chrome/browser/feedback/feedback_util.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/search_engines/template_url_service.h" +#include "chrome/browser/search_engines/template_url_service_factory.h" +#include "chrome/common/pref_names.h" + +namespace { + +// Feedback bucket label. +const char kProfileResetFeedbackBucket[] = "ProfileResetReport"; + +// Dictionary keys for feedback report. +const char kDefaultSearchEnginePath[] = "default_search_engine"; +const char kHomepageIsNewTabPage[] = "homepage_is_ntp"; +const char kHomepagePath[] = "homepage"; +const char kStartupTypePath[] = "startup_type"; +const char kStartupURLPath[] = "startup_urls"; + +} // namespace + +ResettableSettingsSnapshot::ResettableSettingsSnapshot(Profile* profile) + : startup_(SessionStartupPref::GetStartupPref(profile)) { + // URLs are always stored sorted. + std::sort(startup_.urls.begin(), startup_.urls.end()); + + PrefService* prefs = profile->GetPrefs(); + DCHECK(prefs); + homepage_ = prefs->GetString(prefs::kHomePage); + homepage_is_ntp_ = prefs->GetBoolean(prefs::kHomePageIsNewTabPage); + + TemplateURLService* service = + TemplateURLServiceFactory::GetForProfile(profile); + DCHECK(service); + TemplateURL* dse = service->GetDefaultSearchProvider(); + if (dse) + dse_url_ = dse->url(); +} + +ResettableSettingsSnapshot::~ResettableSettingsSnapshot() {} + +void ResettableSettingsSnapshot::SubtractStartupURLs( + const ResettableSettingsSnapshot& snapshot) { + std::vector<GURL> urls; + std::set_difference(startup_.urls.begin(), startup_.urls.end(), + snapshot.startup_.urls.begin(), + snapshot.startup_.urls.end(), + std::back_inserter(urls)); + startup_.urls.swap(urls); +} + +int ResettableSettingsSnapshot::FindDifferentFields( + const ResettableSettingsSnapshot& snapshot) const { + int bit_mask = 0; + + if (startup_.urls != snapshot.startup_.urls) { + bit_mask |= STARTUP_URLS; + } + + if (startup_.type != snapshot.startup_.type) + bit_mask |= STARTUP_TYPE; + + if (homepage_ != snapshot.homepage_) + bit_mask |= HOMEPAGE; + + if (homepage_is_ntp_ != snapshot.homepage_is_ntp_) + bit_mask |= HOMEPAGE_IS_NTP; + + if (dse_url_ != snapshot.dse_url_) + bit_mask |= DSE_URL; + + COMPILE_ASSERT(ResettableSettingsSnapshot::ALL_FIELDS == 31, + add_new_field_here); + + return bit_mask; +} + +std::string SerializeSettingsReport(const ResettableSettingsSnapshot& snapshot, + int field_mask) { + DictionaryValue dict; + + if (field_mask & ResettableSettingsSnapshot::STARTUP_URLS) { + ListValue* list = new ListValue; + const std::vector<GURL>& urls = snapshot.startup_urls(); + for (std::vector<GURL>::const_iterator i = urls.begin(); + i != urls.end(); ++i) + list->AppendString(i->spec()); + dict.Set(kStartupURLPath, list); + } + + if (field_mask & ResettableSettingsSnapshot::STARTUP_TYPE) + dict.SetInteger(kStartupTypePath, snapshot.startup_type()); + + if (field_mask & ResettableSettingsSnapshot::HOMEPAGE) + dict.SetString(kHomepagePath, snapshot.homepage()); + + if (field_mask & ResettableSettingsSnapshot::HOMEPAGE_IS_NTP) + dict.SetBoolean(kHomepageIsNewTabPage, snapshot.homepage_is_ntp()); + + if (field_mask & ResettableSettingsSnapshot::DSE_URL) + dict.SetString(kDefaultSearchEnginePath, snapshot.dse_url()); + + COMPILE_ASSERT(ResettableSettingsSnapshot::ALL_FIELDS == 31, + serialize_new_field_here); + + std::string json; + base::JSONWriter::Write(&dict, &json); + return json; +} + +void SendSettingsFeedback(const std::string& report, Profile* profile) { + scoped_refptr<FeedbackData> feedback_data = new FeedbackData(); + feedback_data->set_category_tag(kProfileResetFeedbackBucket); + feedback_data->set_description(report); + + feedback_data->set_image(ScreenshotDataPtr()); + feedback_data->set_profile(profile); + + feedback_data->set_page_url(""); + feedback_data->set_user_email(""); + + FeedbackUtil::SendReport(feedback_data); +} diff --git a/chrome/browser/profile_resetter/resettable_settings_snapshot.h b/chrome/browser/profile_resetter/resettable_settings_snapshot.h new file mode 100644 index 0000000000..93aaf4852e --- /dev/null +++ b/chrome/browser/profile_resetter/resettable_settings_snapshot.h @@ -0,0 +1,73 @@ +// Copyright (c) 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_PROFILE_RESETTER_RESETTABLE_SETTINGS_SNAPSHOT_H_ +#define CHROME_BROWSER_PROFILE_RESETTER_RESETTABLE_SETTINGS_SNAPSHOT_H_ + +#include "base/basictypes.h" +#include "chrome/browser/prefs/session_startup_pref.h" + +// ResettableSettingsSnapshot captures some settings values at constructor. It +// can calculate the difference between two snapshots. That is, modified fields. +class ResettableSettingsSnapshot { + public: + // All types of settings handled by this class. + enum Field { + STARTUP_URLS = 1 << 0, + STARTUP_TYPE = 1 << 1, + HOMEPAGE = 1 << 2, + HOMEPAGE_IS_NTP = 1 << 3, + DSE_URL = 1 << 4, + + ALL_FIELDS = STARTUP_URLS | STARTUP_TYPE | HOMEPAGE | + HOMEPAGE_IS_NTP | DSE_URL, + }; + + explicit ResettableSettingsSnapshot(Profile* profile); + ~ResettableSettingsSnapshot(); + + // Getters. + const std::vector<GURL>& startup_urls() const { return startup_.urls; } + + SessionStartupPref::Type startup_type() const { return startup_.type; } + + const std::string& homepage() const { return homepage_; } + + bool homepage_is_ntp() const { return homepage_is_ntp_; } + + const std::string& dse_url() const { return dse_url_; } + + // Substitutes |startup_.urls| with |startup_.urls|\|snapshot.startup_.urls|. + void SubtractStartupURLs(const ResettableSettingsSnapshot& snapshot); + + // For each member 'm' compares |this->m| with |snapshot.m| and sets the + // corresponding |ResetableSettingsSnapshot::Field| bit to 1 in case of + // difference. + // The return value is a bit mask of Field values signifying which members + // were different. + int FindDifferentFields(const ResettableSettingsSnapshot& snapshot) const; + + private: + // Startup pages. URLs are always stored sorted. + SessionStartupPref startup_; + + std::string homepage_; + bool homepage_is_ntp_; + + // Default search engine. + std::string dse_url_; + + DISALLOW_COPY_AND_ASSIGN(ResettableSettingsSnapshot); +}; + +// Serializes specified |snapshot| members to JSON format. |field_mask| is a bit +// mask of ResettableSettingsSnapshot::Field values. +std::string SerializeSettingsReport(const ResettableSettingsSnapshot& snapshot, + int field_mask); + +// Sends |report| as a feedback. |report| is supposed to be result of +// SerializeSettingsReport(). +void SendSettingsFeedback(const std::string& report, Profile* profile); + +#endif // CHROME_BROWSER_PROFILE_RESETTER_RESETTABLE_SETTINGS_SNAPSHOT_H_ diff --git a/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css b/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css index e576c97f08..44d8a2ada9 100644 --- a/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css +++ b/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css @@ -21,7 +21,7 @@ body { * TODO(bshe): Remove this when http://crbug.com/142275 fixed. */ .dialog-topbar #navstrip, -.dialog-topbar #close, +.dialog-topbar #window-close-button, .image-picker, .overlay-container .page, #surprise-me { @@ -84,16 +84,22 @@ body { color: #eee; } -#close { - background-image: url('../images/ui/close-white.png'); +.close { + background-position: center; + background-repeat: no-repeat; height: 14px; + padding: 10px; position: absolute; - right: 10px; - top: 10px; - width: 14px + right: 0; + top: 0; + width: 14px; +} + +#window-close-button { + background-image: url('../images/ui/close-white.png'); } -#close:hover { +#window-close-button:hover { background-image: url('../images/ui/close-white-hover.png'); } @@ -282,16 +288,11 @@ body:not([custom]) [visibleif~='custom'] { z-index: 5; } -.close-overlay { +.overlay-container .close { background-image: url('../images/ui/close-overlay.png'); - height: 14px; - position: absolute; - right: 10px; - top: 10px; - width: 14px } -.close-overlay:hover { +.overlay-container .close:hover { background-image: url('../images/ui/close-overlay-hover.png'); } diff --git a/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_manager.js b/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_manager.js index b9efd3be21..be090ff18d 100644 --- a/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_manager.js +++ b/chrome/browser/resources/chromeos/wallpaper_manager/js/wallpaper_manager.js @@ -269,7 +269,9 @@ function WallpaperManager(dialogDom) { $('wallpaper-grid').classList.remove('image-picker-offline'); }); } - $('close').addEventListener('click', function() {window.close()}); + $('window-close-button').addEventListener('click', function() { + window.close(); + }); this.document_.defaultView.addEventListener( 'resize', this.onResize_.bind(this)); $('learn-more').href = LearnMoreURL; diff --git a/chrome/browser/resources/chromeos/wallpaper_manager/main.html b/chrome/browser/resources/chromeos/wallpaper_manager/main.html index 121acbe2b9..2cff7cb21a 100644 --- a/chrome/browser/resources/chromeos/wallpaper_manager/main.html +++ b/chrome/browser/resources/chromeos/wallpaper_manager/main.html @@ -60,14 +60,14 @@ found in the LICENSE file. <div id="error-container" class="overlay-container" hidden> <div class="page"> - <div id="close-error" class="close-overlay"></div> + <div id="close-error" class="close"></div> <span class="error-message"></span> <a id="learn-more" i18n-content="learnMore" target="_blank"></a> </div> </div> <div id="wallpaper-selection-container" class="overlay-container" hidden> <div class="page"> - <div id="close-wallpaper-selection" class="close-overlay"></div> + <div id="close-wallpaper-selection" class="close"></div> <div id="content"> <input id="file-selector" type="file" size="80" accept="image/jpeg, image/png"> @@ -92,7 +92,7 @@ found in the LICENSE file. <div id="bar"></div> </div> <div class="spacer"></div> - <div id="close"></div> + <div id="window-close-button" class="close"></div> </div> <div class="dialog-main"> <div id="category-container"> diff --git a/chrome/browser/resources/file_manager/js/butter_bar.js b/chrome/browser/resources/file_manager/js/butter_bar.js index 98488bea82..72aa0a470f 100644 --- a/chrome/browser/resources/file_manager/js/butter_bar.js +++ b/chrome/browser/resources/file_manager/js/butter_bar.js @@ -27,10 +27,11 @@ function ButterBar(dialogDom, copyManager, metadataCache) { this.lastProgressValue_ = 0; this.alert_ = new ErrorDialog(this.dialogDom_); - this.copyManager_.addEventListener('copy-progress', - this.onCopyProgress_.bind(this)); - this.copyManager_.addEventListener('delete', - this.onDelete_.bind(this)); + this.onCopyProgressBound_ = this.onCopyProgress_.bind(this); + this.copyManager_.addEventListener( + 'copy-progress', this.onCopyProgressBound_); + this.onDeleteBound_ = this.onDelete_.bind(this); + this.copyManager_.addEventListener('delete', this.onDeleteBound_); } /** @@ -59,6 +60,17 @@ ButterBar.Mode = { }; /** + * Disposes the instance. No methods should be called after this method's + * invocation. + */ +ButterBar.prototype.dispose = function() { + // Unregister listeners from FileCopyManager. + this.copyManager_.removeEventListener( + 'copy-progress', this.onCopyProgressBound_); + this.copyManager_.removeEventListener('delete', this.onDeleteBound_); +}; + +/** * @return {boolean} True if visible. * @private */ diff --git a/chrome/browser/resources/file_manager/js/file_copy_manager.js b/chrome/browser/resources/file_manager/js/file_copy_manager.js index 3f6aa7a21e..d62889fa68 100644 --- a/chrome/browser/resources/file_manager/js/file_copy_manager.js +++ b/chrome/browser/resources/file_manager/js/file_copy_manager.js @@ -14,7 +14,8 @@ function FileCopyManager() { this.cancelRequested_ = false; this.cancelCallback_ = null; this.unloadTimeout_ = null; - this.listeners_ = []; + + this.eventRouter_ = new FileCopyManager.EventRouter(); } /** @@ -31,6 +32,76 @@ FileCopyManager.getInstance = function() { }; /** + * Manages cr.Event dispatching. + * Currently this can send three types of events: "copy-progress", + * "copy-operation-completed" and "delete". + * + * TODO(hidehiko): Reorganize the event dispatching mechanism. + * @constructor + * @extends {cr.EventTarget} + */ +FileCopyManager.EventRouter = function() { +}; + +/** + * Extends cr.EventTarget. + */ +FileCopyManager.EventRouter.prototype.__proto__ = cr.EventTarget.prototype; + +/** + * Dispatches a simple "copy-progress" event with reason and current + * FileCopyManager status. If it is an ERROR event, error should be set. + * + * @param {string} reason Event type. One of "BEGIN", "PROGRESS", "SUCCESS", + * "ERROR" or "CANCELLED". TODO(hidehiko): Use enum. + * @param {Object} status Current FileCopyManager's status. See also + * FileCopyManager.getStatus(). + * @param {FileCopyManager.Error=} opt_error The info for the error. This + * should be set iff the reason is "ERROR". + */ +FileCopyManager.EventRouter.prototype.sendProgressEvent = function( + reason, status, opt_error) { + var event = new cr.Event('copy-progress'); + event.reason = reason; + event.status = status; + if (opt_error) + event.error = opt.error; + this.dispatchEvent(event); +}; + +/** + * Dispatches an event to notify that the entries in affectedEntries are + * changed (created or deleted) by operation reason. + * + * @param {string} reason Completed file operation. One of "moved", "copied" + * or "deleted". TODO(hidehiko): Use enum. + * @param {Array.<Entry>} affectedEntries Entries which are created or deleted. + */ +FileCopyManager.EventRouter.prototype.sendOperationEvent = function( + reason, affectedEntries) { + var event = new cr.Event('copy-operation-complete'); + event.reason = reason; + event.affectedEntries = affectedEntries; + this.dispatchEvent(event); +}; + +/** + * Dispatches an event to notify entries are changed for delete task. + * + * @param {string} reason Event type. One of "BEGIN", "PROGRESS", "SUCCESS", + * or "ERROR". TODO(hidehiko): Use enum. + * @param {Array.<string>} urls An array of URLs which are affected by delete + * operation. + */ +FileCopyManager.EventRouter.prototype.sendDeleteEvent = function( + reason, urls) { + var event = new cr.Event('delete'); + event.reason = reason; + event.urls = urls; + this.dispatchEvent(event); +}; + +/** * A record of a queued copy operation. * * Multiple copy operations may be queued at any given time. Additional @@ -358,39 +429,22 @@ FileCopyManager.prototype.getStatus = function() { }; /** - * Send an event to all the FileManager windows. - * - * @param {string} eventName Event name. - * @param {Object} eventArgs An object with arbitrary event parameters. - * @private - */ -FileCopyManager.prototype.sendEvent_ = function(eventName, eventArgs) { - if (this.cancelRequested_) - return; // Swallow events until cancellation complete. - - eventArgs.status = this.getStatus(); - for (var i = 0; i < this.listeners_.length; ++i) { - this.listeners_[i](eventName, eventArgs); - } -}; - -/** - * Adds a listener for running task events. - * @param {function(string, Object)} listener A listener to be added. + * Adds an event listener for the tasks. + * @param {string} type The name of the event. + * @param {function(cr.Event)} handler The handler for the event. + * This is called when the event is dispatched. */ -FileCopyManager.prototype.addListener = function(listener) { - this.listeners_.push(listener); +FileCopyManager.prototype.addEventListener = function(type, handler) { + this.eventRouter_.addEventListener(type, handler); }; /** - * Removes the listener for running task events. If the listener is not added - * by addListener(), it is simply ignored. - * @param {function(string, Object)} listener A listener to be removed. + * Removes an event listener for the tasks. + * @param {string} type The name of the event. + * @param {function(cr.Event)} handler The handler to be removed. */ -FileCopyManager.prototype.removeListener = function(listener) { - var index = this.listeners_.indexOf(listener); - if (index >= 0) - this.listeners_.splice(index, 1); +FileCopyManager.prototype.removeEventListener = function(type, handler) { + this.eventRouter_.removeEventListener(type, handler); }; /** @@ -419,36 +473,6 @@ FileCopyManager.prototype.maybeScheduleCloseBackgroundPage_ = function() { }; /** - * Dispatch a simple copy-progress event with reason and optional err data. - * - * @param {string} reason Event type. - * @param {FileCopyManager.Error=} opt_err Error. - * @private - */ -FileCopyManager.prototype.sendProgressEvent_ = function(reason, opt_err) { - var event = {}; - event.reason = reason; - if (opt_err) - event.error = opt_err; - this.sendEvent_('copy-progress', event); -}; - -/** - * Dispatch an event of file operation completion (allows to update the UI). - * - * @private - * @param {string} reason Completed file operation: 'movied|copied|deleted'. - * @param {Array.<Entry>} affectedEntries deleted ot created entries. - */ -FileCopyManager.prototype.sendOperationEvent_ = function(reason, - affectedEntries) { - var event = {}; - event.reason = reason; - event.affectedEntries = affectedEntries; - this.sendEvent_('copy-operation-complete', event); -}; - -/** * Completely clear out the copy queue, either because we encountered an error * or completed successfully. * @@ -489,7 +513,7 @@ FileCopyManager.prototype.requestCancel = function(opt_callback) { FileCopyManager.prototype.doCancel_ = function() { this.resetQueue_(); this.cancelRequested_ = false; - this.sendProgressEvent_('CANCELLED'); + this.eventRouter_.sendProgressEvent('CANCELLED', this.getStatus()); }; /** @@ -576,8 +600,9 @@ FileCopyManager.prototype.paste = function(files, directories, isCut, isOnDrive, }, onPathError: function(err) { - self.sendProgressEvent_( + self.eventRouter_.sendProgressEvent( 'ERROR', + self.getStatus(), new FileCopyManager.Error( util.FileOperationErrorType.FILESYSTEM_ERROR, err)); } @@ -638,7 +663,7 @@ FileCopyManager.prototype.queueCopy_ = function(targetDirEntry, } else { // Force to update the progress of butter bar when there are new tasks // coming while servicing current task. - self.sendProgressEvent_('PROGRESS'); + self.eventRouter_.sendProgressEvent('PROGRESS', self.getStatus()); } }); @@ -657,7 +682,7 @@ FileCopyManager.prototype.serviceAllTasks_ = function() { var onTaskError = function(err) { if (self.maybeCancel_()) return; - self.sendProgressEvent_('ERROR', err); + self.eventRouter_.sendProgressEvent('ERROR', self.getStatus(), err); self.resetQueue_(); }; @@ -671,7 +696,7 @@ FileCopyManager.prototype.serviceAllTasks_ = function() { if (!self.copyTasks_.length) { // All tasks have been serviced, clean up and exit. - self.sendProgressEvent_('SUCCESS'); + self.eventRouter_.sendProgressEvent('SUCCESS', self.getStatus()); self.resetQueue_(); return; } @@ -680,7 +705,7 @@ FileCopyManager.prototype.serviceAllTasks_ = function() { // right after one task finished in the queue. We treat all tasks as one // big task logically, so there is only one BEGIN/SUCCESS event pair for // these continuous tasks. - self.sendProgressEvent_('PROGRESS'); + self.eventRouter_.sendProgressEvent('PROGRESS', self.getStatus()); self.serviceTask_(self.copyTasks_[0], onTaskSuccess, onTaskError); }; @@ -688,7 +713,7 @@ FileCopyManager.prototype.serviceAllTasks_ = function() { // If the queue size is 1 after pushing our task, it was empty before, // so we need to kick off queue processing and dispatch BEGIN event. - this.sendProgressEvent_('BEGIN'); + this.eventRouter_.sendProgressEvent('BEGIN', this.getStatus()); this.serviceTask_(this.copyTasks_[0], onTaskSuccess, onTaskError); }; @@ -732,7 +757,7 @@ FileCopyManager.prototype.serviceCopyTask_ = function( var count = task.originalEntries.length; var onEntryDeleted = function(entry) { - self.sendOperationEvent_('deleted', [entry]); + self.eventRouter_.sendOperationEvent('deleted', [entry]); count--; if (!count) successCallback(); @@ -762,7 +787,7 @@ FileCopyManager.prototype.serviceCopyTask_ = function( return; } - self.sendProgressEvent_('PROGRESS'); + self.eventRouter_.sendProgressEvent('PROGRESS', self.getStatus()); self.serviceNextCopyTaskEntry_(task, onEntryServiced, errorCallback); }; @@ -813,13 +838,13 @@ FileCopyManager.prototype.serviceNextCopyTaskEntry_ = function( }; var onCopyComplete = function(entry, size) { - self.sendOperationEvent_('copied', [entry]); + self.eventRouter_.sendOperationEvent('copied', [entry]); onCopyCompleteBase(entry, size); }; var onCopyProgress = function(entry, size) { task.updateFileCopyProgress(entry, size); - self.sendProgressEvent_('PROGRESS'); + self.eventRouter_.sendProgressEvent('PROGRESS', self.getStatus()); }; var onFilesystemCopyComplete = function(sourceEntry, targetEntry) { @@ -827,7 +852,7 @@ FileCopyManager.prototype.serviceNextCopyTaskEntry_ = function( // copied by FileEntry.copyTo(), so task.completedBytes will not be // increased. We will address this issue once we need to use // task.completedBytes to track the progress. - self.sendOperationEvent_('copied', [sourceEntry, targetEntry]); + self.eventRouter_.sendOperationEvent('copied', [sourceEntry, targetEntry]); onCopyCompleteBase(targetEntry, 0); }; @@ -1004,7 +1029,7 @@ FileCopyManager.prototype.serviceMoveTask_ = function( } // Move the next entry. - this.sendProgressEvent_('PROGRESS'); + this.eventRouter_.sendProgressEvent('PROGRESS', this.getStatus()); this.serviceNextMoveTaskEntry_( task, onCompleted.bind(this), errorCallback); }).bind(this), @@ -1070,7 +1095,7 @@ FileCopyManager.prototype.serviceNextMoveTaskEntry_ = function( sourceEntry.moveTo( dirEntry, PathUtil.basename(targetRelativePath), function(targetEntry) { - self.sendOperationEvent_( + self.eventRouter_.sendOperationEvent( 'moved', [sourceEntry, targetEntry]); task.markEntryComplete(targetEntry, 0); successCallback(); @@ -1112,7 +1137,7 @@ FileCopyManager.prototype.serviceZipTask_ = function( var onDeduplicated = function(destPath) { var onZipSelectionComplete = function(success) { if (success) { - self.sendProgressEvent_('SUCCESS'); + self.eventRouter_.sendProgressEvent('SUCCESS', self.getStatus()); successCallback(); } else { errorCallback(new FileCopyManager.Error( @@ -1125,7 +1150,7 @@ FileCopyManager.prototype.serviceZipTask_ = function( } }; - self.sendProgressEvent_('PROGRESS'); + self.eventRouter_.sendProgressEvent('PROGRESS', self.getStatus()); chrome.fileBrowserPrivate.zipSelection(dirURL, selectionURLs, destPath, onZipSelectionComplete); }; @@ -1228,7 +1253,11 @@ FileCopyManager.prototype.serviceAllDeleteTasks_ = function() { self.deleteTasks_.shift(); if (!self.deleteTasks_.length) { // All tasks have been serviced, clean up and exit. - self.sendDeleteEvent_(task, 'SUCCESS'); + self.eventRouter_.sendDeleteEvent( + 'SUCCESS', + task.entries.map(function(e) { + return util.makeFilesystemUrl(e.fullPath); + })); self.maybeScheduleCloseBackgroundPage_(); return; } @@ -1237,19 +1266,31 @@ FileCopyManager.prototype.serviceAllDeleteTasks_ = function() { // right after one task finished in the queue. We treat all tasks as one // big task logically, so there is only one BEGIN/SUCCESS event pair for // these continuous tasks. - self.sendDeleteEvent_(self.deleteTasks_[0], 'PROGRESS'); + self.eventRouter_.sendDeleteEvent( + 'PROGRESS', + task.entries.map(function(e) { + return util.makeFilesystemUrl(e.fullPath); + })); self.serviceDeleteTask_(self.deleteTasks_[0], onTaskSuccess, onTaskFailure); }; var onTaskFailure = function(task) { self.deleteTasks_ = []; - self.sendDeleteEvent_(task, 'ERROR'); + self.eventRouter_.sendDeleteEvent( + 'ERROR', + task.entries.map(function(e) { + return util.makeFilesystemUrl(e.fullPath); + })); self.maybeScheduleCloseBackgroundPage_(); }; // If the queue size is 1 after pushing our task, it was empty before, // so we need to kick off queue processing and dispatch BEGIN event. - this.sendDeleteEvent_(this.deleteTasks_[0], 'BEGIN'); + this.eventRouter_.sendDeleteEvent( + 'BEGIN', + this.deleteTasks_[0].entries.map(function(e) { + return util.makeFilesystemUrl(e.fullPath); + })); this.serviceDeleteTask_(this.deleteTasks_[0], onTaskSuccess, onTaskFailure); }; @@ -1290,22 +1331,6 @@ FileCopyManager.prototype.serviceDeleteTask_ = function( }; /** - * Send a 'delete' event to listeners. - * - * @param {Object} task The delete task (see deleteEntries function). - * @param {string} reason Event reason. - * @private - */ -FileCopyManager.prototype.sendDeleteEvent_ = function(task, reason) { - this.sendEvent_('delete', { - reason: reason, - urls: task.entries.map(function(e) { - return util.makeFilesystemUrl(e.fullPath); - }) - }); -}; - -/** * Creates a zip file for the selection of files. * * @param {Entry} dirEntry the directory containing the selection. @@ -1330,7 +1355,7 @@ FileCopyManager.prototype.zipSelection = function(dirEntry, isOnDrive, } else { // Force to update the progress of butter bar when there are new tasks // coming while servicing current task. - self.sendProgressEvent_('PROGRESS'); + self.eventRouter_.sendProgressEvent('PROGRESS', self.getStatus()); } }); }; diff --git a/chrome/browser/resources/file_manager/js/file_copy_manager_wrapper.js b/chrome/browser/resources/file_manager/js/file_copy_manager_wrapper.js index b0206e61aa..6642e7e9c6 100644 --- a/chrome/browser/resources/file_manager/js/file_copy_manager_wrapper.js +++ b/chrome/browser/resources/file_manager/js/file_copy_manager_wrapper.js @@ -23,13 +23,6 @@ function FileCopyManagerWrapper() { */ this.pendingTasks_ = []; - // Keep the instance for unloading. - var onEventBound = this.onEventBound_ = this.onEvent_.bind(this); - this.pendingTasks_.push( - function(fileCopyManager) { - fileCopyManager.addListener(onEventBound); - }); - chrome.runtime.getBackgroundPage(function(backgroundPage) { var fileCopyManager = backgroundPage.FileCopyManager.getInstance(); fileCopyManager.initialize(function() { @@ -45,11 +38,6 @@ function FileCopyManagerWrapper() { } /** - * Extending cr.EventTarget. - */ -FileCopyManagerWrapper.prototype.__proto__ = cr.EventTarget.prototype; - -/** * Create a new instance or get existing instance of FCMW. * @return {FileCopyManagerWrapper} A FileCopyManagerWrapper instance. */ @@ -61,34 +49,6 @@ FileCopyManagerWrapper.getInstance = function() { }; /** - * Disposes the instance. No methods should be called after this method's - * invocation. - */ -FileCopyManagerWrapper.prototype.dispose = function() { - // Cancel all pending tasks. - this.pendingTasks_ = []; - - // Unregister the listener to avoid resource leaking. - if (this.fileCopyManager_) - this.fileCopyManager_.removeListener(this.onEventBound_); -}; - -/** - * Called be FileCopyManager to raise an event in this instance of FileManager. - * @param {string} eventName Event name. - * @param {Object} eventArgs Arbitratry field written to event object. - * @private - */ -FileCopyManagerWrapper.prototype.onEvent_ = function(eventName, eventArgs) { - var event = new cr.Event(eventName); - for (var arg in eventArgs) - if (eventArgs.hasOwnProperty(arg)) - event[arg] = eventArgs[arg]; - - this.dispatchEvent(event); -}; - -/** * @return {boolean} True if there is a running task. */ FileCopyManagerWrapper.prototype.isRunning = function() { @@ -126,3 +86,5 @@ FileCopyManagerWrapper.decorateAsyncMethod('deleteEntries'); FileCopyManagerWrapper.decorateAsyncMethod('forceDeleteTask'); FileCopyManagerWrapper.decorateAsyncMethod('cancelDeleteTask'); FileCopyManagerWrapper.decorateAsyncMethod('zipSelection'); +FileCopyManagerWrapper.decorateAsyncMethod('addEventListener'); +FileCopyManagerWrapper.decorateAsyncMethod('removeEventListener'); diff --git a/chrome/browser/resources/file_manager/js/file_manager.js b/chrome/browser/resources/file_manager/js/file_manager.js index c3b2c94724..f16c187f62 100644 --- a/chrome/browser/resources/file_manager/js/file_manager.js +++ b/chrome/browser/resources/file_manager/js/file_manager.js @@ -430,10 +430,17 @@ var BOTTOM_MARGIN_FOR_PREVIEW_PANEL_PX = 52; // Open and Save dialogs. But drag-n-drop and copy-paste are not needed. if (this.dialogType != DialogType.FULL_PAGE) return; - this.copyManager_.addEventListener('copy-progress', - this.onCopyProgress_.bind(this)); - this.copyManager_.addEventListener('copy-operation-complete', - this.onCopyManagerOperationComplete_.bind(this)); + // TODO(hidehiko): Extract FileCopyManager related code from FileManager + // to simplify it. + this.onCopyProgressBound_ = this.onCopyProgress_.bind(this); + this.copyManager_.addEventListener( + 'copy-progress', this.onCopyProgressBound_); + + this.onCopyManagerOperationCompleteBound_ = + this.onCopyManagerOperationComplete_.bind(this); + this.copyManager_.addEventListener( + 'copy-operation-complete', + this.onCopyManagerOperationCompleteBound_); var controller = this.fileTransferController_ = new FileTransferController(this.document_, @@ -549,13 +556,13 @@ var BOTTOM_MARGIN_FOR_PREVIEW_PANEL_PX = 52; var doc = this.document_; - CommandUtil.registerCommand(doc, 'newfolder', + CommandUtil.registerCommand(this.dialogContainer_, 'newfolder', Commands.newFolderCommand, this, this.directoryModel_); - CommandUtil.registerCommand(doc, 'newwindow', + CommandUtil.registerCommand(this.dialogContainer_, 'newwindow', Commands.newWindowCommand, this, this.directoryModel_); - CommandUtil.registerCommand(doc, 'change-default-app', + CommandUtil.registerCommand(this.dialogContainer_, 'change-default-app', Commands.changeDefaultAppCommand, this); CommandUtil.registerCommand(this.volumeList_, 'unmount', @@ -564,53 +571,58 @@ var BOTTOM_MARGIN_FOR_PREVIEW_PANEL_PX = 52; CommandUtil.registerCommand(this.volumeList_, 'import-photos', Commands.importCommand, this.volumeList_); - CommandUtil.registerCommand(doc, 'format', + CommandUtil.registerCommand(this.dialogContainer_, 'format', Commands.formatCommand, this.volumeList_, this, this.directoryModel_); - CommandUtil.registerCommand(doc, 'delete', + CommandUtil.registerCommand(this.dialogContainer_, 'delete', Commands.deleteFileCommand, this); - CommandUtil.registerCommand(doc, 'rename', + CommandUtil.registerCommand(this.dialogContainer_, 'rename', Commands.renameFileCommand, this); - CommandUtil.registerCommand(doc, 'volume-help', + CommandUtil.registerCommand(this.dialogContainer_, 'volume-help', Commands.volumeHelpCommand, this); - CommandUtil.registerCommand(doc, 'drive-buy-more-space', + CommandUtil.registerCommand(this.dialogContainer_, 'drive-buy-more-space', Commands.driveBuySpaceCommand, this); - CommandUtil.registerCommand(doc, 'drive-clear-local-cache', - Commands.driveClearCacheCommand, this); + CommandUtil.registerCommand(this.dialogContainer_, + 'drive-clear-local-cache', Commands.driveClearCacheCommand, this); - CommandUtil.registerCommand(doc, 'drive-go-to-drive', + CommandUtil.registerCommand(this.dialogContainer_, 'drive-go-to-drive', Commands.driveGoToDriveCommand, this); - CommandUtil.registerCommand(doc, 'paste', + CommandUtil.registerCommand(this.dialogContainer_, 'paste', Commands.pasteFileCommand, doc, this.fileTransferController_); - CommandUtil.registerCommand(doc, 'open-with', + CommandUtil.registerCommand(this.dialogContainer_, 'open-with', Commands.openWithCommand, this); - CommandUtil.registerCommand(doc, 'toggle-pinned', + CommandUtil.registerCommand(this.dialogContainer_, 'toggle-pinned', Commands.togglePinnedCommand, this); - CommandUtil.registerCommand(doc, 'zip-selection', + CommandUtil.registerCommand(this.dialogContainer_, 'zip-selection', Commands.zipSelectionCommand, this, this.directoryModel_); - CommandUtil.registerCommand(doc, 'share', Commands.shareCommand, this); - CommandUtil.registerCommand(doc, 'create-folder-shortcut', - Commands.createFolderShortcutCommand, this); - CommandUtil.registerCommand(doc, 'remove-folder-shortcut', - Commands.removeFolderShortcutCommand, this, this.volumeList_); + CommandUtil.registerCommand(this.dialogContainer_, 'share', + Commands.shareCommand, this); - CommandUtil.registerCommand(doc, 'search', Commands.searchCommand, this, + CommandUtil.registerCommand(this.dialogContainer_, + 'create-folder-shortcut', Commands.createFolderShortcutCommand, this); + + CommandUtil.registerCommand(this.dialogContainer_, + 'remove-folder-shortcut', Commands.removeFolderShortcutCommand, this, + this.volumeList_); + + CommandUtil.registerCommand(this.dialogContainer_, 'search', + Commands.searchCommand, this, this.dialogDom_.querySelector('#search-box')); // Register commands with CTRL-1..9 shortcuts for switching between // volumes. for (var i = 1; i <= 9; i++) { - CommandUtil.registerCommand(doc, + CommandUtil.registerCommand(this.dialogContainer_, 'volume-switch-' + i, Commands.volumeSwitchCommand, this.volumeList_, @@ -2457,11 +2469,21 @@ var BOTTOM_MARGIN_FOR_PREVIEW_PANEL_PX = 52; this.directoryModel_.dispose(); if (this.filePopup_ && this.filePopup_.contentWindow && - this.filePopup_.contentWindow.unload) { + this.filePopup_.contentWindow.unload) this.filePopup_.contentWindow.unload(true /* exiting */); + if (this.butterBar_) + this.butterBar_.dispose(); + if (this.copyManager_) { + if (this.onCopyProgressBound_) { + this.copyManager_.removeEventListener( + 'copy-progress', this.onCopyProgressBound_); + } + if (this.onCopyManagerOperationCompleteBound_) { + this.copyManager_.removeEventListener( + 'copy-operation-complete', + this.onCopyManagerOperationCompleteBound_); + } } - if (this.copyManager_) - this.copyManager_.dispose(); }; FileManager.prototype.initiateRename = function() { diff --git a/chrome/browser/resources/file_manager/manifest.json b/chrome/browser/resources/file_manager/manifest.json index 503bce93c5..72b0db2199 100644 --- a/chrome/browser/resources/file_manager/manifest.json +++ b/chrome/browser/resources/file_manager/manifest.json @@ -222,6 +222,8 @@ "app": { "background": { "scripts": [ + "chrome://resources/js/cr.js", + "chrome://resources/js/cr/event_target.js", "js/file_copy_manager.js", "js/async_util.js", "js/path_util.js", diff --git a/chrome/browser/resources/history/other_devices.js b/chrome/browser/resources/history/other_devices.js index 3224bdb7d1..4ae595dc7a 100644 --- a/chrome/browser/resources/history/other_devices.js +++ b/chrome/browser/resources/history/other_devices.js @@ -256,8 +256,7 @@ Device.prototype.createSessionContents_ = function(maxNumTabs) { numTabsShown++; var a = createElementWithClassName('a', 'device-tab-entry'); a.href = tab.url; - a.style.backgroundImage = - getFaviconImageSet(tab.url, 16, 'session-favicon'); + a.style.backgroundImage = getFaviconImageSet(tab.url); this.addHighlightedText_(a, tab.title); // Add a tooltip, since it might be ellipsized. The ones that are not // necessary will be removed once added to the document, so we can diff --git a/chrome/browser/resources/ntp4/other_sessions.js b/chrome/browser/resources/ntp4/other_sessions.js index fba1225efe..1e731beaad 100644 --- a/chrome/browser/resources/ntp4/other_sessions.js +++ b/chrome/browser/resources/ntp4/other_sessions.js @@ -213,8 +213,7 @@ cr.define('ntp', function() { a.className = 'footer-menu-item'; a.textContent = tab.title; a.href = tab.url; - a.style.backgroundImage = - getFaviconImageSet(tab.url, 16, 'session-favicon'); + a.style.backgroundImage = getFaviconImageSet(tab.url); var clickHandler = this.makeClickHandler_( session.tag, String(window.sessionId), String(tab.sessionId)); diff --git a/chrome/browser/resources/ntp_android/ntp_android.js b/chrome/browser/resources/ntp_android/ntp_android.js index 9ec3a10ac8..214abd8ef1 100644 --- a/chrome/browser/resources/ntp_android/ntp_android.js +++ b/chrome/browser/resources/ntp_android/ntp_android.js @@ -1826,8 +1826,7 @@ cr.define('ntp', function() { // use a section divider. var needSectionDivider = (tabNum + 1 == tabs.length) && (winNum + 1 < windows.length); - tab.icon = tab.icon || - 'chrome://session-favicon/size/16@1x/' + tab.url; + tab.icon = tab.icon || 'chrome://favicon/size/16@1x/' + tab.url; openTabsList.push({ timestamp: tab.timestamp, diff --git a/chrome/browser/resources/options/reset_profile_settings_overlay.css b/chrome/browser/resources/options/reset_profile_settings_overlay.css index 9fa3b8e03b..f8b838c3dc 100644 --- a/chrome/browser/resources/options/reset_profile_settings_overlay.css +++ b/chrome/browser/resources/options/reset_profile_settings_overlay.css @@ -11,3 +11,13 @@ vertical-align: middle; visibility: hidden; } + +.feedback-area { + background-color: #f5f5f5; + border-color: #e7e7e7; + border-top-style: solid; + border-width: 1px; + color: #888; + display: -webkit-box; + padding: 14px 17px; +} diff --git a/chrome/browser/resources/options/reset_profile_settings_overlay.html b/chrome/browser/resources/options/reset_profile_settings_overlay.html index f0150c60de..b2fa0bceee 100644 --- a/chrome/browser/resources/options/reset_profile_settings_overlay.html +++ b/chrome/browser/resources/options/reset_profile_settings_overlay.html @@ -21,4 +21,9 @@ </div> </div> </div> + <div class="feedback-area checkbox"> + <input id="send-settings" type="checkbox" checked=true> + <label for="send-settings" i18n-content="resetProfileSettingsFeedback"> + </label> + </div> </div> diff --git a/chrome/browser/resources/options/reset_profile_settings_overlay.js b/chrome/browser/resources/options/reset_profile_settings_overlay.js index 8216643fa3..61766d4db7 100644 --- a/chrome/browser/resources/options/reset_profile_settings_overlay.js +++ b/chrome/browser/resources/options/reset_profile_settings_overlay.js @@ -34,7 +34,8 @@ cr.define('options', function() { }; $('reset-profile-settings-commit').onclick = function(event) { ResetProfileSettingsOverlay.setResettingState(true); - chrome.send('performResetProfileSettings'); + chrome.send('performResetProfileSettings', + [$('send-settings').checked]); }; }, diff --git a/chrome/browser/resources/sync_setup_overlay.css b/chrome/browser/resources/sync_setup_overlay.css index 4430bb681f..12457b5f67 100644 --- a/chrome/browser/resources/sync_setup_overlay.css +++ b/chrome/browser/resources/sync_setup_overlay.css @@ -110,6 +110,11 @@ margin-bottom: 5px; } +#basic-encryption-body, +#full-encryption-body { + display: table; +} + #passphrase-input { margin-bottom: 5px; margin-top: 5px; diff --git a/chrome/browser/resources/sync_setup_overlay.html b/chrome/browser/resources/sync_setup_overlay.html index 7a37299aba..fba395b809 100644 --- a/chrome/browser/resources/sync_setup_overlay.html +++ b/chrome/browser/resources/sync_setup_overlay.html @@ -118,7 +118,8 @@ <label> <input id="basic-encryption-option" name="encrypt-new" type="radio" value="full"> - <span i18n-content="basicEncryptionOption"></span> + <span id="basic-encryption-body" + i18n-content="basicEncryptionOption"></span> </label> </div> <div class="radio"> diff --git a/chrome/browser/ui/app_list/search/omnibox_provider.cc b/chrome/browser/ui/app_list/search/omnibox_provider.cc index 0869c20c9f..18656b670e 100644 --- a/chrome/browser/ui/app_list/search/omnibox_provider.cc +++ b/chrome/browser/ui/app_list/search/omnibox_provider.cc @@ -6,9 +6,11 @@ #include "chrome/browser/autocomplete/autocomplete_classifier.h" #include "chrome/browser/autocomplete/autocomplete_controller.h" +#include "chrome/browser/autocomplete/autocomplete_input.h" #include "chrome/browser/autocomplete/autocomplete_match.h" #include "chrome/browser/ui/app_list/search/chrome_search_result.h" #include "chrome/browser/ui/browser_navigator.h" +#include "chrome/common/metrics/proto/omnibox_event.pb.h" #include "grit/theme_resources.h" #include "ui/base/resource/resource_bundle.h" @@ -143,6 +145,7 @@ void OmniboxProvider::Start(const base::string16& query) { base::string16::npos, base::string16(), GURL(), + AutocompleteInput::INVALID_SPEC, false, false, true, diff --git a/chrome/browser/ui/bookmarks/bookmark_prompt_controller.cc b/chrome/browser/ui/bookmarks/bookmark_prompt_controller.cc index 99863836b9..6013a1be95 100644 --- a/chrome/browser/ui/bookmarks/bookmark_prompt_controller.cc +++ b/chrome/browser/ui/bookmarks/bookmark_prompt_controller.cc @@ -229,8 +229,9 @@ bool BookmarkPromptController::IsEnabled() { kBookmarkPromptTrialName, 100, kBookmarkPromptDefaultGroup, date_range->expiration_date.year, date_range->expiration_date.month, - date_range->expiration_date.day_of_month, NULL)); - trial->UseOneTimeRandomization(); + date_range->expiration_date.day_of_month, + base::FieldTrial::ONE_TIME_RANDOMIZED, + NULL)); trial->AppendGroup(kBookmarkPromptControlGroup, 10); trial->AppendGroup(kBookmarkPromptExperimentGroup, 10); diff --git a/chrome/browser/ui/omnibox/omnibox_controller.cc b/chrome/browser/ui/omnibox/omnibox_controller.cc index b5b7117f8f..31ae5e59ec 100644 --- a/chrome/browser/ui/omnibox/omnibox_controller.cc +++ b/chrome/browser/ui/omnibox/omnibox_controller.cc @@ -40,6 +40,7 @@ void OmniboxController::StartAutocomplete( string16 user_text, size_t cursor_position, const GURL& current_url, + AutocompleteInput::PageClassification current_page_classification, bool prevent_inline_autocomplete, bool prefer_keyword, bool allow_exact_keyword_match, @@ -56,7 +57,8 @@ void OmniboxController::StartAutocomplete( // Start ends up invoking OmniboxPopupModel::OnResultChanged which clears it. autocomplete_controller_->Start(AutocompleteInput( user_text, cursor_position, string16(), current_url, - prevent_inline_autocomplete, prefer_keyword, allow_exact_keyword_match, + current_page_classification, prevent_inline_autocomplete, + prefer_keyword, allow_exact_keyword_match, AutocompleteInput::ALL_MATCHES)); } diff --git a/chrome/browser/ui/omnibox/omnibox_controller.h b/chrome/browser/ui/omnibox/omnibox_controller.h index 690acab2fe..977bd4c1d5 100644 --- a/chrome/browser/ui/omnibox/omnibox_controller.h +++ b/chrome/browser/ui/omnibox/omnibox_controller.h @@ -11,6 +11,7 @@ #include "base/strings/string16.h" #include "chrome/browser/autocomplete/autocomplete_controller.h" #include "chrome/browser/autocomplete/autocomplete_controller_delegate.h" +#include "chrome/browser/autocomplete/autocomplete_input.h" #include "chrome/browser/autocomplete/autocomplete_match.h" struct AutocompleteMatch; @@ -40,13 +41,15 @@ class OmniboxController : public AutocompleteControllerDelegate { virtual ~OmniboxController(); // |current_url| is only set for mobile ports. - void StartAutocomplete(string16 user_text, - size_t cursor_position, - const GURL& current_url, - bool prevent_inline_autocomplete, - bool prefer_keyword, - bool allow_exact_keyword_match, - int omnibox_start_margin) const; + void StartAutocomplete( + string16 user_text, + size_t cursor_position, + const GURL& current_url, + AutocompleteInput::PageClassification current_page_classification, + bool prevent_inline_autocomplete, + bool prefer_keyword, + bool allow_exact_keyword_match, + int omnibox_start_margin) const; // AutocompleteControllerDelegate: virtual void OnResultChanged(bool default_match_changed) OVERRIDE; diff --git a/chrome/browser/ui/omnibox/omnibox_edit_model.cc b/chrome/browser/ui/omnibox/omnibox_edit_model.cc index 42f10516be..de0b3efabb 100644 --- a/chrome/browser/ui/omnibox/omnibox_edit_model.cc +++ b/chrome/browser/ui/omnibox/omnibox_edit_model.cc @@ -490,6 +490,7 @@ void OmniboxEditModel::StartAutocomplete( user_text_, cursor_position, current_url, + ClassifyPage(), prevent_inline_autocomplete || just_deleted_text_ || (has_selected_text && inline_autocomplete_text_.empty()) || (paste_state_ != NONE), @@ -550,9 +551,9 @@ void OmniboxEditModel::AcceptInput(WindowOpenDisposition disposition, const AutocompleteInput& old_input = autocomplete_controller()->input(); AutocompleteInput input( old_input.text(), old_input.cursor_position(), ASCIIToUTF16("com"), - GURL(), old_input.prevent_inline_autocomplete(), - old_input.prefer_keyword(), old_input.allow_exact_keyword_match(), - old_input.matches_requested()); + GURL(), old_input.current_page_classification(), + old_input.prevent_inline_autocomplete(), old_input.prefer_keyword(), + old_input.allow_exact_keyword_match(), old_input.matches_requested()); AutocompleteMatch url_match = HistoryURLProvider::SuggestExactInput( autocomplete_controller()->history_url_provider(), input, true); @@ -809,6 +810,7 @@ void OmniboxEditModel::OnSetFocus(bool control_down) { // the actual underlying current URL, e.g. if we're on the NTP and the // |permanent_text_| is empty. autocomplete_controller()->StartZeroSuggest(delegate_->GetURL(), + ClassifyPage(), permanent_text_); } diff --git a/chrome/browser/ui/webui/favicon_source.cc b/chrome/browser/ui/webui/favicon_source.cc index eb284e6e5b..5d6d6ffcb9 100644 --- a/chrome/browser/ui/webui/favicon_source.cc +++ b/chrome/browser/ui/webui/favicon_source.cc @@ -11,6 +11,9 @@ #include "chrome/browser/history/top_sites.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/search/instant_io_context.h" +#include "chrome/browser/sync/glue/session_model_associator.h" +#include "chrome/browser/sync/profile_sync_service.h" +#include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/common/favicon/favicon_url_parser.h" #include "chrome/common/url_constants.h" #include "grit/locale_settings.h" @@ -137,8 +140,19 @@ bool FaviconSource::ShouldServiceRequest(const net::URLRequest* request) const { } bool FaviconSource::HandleMissingResource(const IconRequest& request) { - // No additional checks to locate the favicon resource in the base - // implementation. + // If the favicon is not available, try to use the synced favicon. + ProfileSyncService* sync_service = + ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile_); + browser_sync::SessionModelAssociator* associator = sync_service ? + sync_service->GetSessionModelAssociator() : NULL; + + scoped_refptr<base::RefCountedMemory> response; + if (associator && + associator->GetSyncedFaviconForPageURL(request.request_path.spec(), + &response)) { + request.callback.Run(response.get()); + return true; + } return false; } diff --git a/chrome/browser/ui/webui/nacl_ui.cc b/chrome/browser/ui/webui/nacl_ui.cc index aaa1d6eb0f..aa48775763 100644 --- a/chrome/browser/ui/webui/nacl_ui.cc +++ b/chrome/browser/ui/webui/nacl_ui.cc @@ -127,6 +127,21 @@ class NaClDomHandler : public WebUIMessageHandler { // Factory for the creating refs in callbacks. base::WeakPtrFactory<NaClDomHandler> weak_ptr_factory_; + // Returns whether the specified plugin is enabled. + bool isPluginEnabled(size_t plugin_index); + + // Adds information regarding the operating system and chrome version to list. + void AddOperatingSystemInfo(ListValue* list); + + // Adds the list of plugins for NaCl to list. + void AddPluginList(ListValue* list); + + // Adds the information relevant to PNaCl (e.g., enablement, paths) to list. + void AddPnaclInfo(ListValue* list); + + // Adds the information relevant to NaCl to list. + void AddNaClInfo(ListValue* list); + // Whether the page has requested data. bool page_has_requested_data_; @@ -217,38 +232,20 @@ void AddLineBreak(ListValue* list) { AddPair(list, ASCIIToUTF16(""), ASCIIToUTF16("")); } -// Check whether a commandline switch is turned on or off. -void ListFlagStatus(ListValue* list, const std::string& flag_label, - const std::string& flag_name) { - if (CommandLine::ForCurrentProcess()->HasSwitch(flag_name)) - AddPair(list, ASCIIToUTF16(flag_label), ASCIIToUTF16("On")); - else - AddPair(list, ASCIIToUTF16(flag_label), ASCIIToUTF16("Off")); -} - -void NaClDomHandler::HandleRequestNaClInfo(const ListValue* args) { - page_has_requested_data_ = true; - // Force re-validation of pnacl's path in the next call to - // MaybeRespondToPage(), in case PNaCl went from not-installed - // to installed since the request. - pnacl_path_validated_ = false; - MaybeRespondToPage(); -} - -void NaClDomHandler::OnGotPlugins( - const std::vector<content::WebPluginInfo>& plugins) { - has_plugin_info_ = true; - MaybeRespondToPage(); +bool NaClDomHandler::isPluginEnabled(size_t plugin_index) { + std::vector<content::WebPluginInfo> info_array; + PluginService::GetInstance()->GetPluginInfoArray( + GURL(), "application/x-nacl", false, &info_array, NULL); + PluginPrefs* plugin_prefs = + PluginPrefs::GetForProfile(Profile::FromWebUI(web_ui())).get(); + return (!info_array.empty() && + plugin_prefs->IsPluginEnabled(info_array[plugin_index])); } -void NaClDomHandler::PopulatePageInformation(DictionaryValue* naclInfo) { - DCHECK(pnacl_path_validated_); - // Store Key-Value pairs of about-information. - scoped_ptr<ListValue> list(new ListValue()); - +void NaClDomHandler::AddOperatingSystemInfo(ListValue* list) { // Obtain the Chrome version info. chrome::VersionInfo version_info; - AddPair(list.get(), + AddPair(list, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), ASCIIToUTF16(version_info.Version() + " (" + chrome::VersionInfo::GetVersionStringModifier() + ")")); @@ -275,12 +272,13 @@ void NaClDomHandler::PopulatePageInformation(DictionaryValue* naclInfo) { if (os->architecture() == base::win::OSInfo::X64_ARCHITECTURE) os_label += " 64 bit"; #endif - AddPair(list.get(), + AddPair(list, l10n_util::GetStringUTF16(IDS_ABOUT_VERSION_OS), ASCIIToUTF16(os_label)); + AddLineBreak(list); +} - AddLineBreak(list.get()); - +void NaClDomHandler::AddPluginList(ListValue* list) { // Obtain the version of the NaCl plugin. std::vector<content::WebPluginInfo> info_array; PluginService::GetInstance()->GetPluginInfoArray( @@ -288,57 +286,104 @@ void NaClDomHandler::PopulatePageInformation(DictionaryValue* naclInfo) { string16 nacl_version; string16 nacl_key = ASCIIToUTF16("NaCl plugin"); if (info_array.empty()) { - AddPair(list.get(), nacl_key, ASCIIToUTF16("Disabled")); + AddPair(list, nacl_key, ASCIIToUTF16("Disabled")); } else { - PluginPrefs* plugin_prefs = - PluginPrefs::GetForProfile(Profile::FromWebUI(web_ui())).get(); - // Only the 0th plugin is used. nacl_version = info_array[0].version + ASCIIToUTF16(" ") + info_array[0].path.LossyDisplayName(); - if (!plugin_prefs->IsPluginEnabled(info_array[0])) { + if (!isPluginEnabled(0)) { nacl_version += ASCIIToUTF16(" (Disabled in profile prefs)"); - AddPair(list.get(), nacl_key, nacl_version); } - AddPair(list.get(), nacl_key, nacl_version); + AddPair(list, nacl_key, nacl_version); // Mark the rest as not used. for (size_t i = 1; i < info_array.size(); ++i) { nacl_version = info_array[i].version + ASCIIToUTF16(" ") + info_array[i].path.LossyDisplayName(); nacl_version += ASCIIToUTF16(" (not used)"); - if (!plugin_prefs->IsPluginEnabled(info_array[i])) + if (!isPluginEnabled(i)) { nacl_version += ASCIIToUTF16(" (Disabled in profile prefs)"); - AddPair(list.get(), nacl_key, nacl_version); + } + AddPair(list, nacl_key, nacl_version); } } + AddLineBreak(list); +} - // Check that commandline flags are enabled. - ListFlagStatus(list.get(), "Flag '--enable-nacl'", switches::kEnableNaCl); - - AddLineBreak(list.get()); +void NaClDomHandler::AddPnaclInfo(ListValue* list) { + // Display whether PNaCl is enabled. + string16 pnacl_enabled_string = ASCIIToUTF16("Enabled"); + if (!isPluginEnabled(0)) { + pnacl_enabled_string = ASCIIToUTF16("Disabled in profile prefs"); + } else if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisablePnacl)) { + pnacl_enabled_string = ASCIIToUTF16("Disabled by flag '--disable-pnacl'"); + } + AddPair(list, + ASCIIToUTF16("Portable Native Client (PNaCl)"), + pnacl_enabled_string); // Obtain the version of the PNaCl translator. base::FilePath pnacl_path; bool got_path = PathService::Get(chrome::DIR_PNACL_COMPONENT, &pnacl_path); if (!got_path || pnacl_path.empty() || !pnacl_path_exists_) { - AddPair(list.get(), + AddPair(list, ASCIIToUTF16("PNaCl translator"), ASCIIToUTF16("Not installed")); } else { - AddPair(list.get(), + AddPair(list, ASCIIToUTF16("PNaCl translator path"), pnacl_path.LossyDisplayName()); // Version string is part of the directory name: // pnacl/<version>/_platform_specific/<arch>/[files] // Keep in sync with pnacl_component_installer.cc. - AddPair(list.get(), + AddPair(list, ASCIIToUTF16("PNaCl translator version"), pnacl_path.DirName().DirName().BaseName().LossyDisplayName()); } + AddLineBreak(list); +} + +void NaClDomHandler::AddNaClInfo(ListValue* list) { + string16 nacl_enabled_string = ASCIIToUTF16("Disabled"); + if (isPluginEnabled(0) && + CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableNaCl)) { + nacl_enabled_string = ASCIIToUTF16("Enabled by flag '--enable-nacl'"); + } + AddPair(list, + ASCIIToUTF16("Native Client (non-portable, outside web store)"), + nacl_enabled_string); + AddLineBreak(list); +} + +void NaClDomHandler::HandleRequestNaClInfo(const ListValue* args) { + page_has_requested_data_ = true; + // Force re-validation of pnacl's path in the next call to + // MaybeRespondToPage(), in case PNaCl went from not-installed + // to installed since the request. + pnacl_path_validated_ = false; + MaybeRespondToPage(); +} + +void NaClDomHandler::OnGotPlugins( + const std::vector<content::WebPluginInfo>& plugins) { + has_plugin_info_ = true; + MaybeRespondToPage(); +} - ListFlagStatus(list.get(), "Flag '--disable-pnacl'", switches::kDisablePnacl); +void NaClDomHandler::PopulatePageInformation(DictionaryValue* naclInfo) { + DCHECK(pnacl_path_validated_); + // Store Key-Value pairs of about-information. + scoped_ptr<ListValue> list(new ListValue()); + // Display the operating system and chrome version information. + AddOperatingSystemInfo(list.get()); + // Display the list of plugins serving NaCl. + AddPluginList(list.get()); + // Display information relevant to PNaCl. + AddPnaclInfo(list.get()); + // Display information relevant to NaCl (non-portable. + AddNaClInfo(list.get()); // naclInfo will take ownership of list, and clean it up on destruction. naclInfo->Set("naclInfo", list.release()); } diff --git a/chrome/browser/ui/webui/ntp/android/bookmarks_handler.cc b/chrome/browser/ui/webui/ntp/android/bookmarks_handler.cc index 3981a7c474..a6a96839b4 100644 --- a/chrome/browser/ui/webui/ntp/android/bookmarks_handler.cc +++ b/chrome/browser/ui/webui/ntp/android/bookmarks_handler.cc @@ -33,31 +33,6 @@ namespace { static const char* kParentIdParam = "parent_id"; static const char* kNodeIdParam = "node_id"; -// Parses a bookmark ID passed back from the NTP. The IDs differ from the -// normal int64 bookmark ID because we prepend a "p" if the ID represents a -// partner bookmark. -bool ParseNtpBookmarkId(const ListValue* args, - int64* out_id, - bool* out_is_partner) { - if (!args || args->empty()) - return false; - - std::string string_id; - if (!args->GetString(0, &string_id)) - return false; - - if (string_id.empty()) - return false; - - if (StartsWithASCII(string_id, "p", true)) { - *out_is_partner = true; - return base::StringToInt64(string_id.substr(1), out_id); - } - - *out_is_partner = false; - return base::StringToInt64(string_id, out_id); -} - std::string BookmarkTypeAsString(BookmarkNode::Type type) { switch (type) { case BookmarkNode::URL: @@ -99,6 +74,9 @@ BookmarksHandler::~BookmarksHandler() { if (partner_bookmarks_shim_) partner_bookmarks_shim_->RemoveObserver(this); + + if (managed_bookmarks_shim_) + managed_bookmarks_shim_->RemoveObserver(this); } void BookmarksHandler::RegisterMessages() { @@ -125,6 +103,9 @@ void BookmarksHandler::RegisterMessages() { partner_bookmarks_shim_->AddObserver(this); } + managed_bookmarks_shim_.reset(new ManagedBookmarksShim(profile->GetPrefs())); + managed_bookmarks_shim_->AddObserver(this); + // Register ourselves as the handler for the bookmark javascript callbacks. web_ui()->RegisterMessageCallback("getBookmarks", base::Bind(&BookmarksHandler::HandleGetBookmarks, @@ -159,24 +140,20 @@ void BookmarksHandler::HandleGetBookmarks(const ListValue* args) { if (!partner_bookmarks_shim_->IsLoaded()) return; // is handled with a PartnerShimLoaded() callback - int64 id; - bool is_partner; - if (ParseNtpBookmarkId(args, &id, &is_partner)) - QueryBookmarkFolder(id, is_partner); + const BookmarkNode* node = GetNodeByID(args); + if (node) + QueryBookmarkFolder(node); else QueryInitialBookmarks(); } void BookmarksHandler::HandleDeleteBookmark(const ListValue* args) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - int64 id; - bool is_partner; - if (!ParseNtpBookmarkId(args, &id, &is_partner)) + const BookmarkNode* node = GetNodeByID(args); + if (!node) return; - const BookmarkNode* node = - partner_bookmarks_shim_->GetNodeByID(id, is_partner); - if (!partner_bookmarks_shim_->IsBookmarkEditable(node)) { + if (!IsEditable(node)) { NOTREACHED(); return; } @@ -187,14 +164,11 @@ void BookmarksHandler::HandleDeleteBookmark(const ListValue* args) { void BookmarksHandler::HandleEditBookmark(const ListValue* args) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - int64 id; - bool is_partner; - if (!ParseNtpBookmarkId(args, &id, &is_partner)) + const BookmarkNode* node = GetNodeByID(args); + if (!node) return; - const BookmarkNode* node = - partner_bookmarks_shim_->GetNodeByID(id, is_partner); - if (!partner_bookmarks_shim_->IsBookmarkEditable(node)) { + if (!IsEditable(node)) { NOTREACHED(); return; } @@ -205,8 +179,12 @@ void BookmarksHandler::HandleEditBookmark(const ListValue* args) { } std::string BookmarksHandler::GetBookmarkIdForNtp(const BookmarkNode* node) { - return (partner_bookmarks_shim_->IsPartnerBookmark(node) ? "p" : "") + - Int64ToString(node->id()); + std::string prefix; + if (partner_bookmarks_shim_->IsPartnerBookmark(node)) + prefix = "p"; + else if (managed_bookmarks_shim_->IsManagedBookmark(node)) + prefix = "m"; + return prefix + Int64ToString(node->id()); } void BookmarksHandler::SetParentInBookmarksResult(const BookmarkNode* parent, @@ -221,17 +199,7 @@ void BookmarksHandler::PopulateBookmark(const BookmarkNode* node, DictionaryValue* filler_value = new DictionaryValue(); filler_value->SetString("title", node->GetTitle()); - - // Mark reserved system nodes and partner bookmarks as uneditable. - // Also mark them uneditable when it is disabled by a preference - // (which can be forced by a policy). - // (i.e. the bookmark bar along with the "Other Bookmarks" folder). - const PrefService* pref = Profile::FromBrowserContext( - web_ui()->GetWebContents()->GetBrowserContext())->GetPrefs(); - bool editable = partner_bookmarks_shim_->IsBookmarkEditable(node) && - pref->GetBoolean(prefs::kEditBookmarksEnabled); - filler_value->SetBoolean("editable", editable); - + filler_value->SetBoolean("editable", IsEditable(node)); if (node->is_url()) { filler_value->SetBoolean("folder", false); filler_value->SetString("url", node->url().spec()); @@ -248,6 +216,14 @@ void BookmarksHandler::PopulateBookmarksInFolder( DictionaryValue* result) { ListValue* bookmarks = new ListValue(); + // If this is the Mobile bookmarks folder then add the "Managed bookmarks" + // folder first, so that it's the first entry. + if (bookmark_model_ && folder == bookmark_model_->mobile_node() && + managed_bookmarks_shim_->HasManagedBookmarks()) { + PopulateBookmark(managed_bookmarks_shim_->GetManagedBookmarksRoot(), + bookmarks); + } + for (int i = 0; i < folder->child_count(); i++) { const BookmarkNode* bookmark= folder->GetChild(i); PopulateBookmark(bookmark, bookmarks); @@ -262,34 +238,30 @@ void BookmarksHandler::PopulateBookmarksInFolder( } ListValue* folder_hierarchy = new ListValue(); - const BookmarkNode* parent = partner_bookmarks_shim_->GetParentOf(folder); + const BookmarkNode* parent = GetParentOf(folder); while (parent != NULL) { DictionaryValue* hierarchy_entry = new DictionaryValue(); - if (partner_bookmarks_shim_->IsRootNode(parent)) + if (IsRoot(parent)) hierarchy_entry->SetBoolean("root", true); hierarchy_entry->SetString("title", parent->GetTitle()); hierarchy_entry->SetString("id", GetBookmarkIdForNtp(parent)); folder_hierarchy->Append(hierarchy_entry); - parent = partner_bookmarks_shim_->GetParentOf(parent); + parent = GetParentOf(parent); } result->SetString("title", folder->GetTitle()); result->SetString("id", GetBookmarkIdForNtp(folder)); - result->SetBoolean("root", partner_bookmarks_shim_->IsRootNode(folder)); + result->SetBoolean("root", IsRoot(folder)); result->Set("bookmarks", bookmarks); result->Set("hierarchy", folder_hierarchy); } -void BookmarksHandler::QueryBookmarkFolder(const int64& folder_id, - bool is_partner_bookmark) { - DCHECK(partner_bookmarks_shim_ != NULL); - const BookmarkNode* bookmarks = - partner_bookmarks_shim_->GetNodeByID(folder_id, is_partner_bookmark); - if (bookmarks) { +void BookmarksHandler::QueryBookmarkFolder(const BookmarkNode* node) { + if (node->is_folder()) { DictionaryValue result; - PopulateBookmarksInFolder(bookmarks, &result); + PopulateBookmarksInFolder(node, &result); SendResult(result); } else { // If we receive an ID that no longer maps to a bookmark folder, just @@ -301,12 +273,17 @@ void BookmarksHandler::QueryBookmarkFolder(const int64& folder_id, void BookmarksHandler::QueryInitialBookmarks() { DictionaryValue result; DCHECK(partner_bookmarks_shim_ != NULL); - PopulateBookmarksInFolder( - // We have to go to the partner Root if it exists - partner_bookmarks_shim_->HasPartnerBookmarks() ? - partner_bookmarks_shim_->GetPartnerBookmarksRoot() : - bookmark_model_->mobile_node(), - &result); + + if (managed_bookmarks_shim_->HasManagedBookmarks()) { + PopulateBookmarksInFolder( + managed_bookmarks_shim_->GetManagedBookmarksRoot(), &result); + } else if (partner_bookmarks_shim_->HasPartnerBookmarks()) { + PopulateBookmarksInFolder( + partner_bookmarks_shim_->GetPartnerBookmarksRoot(), &result); + } else { + PopulateBookmarksInFolder(bookmark_model_->mobile_node(), &result); + } + SendResult(result); } @@ -326,6 +303,10 @@ void BookmarksHandler::ShimBeingDeleted(PartnerBookmarksShim* shim) { partner_bookmarks_shim_ = NULL; } +void BookmarksHandler::OnManagedBookmarksChanged() { + BookmarkModelChanged(); +} + void BookmarksHandler::ExtensiveBookmarkChangesBeginning(BookmarkModel* model) { extensive_changes_ = true; } @@ -385,14 +366,8 @@ void BookmarksHandler::HandleCreateHomeScreenBookmarkShortcut( if (!profile) return; - int64 id; - bool is_partner; - if (!ParseNtpBookmarkId(args, &id, &is_partner)) - return; - DCHECK(partner_bookmarks_shim_ != NULL); - const BookmarkNode* node = - partner_bookmarks_shim_->GetNodeByID(id, is_partner); + const BookmarkNode* node = GetNodeByID(args); if (!node) return; @@ -430,3 +405,59 @@ void BookmarksHandler::OnShortcutFaviconDataAvailable( SkColorGetG(color), SkColorGetB(color)); } } + +const BookmarkNode* BookmarksHandler::GetNodeByID( + const base::ListValue* args) const { + // Parses a bookmark ID passed back from the NTP. The IDs differ from the + // normal int64 bookmark ID because we prepend a "p" if the ID represents a + // partner bookmark, and an "m" if the ID represents a managed bookmark. + + if (!args || args->empty()) + return NULL; + + std::string string_id; + if (!args->GetString(0, &string_id) || string_id.empty()) { + NOTREACHED(); + return NULL; + } + + bool is_partner = string_id[0] == 'p'; + bool is_managed = string_id[0] == 'm'; + + if (is_partner || is_managed) + string_id = string_id.substr(1); + + int64 id = 0; + if (!base::StringToInt64(string_id, &id)) { + NOTREACHED(); + return NULL; + } + + if (is_managed) + return managed_bookmarks_shim_->GetNodeByID(id); + else + return partner_bookmarks_shim_->GetNodeByID(id, is_partner); +} + +const BookmarkNode* BookmarksHandler::GetParentOf( + const BookmarkNode* node) const { + if (node == managed_bookmarks_shim_->GetManagedBookmarksRoot()) + return bookmark_model_->mobile_node(); + return partner_bookmarks_shim_->GetParentOf(node); +} + +bool BookmarksHandler::IsEditable(const BookmarkNode* node) const { + // Reserved system nodes, partner bookmarks and managed bookmarks are not + // editable. Additionally, bookmark editing may be completely disabled via + // a managed preference. + const PrefService* pref = Profile::FromBrowserContext( + web_ui()->GetWebContents()->GetBrowserContext())->GetPrefs(); + return partner_bookmarks_shim_->IsBookmarkEditable(node) && + !managed_bookmarks_shim_->IsManagedBookmark(node) && + pref->GetBoolean(prefs::kEditBookmarksEnabled); +} + +bool BookmarksHandler::IsRoot(const BookmarkNode* node) const { + return partner_bookmarks_shim_->IsRootNode(node) && + node != managed_bookmarks_shim_->GetManagedBookmarksRoot(); +} diff --git a/chrome/browser/ui/webui/ntp/android/bookmarks_handler.h b/chrome/browser/ui/webui/ntp/android/bookmarks_handler.h index d834a15683..9c914172b5 100644 --- a/chrome/browser/ui/webui/ntp/android/bookmarks_handler.h +++ b/chrome/browser/ui/webui/ntp/android/bookmarks_handler.h @@ -5,9 +5,11 @@ #ifndef CHROME_BROWSER_UI_WEBUI_NTP_ANDROID_BOOKMARKS_HANDLER_H_ #define CHROME_BROWSER_UI_WEBUI_NTP_ANDROID_BOOKMARKS_HANDLER_H_ +#include "base/memory/scoped_ptr.h" #include "base/values.h" #include "chrome/browser/bookmarks/base_bookmark_model_observer.h" #include "chrome/browser/favicon/favicon_service.h" +#include "chrome/browser/ui/webui/ntp/android/managed_bookmarks_shim.h" #include "chrome/browser/ui/webui/ntp/android/partner_bookmarks_shim.h" #include "chrome/common/cancelable_task_tracker.h" #include "content/public/browser/web_ui_message_handler.h" @@ -17,7 +19,7 @@ // In Javascript if getBookmarks() is called without any parameter, the 'Other // Bookmark' folder and bookmark bar's bookmarks and folders are returned. // If getBookmarks() is called with a valid bookmark folder id, the given -// folder's bookmarks and sub folders of are returned. +// folder's bookmarks and sub folders of it are returned. // // All bookmarks and subfolder is returned by bookmarks() javascript callback // function. @@ -46,7 +48,8 @@ // } class BookmarksHandler : public content::WebUIMessageHandler, public BaseBookmarkModelObserver, - public PartnerBookmarksShim::Observer { + public PartnerBookmarksShim::Observer, + public ManagedBookmarksShim::Observer { public: BookmarksHandler(); virtual ~BookmarksHandler(); @@ -87,6 +90,9 @@ class BookmarksHandler : public content::WebUIMessageHandler, virtual void PartnerShimLoaded(PartnerBookmarksShim* shim) OVERRIDE; virtual void ShimBeingDeleted(PartnerBookmarksShim* shim) OVERRIDE; + // Override the methods of ManagedBookmarksShim::Observer + virtual void OnManagedBookmarksChanged() OVERRIDE; + private: // The bookmark model being observed (if it has been attached). BookmarkModel* bookmark_model_; @@ -94,6 +100,9 @@ class BookmarksHandler : public content::WebUIMessageHandler, // Information about the Partner bookmarks (must check for IsLoaded()) PartnerBookmarksShim* partner_bookmarks_shim_; + // Contains the bookmarks managed via enterprise policy. + scoped_ptr<ManagedBookmarksShim> managed_bookmarks_shim_; + // Whether the bookmark data has been requested by the UI yet. bool bookmark_data_requested_; @@ -121,7 +130,7 @@ class BookmarksHandler : public content::WebUIMessageHandler, DictionaryValue* result); // Sends all bookmarks and sub folders in the given folder back to the NTP. - void QueryBookmarkFolder(const int64& id, bool is_partner_bookmark); + void QueryBookmarkFolder(const BookmarkNode* node); // Sends bookmark bar's bookmarks and sub folders and other folders back to // NTP. @@ -136,6 +145,20 @@ class BookmarksHandler : public content::WebUIMessageHandler, const BookmarkNode* node, const chrome::FaviconBitmapResult& bitmap_result); + // Looks at an optional bookmark ID in |args| and returns the corresponding + // node if found, otherwise returns NULL. + const BookmarkNode* GetNodeByID(const base::ListValue* args) const; + + // Returns the parent of |node|, or NULL if it's the root node. + const BookmarkNode* GetParentOf(const BookmarkNode* node) const; + + // Returns true if |node| can be modified by the user. + bool IsEditable(const BookmarkNode* node) const; + + // Returns true if |node| is the real root node (not the root node of the + // partner bookmarks shim nor the managed bookmark shim root). + bool IsRoot(const BookmarkNode* node) const; + DISALLOW_COPY_AND_ASSIGN(BookmarksHandler); }; diff --git a/chrome/browser/ui/webui/ntp/android/managed_bookmarks_shim.cc b/chrome/browser/ui/webui/ntp/android/managed_bookmarks_shim.cc new file mode 100644 index 0000000000..c1f8f277b0 --- /dev/null +++ b/chrome/browser/ui/webui/ntp/android/managed_bookmarks_shim.cc @@ -0,0 +1,96 @@ +// Copyright (c) 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/webui/ntp/android/managed_bookmarks_shim.h" + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/prefs/pref_service.h" +#include "chrome/browser/bookmarks/bookmark_model.h" +#include "chrome/browser/policy/configuration_policy_handler_android.h" +#include "chrome/common/pref_names.h" +#include "grit/generated_resources.h" +#include "ui/base/l10n/l10n_util.h" + +using policy::ManagedBookmarksPolicyHandler; + +ManagedBookmarksShim::ManagedBookmarksShim(PrefService* prefs) + : prefs_(prefs) { + registrar_.Init(prefs_); + registrar_.Add( + prefs::kManagedBookmarks, + base::Bind(&ManagedBookmarksShim::Reload, base::Unretained(this))); + Reload(); +} + +ManagedBookmarksShim::~ManagedBookmarksShim() {} + +void ManagedBookmarksShim::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void ManagedBookmarksShim::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +bool ManagedBookmarksShim::HasManagedBookmarks() const { + return !root_->empty(); +} + +bool ManagedBookmarksShim::IsManagedBookmark(const BookmarkNode* node) const { + while (node != NULL) { + if (node == root_.get()) + return true; + node = node->parent(); + } + return false; +} + +const BookmarkNode* ManagedBookmarksShim::GetManagedBookmarksRoot() const { + return root_.get(); +} + +const BookmarkNode* ManagedBookmarksShim::GetNodeByID(int64 id) const { + if (root_->id() == id) + return root_.get(); + for (int i = 0; i < root_->child_count(); ++i) { + const BookmarkNode* child = root_->GetChild(i); + if (child->id() == id) + return child; + } + return NULL; +} + +void ManagedBookmarksShim::Reload() { + root_.reset(new BookmarkPermanentNode(0)); + root_->SetTitle(l10n_util::GetStringUTF16(IDS_POLICY_MANAGED_BOOKMARKS)); + + const base::ListValue* list = prefs_->GetList(prefs::kManagedBookmarks); + int64 id = 1; + if (list) { + for (base::ListValue::const_iterator it = list->begin(); + it != list->end(); ++it) { + const base::DictionaryValue* dict = NULL; + if (!*it || !(*it)->GetAsDictionary(&dict)) { + NOTREACHED(); + continue; + } + + string16 name; + std::string url; + if (!dict->GetString(ManagedBookmarksPolicyHandler::kName, &name) || + !dict->GetString(ManagedBookmarksPolicyHandler::kUrl, &url)) { + NOTREACHED(); + continue; + } + + BookmarkNode* node = new BookmarkNode(id++, GURL(url)); + node->set_type(BookmarkNode::URL); + node->SetTitle(name); + root_->Add(node, root_->child_count()); + } + } + + FOR_EACH_OBSERVER(Observer, observers_, OnManagedBookmarksChanged()); +} diff --git a/chrome/browser/ui/webui/ntp/android/managed_bookmarks_shim.h b/chrome/browser/ui/webui/ntp/android/managed_bookmarks_shim.h new file mode 100644 index 0000000000..affb1ce5ad --- /dev/null +++ b/chrome/browser/ui/webui/ntp/android/managed_bookmarks_shim.h @@ -0,0 +1,56 @@ +// Copyright (c) 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_WEBUI_NTP_ANDROID_MANAGED_BOOKMARKS_SHIM_H_ +#define CHROME_BROWSER_UI_WEBUI_NTP_ANDROID_MANAGED_BOOKMARKS_SHIM_H_ + +#include "base/basictypes.h" +#include "base/memory/scoped_ptr.h" +#include "base/observer_list.h" +#include "base/prefs/pref_change_registrar.h" + +class BookmarkNode; +class PrefService; + +// A shim that lives on top of a BookmarkModel that allows the injection of +// policy managed bookmarks without submitting changes to the user configured +// bookmark model. +// Policy managed bookmarks live on a subfolder of the Mobile bookmarks called +// "Managed bookmarks" that isn't editable by the user. +class ManagedBookmarksShim { + public: + class Observer { + public: + virtual ~Observer() {} + virtual void OnManagedBookmarksChanged() = 0; + }; + + // Will read managed bookmarks from the given PrefService. The preference + // that contains the bookmarks is managed by policy, and is updated when the + // policy changes. + explicit ManagedBookmarksShim(PrefService* prefs); + ~ManagedBookmarksShim(); + + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + + // Returns true if there exists at least one managed bookmark. + bool HasManagedBookmarks() const; + bool IsManagedBookmark(const BookmarkNode* node) const; + const BookmarkNode* GetManagedBookmarksRoot() const; + const BookmarkNode* GetNodeByID(int64 id) const; + const BookmarkNode* GetParentOf(const BookmarkNode* node) const; + + private: + void Reload(); + + PrefService* prefs_; + PrefChangeRegistrar registrar_; + scoped_ptr<BookmarkNode> root_; + ObserverList<Observer> observers_; + + DISALLOW_COPY_AND_ASSIGN(ManagedBookmarksShim); +}; + +#endif // CHROME_BROWSER_UI_WEBUI_NTP_ANDROID_MANAGED_BOOKMARKS_SHIM_H_ diff --git a/chrome/browser/ui/webui/ntp/foreign_session_handler.cc b/chrome/browser/ui/webui/ntp/foreign_session_handler.cc index ab58537998..7c42a9b337 100644 --- a/chrome/browser/ui/webui/ntp/foreign_session_handler.cc +++ b/chrome/browser/ui/webui/ntp/foreign_session_handler.cc @@ -24,7 +24,6 @@ #include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/browser/ui/host_desktop.h" #include "chrome/browser/ui/webui/ntp/new_tab_ui.h" -#include "chrome/browser/ui/webui/session_favicon_source.h" #include "chrome/common/pref_names.h" #include "chrome/common/time_format.h" #include "chrome/common/url_constants.h" @@ -187,9 +186,6 @@ void ForeignSessionHandler::Init() { content::Source<Profile>(profile)); registrar_.Add(this, chrome::NOTIFICATION_FOREIGN_SESSION_DISABLED, content::Source<Profile>(profile)); - - // Add the data source for synced favicons. - content::URLDataSource::Add(profile, new SessionFaviconSource(profile)); } void ForeignSessionHandler::Observe( diff --git a/chrome/browser/ui/webui/omnibox/omnibox_ui_handler.cc b/chrome/browser/ui/webui/omnibox/omnibox_ui_handler.cc index c436f9dd10..a78f7352f3 100644 --- a/chrome/browser/ui/webui/omnibox/omnibox_ui_handler.cc +++ b/chrome/browser/ui/webui/omnibox/omnibox_ui_handler.cc @@ -196,6 +196,7 @@ void OmniboxUIHandler::StartOmniboxQuery(const base::ListValue* input) { cursor_position, string16(), // user's desired tld (top-level domain) GURL(), + AutocompleteInput::INVALID_SPEC, prevent_inline_autocomplete, prefer_keyword, true, // allow exact keyword matches diff --git a/chrome/browser/ui/webui/options/browser_options_handler.cc b/chrome/browser/ui/webui/options/browser_options_handler.cc index 94deb7ce47..da78bb005d 100644 --- a/chrome/browser/ui/webui/options/browser_options_handler.cc +++ b/chrome/browser/ui/webui/options/browser_options_handler.cc @@ -12,6 +12,7 @@ #include "base/bind_helpers.h" #include "base/command_line.h" #include "base/memory/singleton.h" +#include "base/metrics/field_trial.h" #include "base/metrics/histogram.h" #include "base/path_service.h" #include "base/prefs/pref_service.h" @@ -125,6 +126,10 @@ namespace options { namespace { +// Constants for the new tab button field trial. + const char kProfileResetTrialName[] = "ManualResetProfile"; + const char kProfileResetTrialEnableGroupName[] = "Enable"; + bool ShouldShowMultiProfilesUserList(chrome::HostDesktopType desktop_type) { #if defined(OS_CHROMEOS) // On Chrome OS we use different UI for multi-profiles. @@ -528,7 +533,11 @@ void BrowserOptionsHandler::GetLocalizedValues(DictionaryValue* values) { g_browser_process->gpu_mode_manager()->initial_gpu_mode_pref()); #endif + bool finch_allows_button = + base::FieldTrialList::FindFullName(kProfileResetTrialName) == + kProfileResetTrialEnableGroupName; values->SetBoolean("enableResetProfileSettingsSection", + finch_allows_button || CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableResetProfileSettings)); } diff --git a/chrome/browser/ui/webui/options/home_page_overlay_handler.cc b/chrome/browser/ui/webui/options/home_page_overlay_handler.cc index f24ad7c1a0..29125dc71f 100644 --- a/chrome/browser/ui/webui/options/home_page_overlay_handler.cc +++ b/chrome/browser/ui/webui/options/home_page_overlay_handler.cc @@ -50,7 +50,8 @@ void HomePageOverlayHandler::RequestAutocompleteSuggestions( CHECK(args->GetString(0, &input)); autocomplete_controller_->Start(AutocompleteInput( - input, string16::npos, string16(), GURL(), true, + input, string16::npos, string16(), GURL(), + AutocompleteInput::INVALID_SPEC, true, false, false, AutocompleteInput::ALL_MATCHES)); } diff --git a/chrome/browser/ui/webui/options/reset_profile_settings_handler.cc b/chrome/browser/ui/webui/options/reset_profile_settings_handler.cc index 68ee2bb35c..6222f9188d 100644 --- a/chrome/browser/ui/webui/options/reset_profile_settings_handler.cc +++ b/chrome/browser/ui/webui/options/reset_profile_settings_handler.cc @@ -13,6 +13,7 @@ #include "chrome/browser/profile_resetter/brandcode_config_fetcher.h" #include "chrome/browser/profile_resetter/brandcoded_default_settings.h" #include "chrome/browser/profile_resetter/profile_resetter.h" +#include "chrome/browser/profile_resetter/resettable_settings_snapshot.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/pref_names.h" #include "content/public/browser/user_metrics.h" @@ -45,7 +46,9 @@ void ResetProfileSettingsHandler::GetLocalizedValues( static OptionsStringResource resources[] = { { "resetProfileSettingsCommit", IDS_RESET_PROFILE_SETTINGS_COMMIT_BUTTON }, - { "resetProfileSettingsExplanation", IDS_RESET_PROFILE_SETTINGS_EXPLANATION} + { "resetProfileSettingsExplanation", + IDS_RESET_PROFILE_SETTINGS_EXPLANATION}, + { "resetProfileSettingsFeedback", IDS_RESET_PROFILE_SETTINGS_FEEDBACK } }; RegisterStrings(localized_strings, resources, arraysize(resources)); @@ -68,20 +71,37 @@ void ResetProfileSettingsHandler::RegisterMessages() { } void ResetProfileSettingsHandler::HandleResetProfileSettings( - const ListValue* /*value*/) { + const ListValue* value) { + bool send_settings = false; + if (!value->GetBoolean(0, &send_settings)) + NOTREACHED(); + DCHECK(brandcode_.empty() || config_fetcher_); if (config_fetcher_ && config_fetcher_->IsActive()) { // Reset once the prefs are fetched. config_fetcher_->SetCallback( base::Bind(&ResetProfileSettingsHandler::ResetProfile, - Unretained(this))); + Unretained(this), + send_settings)); } else { - ResetProfile(); + ResetProfile(send_settings); } } void ResetProfileSettingsHandler::OnResetProfileSettingsDone() { web_ui()->CallJavascriptFunction("ResetProfileSettingsOverlay.doneResetting"); + if (setting_snapshot_) { + Profile* profile = Profile::FromWebUI(web_ui()); + ResettableSettingsSnapshot current_snapshot(profile); + int difference = setting_snapshot_->FindDifferentFields(current_snapshot); + if (difference) { + setting_snapshot_->SubtractStartupURLs(current_snapshot); + std::string report = SerializeSettingsReport(*setting_snapshot_, + difference); + SendSettingsFeedback(report, profile); + } + setting_snapshot_.reset(); + } } void ResetProfileSettingsHandler::OnShowResetProfileDialog(const ListValue*) { @@ -100,7 +120,7 @@ void ResetProfileSettingsHandler::OnSettingsFetched() { // The master prefs is fetched. We are waiting for user pressing 'Reset'. } -void ResetProfileSettingsHandler::ResetProfile() { +void ResetProfileSettingsHandler::ResetProfile(bool send_settings) { DCHECK(resetter_); DCHECK(!resetter_->IsActive()); @@ -117,6 +137,9 @@ void ResetProfileSettingsHandler::ResetProfile() { // installation, use default settings. if (!default_settings) default_settings.reset(new BrandcodedDefaultSettings); + // Save current settings if required. + setting_snapshot_.reset(send_settings ? + new ResettableSettingsSnapshot(Profile::FromWebUI(web_ui())) : NULL); resetter_->Reset( ProfileResetter::ALL, default_settings.Pass(), diff --git a/chrome/browser/ui/webui/options/reset_profile_settings_handler.h b/chrome/browser/ui/webui/options/reset_profile_settings_handler.h index 943159017c..586a773a2b 100644 --- a/chrome/browser/ui/webui/options/reset_profile_settings_handler.h +++ b/chrome/browser/ui/webui/options/reset_profile_settings_handler.h @@ -16,6 +16,7 @@ class ListValue; class BrandcodeConfigFetcher; class ProfileResetter; +class ResettableSettingsSnapshot; namespace options { @@ -48,12 +49,17 @@ class ResetProfileSettingsHandler // Called when BrandcodeConfigFetcher completed fetching settings. void OnSettingsFetched(); - void ResetProfile(); + // Resets profile settings to default values. |send_settings| is true if user + // gave his consent to upload broken settings to Google for analysis. + void ResetProfile(bool send_settings); scoped_ptr<ProfileResetter> resetter_; scoped_ptr<BrandcodeConfigFetcher> config_fetcher_; + // Snapshot of settings before profile was reseted. + scoped_ptr<ResettableSettingsSnapshot> setting_snapshot_; + // Contains Chrome brand code; empty for organic Chrome. std::string brandcode_; diff --git a/chrome/browser/ui/webui/options/startup_pages_handler.cc b/chrome/browser/ui/webui/options/startup_pages_handler.cc index 8c22b5075d..f58b6bc5c5 100644 --- a/chrome/browser/ui/webui/options/startup_pages_handler.cc +++ b/chrome/browser/ui/webui/options/startup_pages_handler.cc @@ -225,7 +225,8 @@ void StartupPagesHandler::RequestAutocompleteSuggestions( CHECK(args->GetString(0, &input)); autocomplete_controller_->Start(AutocompleteInput( - input, string16::npos, string16(), GURL(), true, + input, string16::npos, string16(), GURL(), + AutocompleteInput::INVALID_SPEC, true, false, false, AutocompleteInput::ALL_MATCHES)); } diff --git a/chrome/browser/ui/webui/session_favicon_source.cc b/chrome/browser/ui/webui/session_favicon_source.cc deleted file mode 100644 index 6aacaa6859..0000000000 --- a/chrome/browser/ui/webui/session_favicon_source.cc +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2012 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/webui/session_favicon_source.h" - -#include "chrome/browser/sync/glue/session_model_associator.h" -#include "chrome/browser/sync/profile_sync_service_factory.h" -#include "chrome/browser/sync/profile_sync_service.h" -#include "chrome/common/url_constants.h" - -using browser_sync::SessionModelAssociator; - -SessionFaviconSource::SessionFaviconSource(Profile* profile) - : FaviconSource(profile, FaviconSource::FAVICON) { -} - -SessionFaviconSource::~SessionFaviconSource() { -} - -std::string SessionFaviconSource::GetSource() const { - return chrome::kChromeUISessionFaviconHost; -} - -std::string SessionFaviconSource::GetMimeType(const std::string&) const { - return "image/png"; -} - -bool SessionFaviconSource::ShouldReplaceExistingSource() const { - // Leave the existing DataSource in place, otherwise we'll drop any pending - // requests on the floor. - return false; -} - -bool SessionFaviconSource::AllowCaching() const { - // Prevent responses from being cached, otherwise session favicons won't - // update in a timely manner. - return false; -} - -bool SessionFaviconSource::HandleMissingResource(const IconRequest& request) { - ProfileSyncService* sync_service = - ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile_); - SessionModelAssociator* associator = sync_service ? - sync_service->GetSessionModelAssociator() : NULL; - - scoped_refptr<base::RefCountedMemory> response; - if (associator && - associator->GetSyncedFaviconForPageURL(request.request_path.spec(), - &response)) { - request.callback.Run(response.get()); - return true; - } - return false; -} diff --git a/chrome/browser/ui/webui/session_favicon_source.h b/chrome/browser/ui/webui/session_favicon_source.h deleted file mode 100644 index 5402c1c561..0000000000 --- a/chrome/browser/ui/webui/session_favicon_source.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2012 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_WEBUI_SESSION_FAVICON_SOURCE_H_ -#define CHROME_BROWSER_UI_WEBUI_SESSION_FAVICON_SOURCE_H_ - -#include "chrome/browser/ui/webui/favicon_source.h" - -class Profile; - -namespace browser_sync { -class SessionModelAssociator; -} - -// Provides a way to fetch a favicon for a synced tab via a network request. -class SessionFaviconSource : public FaviconSource { - public: - explicit SessionFaviconSource(Profile* profile); - - // FaviconSource implementation. - virtual std::string GetSource() const OVERRIDE; - virtual std::string GetMimeType(const std::string&) const OVERRIDE; - virtual bool ShouldReplaceExistingSource() const OVERRIDE; - virtual bool AllowCaching() const OVERRIDE; - - protected: - virtual ~SessionFaviconSource(); - virtual bool HandleMissingResource(const IconRequest& request) OVERRIDE; -}; - -#endif // CHROME_BROWSER_UI_WEBUI_SESSION_FAVICON_SOURCE_H_ |