diff --git a/DEPS b/DEPS index c08024e..0ba78fe 100644 --- a/DEPS +++ b/DEPS
@@ -40,7 +40,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '5ce33efa7c91a638c0dc94f539c9597a954fd529', + 'skia_revision': '55b72530fedeb58154635531751a8730982fbf2a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other.
diff --git a/chrome/VERSION b/chrome/VERSION index 8129c6cd..dcb0532a 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=58 MINOR=0 -BUILD=2997 +BUILD=2998 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrDaydreamApiImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrDaydreamApiImpl.java index 2dcd451..74fa03e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrDaydreamApiImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrDaydreamApiImpl.java
@@ -76,6 +76,9 @@ DaydreamApi daydreamApi = DaydreamApi.create(mActivity); if (daydreamApi == null) return false; StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); + // If this is the first time any app reads the daydream config file, daydream may create its + // config directory... crbug.com/686104 + StrictMode.allowThreadDiskWrites(); int type = GvrApi.ViewerType.CARDBOARD; try { type = daydreamApi.getCurrentViewerType();
diff --git a/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc b/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc index bf15ceb6..1cea9df 100644 --- a/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc +++ b/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc
@@ -45,7 +45,7 @@ // external protocol handler because we don't want pages to open them, but // users still can. const ExternalProtocolHandler::BlockState block_state = - ExternalProtocolHandler::GetBlockState(scheme); + ExternalProtocolHandler::GetBlockState(scheme, profile_); switch (block_state) { case ExternalProtocolHandler::DONT_BLOCK: return metrics::OmniboxInputType::URL;
diff --git a/chrome/browser/chrome_site_per_process_browsertest.cc b/chrome/browser/chrome_site_per_process_browsertest.cc index 74de684..8e161e6 100644 --- a/chrome/browser/chrome_site_per_process_browsertest.cc +++ b/chrome/browser/chrome_site_per_process_browsertest.cc
@@ -391,8 +391,8 @@ protocol); } - ExternalProtocolHandler::BlockState GetBlockState( - const std::string& scheme) override { + ExternalProtocolHandler::BlockState GetBlockState(const std::string& scheme, + Profile* profile) override { return ExternalProtocolHandler::DONT_BLOCK; }
diff --git a/chrome/browser/external_protocol/external_protocol_handler.cc b/chrome/browser/external_protocol/external_protocol_handler.cc index d629ddd..96206ed 100644 --- a/chrome/browser/external_protocol/external_protocol_handler.cc +++ b/chrome/browser/external_protocol/external_protocol_handler.cc
@@ -52,11 +52,12 @@ ExternalProtocolHandler::BlockState GetBlockStateWithDelegate( const std::string& scheme, - ExternalProtocolHandler::Delegate* delegate) { + ExternalProtocolHandler::Delegate* delegate, + Profile* profile) { if (!delegate) - return ExternalProtocolHandler::GetBlockState(scheme); + return ExternalProtocolHandler::GetBlockState(scheme, profile); - return delegate->GetBlockState(scheme); + return delegate->GetBlockState(scheme, profile); } void RunExternalProtocolDialogWithDelegate( @@ -135,7 +136,8 @@ // static ExternalProtocolHandler::BlockState ExternalProtocolHandler::GetBlockState( - const std::string& scheme) { + const std::string& scheme, + Profile* profile) { // If we are being carpet bombed, block the request. if (!g_accept_requests) return BLOCK; @@ -147,18 +149,36 @@ return BLOCK; } - // Check the stored prefs. - // TODO(pkasting): This kind of thing should go in the preferences on the - // profile, not in the local state. http://crbug.com/457254 - PrefService* pref = g_browser_process->local_state(); - if (pref) { // May be NULL during testing. - DictionaryPrefUpdate update_excluded_schemas(pref, prefs::kExcludedSchemes); + // Check if there are any prefs in the local state. If there are, wipe them, + // and migrate the prefs to the profile. + // TODO(ramyasharma) remove the migration in M61. + PrefService* local_prefs = g_browser_process->local_state(); + PrefService* profile_prefs = profile->GetPrefs(); + if (local_prefs && profile_prefs) { // May be NULL during testing. + DictionaryPrefUpdate local_state_schemas(local_prefs, + prefs::kExcludedSchemes); + DictionaryPrefUpdate update_excluded_schemas_profile( + profile_prefs, prefs::kExcludedSchemes); + if (update_excluded_schemas_profile->empty()) { + // Copy local state to profile state. + for (base::DictionaryValue::Iterator it(*local_state_schemas); + !it.IsAtEnd(); it.Advance()) { + bool is_blocked; + // Discard local state if set to blocked, to reset all users + // stuck in 'Do Nothing' + 'Do Not Open' state back to the default + // prompt state. + if (it.value().GetAsBoolean(&is_blocked) && !is_blocked) + update_excluded_schemas_profile->SetBoolean(it.key(), is_blocked); + } + // TODO(ramyasharma): Clear only if required. + local_prefs->ClearPref(prefs::kExcludedSchemes); + } - // Warm up the dictionary if needed. - PrepopulateDictionary(update_excluded_schemas.Get()); + // Prepopulate the default states each time. + PrepopulateDictionary(update_excluded_schemas_profile.Get()); bool should_block; - if (update_excluded_schemas->GetBoolean(scheme, &should_block)) + if (update_excluded_schemas_profile->GetBoolean(scheme, &should_block)) return should_block ? BLOCK : DONT_BLOCK; } @@ -167,18 +187,18 @@ // static void ExternalProtocolHandler::SetBlockState(const std::string& scheme, - BlockState state) { + BlockState state, + Profile* profile) { // Set in the stored prefs. - // TODO(pkasting): This kind of thing should go in the preferences on the - // profile, not in the local state. http://crbug.com/457254 - PrefService* pref = g_browser_process->local_state(); - if (pref) { // May be NULL during testing. - DictionaryPrefUpdate update_excluded_schemas(pref, prefs::kExcludedSchemes); - - if (state == UNKNOWN) { - update_excluded_schemas->Remove(scheme, NULL); - } else { - update_excluded_schemas->SetBoolean(scheme, (state == BLOCK)); + PrefService* profile_prefs = profile->GetPrefs(); + if (profile_prefs) { // May be NULL during testing. + DictionaryPrefUpdate update_excluded_schemas_profile( + profile_prefs, prefs::kExcludedSchemes); + if (!update_excluded_schemas_profile->empty()) { + if (state == UNKNOWN) + update_excluded_schemas_profile->Remove(scheme, nullptr); + else + update_excluded_schemas_profile->SetBoolean(scheme, (state == BLOCK)); } } } @@ -197,8 +217,14 @@ // have parameters unexpected by the external program. std::string escaped_url_string = net::EscapeExternalHandlerValue(url.spec()); GURL escaped_url(escaped_url_string); + + content::WebContents* web_contents = tab_util::GetWebContentsByID( + render_process_host_id, render_view_routing_id); + Profile* profile = nullptr; + if (web_contents) // Maybe NULL during testing. + profile = Profile::FromBrowserContext(web_contents->GetBrowserContext()); BlockState block_state = - GetBlockStateWithDelegate(escaped_url.scheme(), delegate); + GetBlockStateWithDelegate(escaped_url.scheme(), delegate, profile); if (block_state == BLOCK) { if (delegate) delegate->BlockRequest(); @@ -243,11 +269,6 @@ // static void ExternalProtocolHandler::PrepopulateDictionary( base::DictionaryValue* win_pref) { - static bool is_warm = false; - if (is_warm) - return; - is_warm = true; - static const char* const denied_schemes[] = { "afp", "data",
diff --git a/chrome/browser/external_protocol/external_protocol_handler.h b/chrome/browser/external_protocol/external_protocol_handler.h index 99c0f03..e70e79bb 100644 --- a/chrome/browser/external_protocol/external_protocol_handler.h +++ b/chrome/browser/external_protocol/external_protocol_handler.h
@@ -14,6 +14,7 @@ class GURL; class PrefRegistrySimple; +class Profile; namespace base { class DictionaryValue; @@ -34,7 +35,8 @@ CreateShellWorker( const shell_integration::DefaultWebClientWorkerCallback& callback, const std::string& protocol) = 0; - virtual BlockState GetBlockState(const std::string& scheme) = 0; + virtual BlockState GetBlockState(const std::string& scheme, + Profile* profile) = 0; virtual void BlockRequest() = 0; virtual void RunExternalProtocolDialog( const GURL& url, @@ -50,10 +52,12 @@ }; // Returns whether we should block a given scheme. - static BlockState GetBlockState(const std::string& scheme); + static BlockState GetBlockState(const std::string& scheme, Profile* profile); // Sets whether we should block a given scheme. - static void SetBlockState(const std::string& scheme, BlockState state); + static void SetBlockState(const std::string& scheme, + BlockState state, + Profile* profile); // Checks to see if the protocol is allowed, if it is whitelisted, // the application associated with the protocol is launched on the io thread,
diff --git a/chrome/browser/external_protocol/external_protocol_handler_unittest.cc b/chrome/browser/external_protocol/external_protocol_handler_unittest.cc index e0c29f4..62e4c31f 100644 --- a/chrome/browser/external_protocol/external_protocol_handler_unittest.cc +++ b/chrome/browser/external_protocol/external_protocol_handler_unittest.cc
@@ -6,6 +6,11 @@ #include "base/message_loop/message_loop.h" #include "base/run_loop.h" +#include "chrome/browser/prefs/browser_prefs.h" +#include "chrome/common/pref_names.h" +#include "chrome/test/base/testing_browser_process.h" +#include "chrome/test/base/testing_profile.h" +#include "components/prefs/testing_pref_service.h" #include "content/public/test/test_browser_thread.h" #include "testing/gtest/include/gtest/gtest.h" @@ -52,8 +57,8 @@ return new FakeExternalProtocolHandlerWorker(callback, protocol, os_state_); } - ExternalProtocolHandler::BlockState GetBlockState( - const std::string& scheme) override { + ExternalProtocolHandler::BlockState GetBlockState(const std::string& scheme, + Profile* profile) override { return block_state_; } @@ -111,11 +116,19 @@ : ui_thread_(BrowserThread::UI, base::MessageLoop::current()), file_thread_(BrowserThread::FILE) {} - void SetUp() override { file_thread_.Start(); } + void SetUp() override { + file_thread_.Start(); + local_state_.reset(new TestingPrefServiceSimple); + profile_.reset(new TestingProfile()); + chrome::RegisterLocalState(local_state_->registry()); + TestingBrowserProcess::GetGlobal()->SetLocalState(local_state_.get()); + } void TearDown() override { // Ensure that g_accept_requests gets set back to true after test execution. ExternalProtocolHandler::PermitLaunchUrl(); + TestingBrowserProcess::GetGlobal()->SetLocalState(nullptr); + local_state_.reset(); } void DoTest(ExternalProtocolHandler::BlockState block_state, @@ -145,6 +158,9 @@ content::TestBrowserThread file_thread_; FakeExternalProtocolHandlerDelegate delegate_; + + std::unique_ptr<TestingPrefServiceSimple> local_state_; + std::unique_ptr<TestingProfile> profile_; }; TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeBlockedChromeDefault) { @@ -191,3 +207,56 @@ DoTest(ExternalProtocolHandler::UNKNOWN, shell_integration::UNKNOWN_DEFAULT, true, false, false); } + +TEST_F(ExternalProtocolHandlerTest, TestGetBlockStateUnknown) { + ExternalProtocolHandler::BlockState block_state = + ExternalProtocolHandler::GetBlockState("tel", profile_.get()); + ASSERT_EQ(ExternalProtocolHandler::UNKNOWN, block_state); + ASSERT_TRUE(local_state_->GetDictionary(prefs::kExcludedSchemes)->empty()); + ASSERT_FALSE( + profile_->GetPrefs()->GetDictionary(prefs::kExcludedSchemes)->empty()); +} + +TEST_F(ExternalProtocolHandlerTest, TestGetBlockStateDefaultBlock) { + ExternalProtocolHandler::BlockState block_state = + ExternalProtocolHandler::GetBlockState("afp", profile_.get()); + ASSERT_EQ(ExternalProtocolHandler::BLOCK, block_state); + ASSERT_TRUE(local_state_->GetDictionary(prefs::kExcludedSchemes)->empty()); + ASSERT_FALSE( + profile_->GetPrefs()->GetDictionary(prefs::kExcludedSchemes)->empty()); +} + +TEST_F(ExternalProtocolHandlerTest, TestGetBlockStateDefaultDontBlock) { + ExternalProtocolHandler::BlockState block_state = + ExternalProtocolHandler::GetBlockState("mailto", profile_.get()); + ASSERT_EQ(ExternalProtocolHandler::DONT_BLOCK, block_state); + ASSERT_TRUE(local_state_->GetDictionary(prefs::kExcludedSchemes)->empty()); + ASSERT_FALSE( + profile_->GetPrefs()->GetDictionary(prefs::kExcludedSchemes)->empty()); +} + +TEST_F(ExternalProtocolHandlerTest, + TestGetBlockStateLocalBlockStateCopiedAndResetOnProfilePref) { + base::DictionaryValue prefs_local; + prefs_local.SetBoolean("tel", true); + local_state_->Set(prefs::kExcludedSchemes, prefs_local); + ExternalProtocolHandler::BlockState block_state = + ExternalProtocolHandler::GetBlockState("tel", profile_.get()); + ASSERT_EQ(ExternalProtocolHandler::UNKNOWN, block_state); + ASSERT_TRUE(local_state_->GetDictionary(prefs::kExcludedSchemes)->empty()); + ASSERT_FALSE( + profile_->GetPrefs()->GetDictionary(prefs::kExcludedSchemes)->empty()); +} + +TEST_F(ExternalProtocolHandlerTest, + TestGetBlockStateLocalDontBlockCopiedAsIsToProfilePref) { + base::DictionaryValue prefs_local; + prefs_local.SetBoolean("tel", false); + local_state_->Set(prefs::kExcludedSchemes, prefs_local); + ExternalProtocolHandler::BlockState block_state = + ExternalProtocolHandler::GetBlockState("tel", profile_.get()); + ASSERT_EQ(ExternalProtocolHandler::DONT_BLOCK, block_state); + ASSERT_TRUE(local_state_->GetDictionary(prefs::kExcludedSchemes)->empty()); + ASSERT_FALSE( + profile_->GetPrefs()->GetDictionary(prefs::kExcludedSchemes)->empty()); +}
diff --git a/chrome/browser/prerender/prerender_test_utils.cc b/chrome/browser/prerender/prerender_test_utils.cc index 0a844c8..73a22726 100644 --- a/chrome/browser/prerender/prerender_test_utils.cc +++ b/chrome/browser/prerender/prerender_test_utils.cc
@@ -224,8 +224,8 @@ return nullptr; } - ExternalProtocolHandler::BlockState GetBlockState( - const std::string& scheme) override { + ExternalProtocolHandler::BlockState GetBlockState(const std::string& scheme, + Profile* profile) override { // Block everything and fail the test. ADD_FAILURE(); return ExternalProtocolHandler::BLOCK;
diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc index c8f14b2..d32c584 100644 --- a/chrome/browser/profiles/profile.cc +++ b/chrome/browser/profiles/profile.cc
@@ -176,6 +176,8 @@ #if defined(OS_CHROMEOS) registry->RegisterBooleanPref(prefs::kAllowScreenLock, true); #endif + + registry->RegisterDictionaryPref(prefs::kExcludedSchemes); } std::string Profile::GetDebugName() {
diff --git a/chrome/browser/ui/cocoa/external_protocol_dialog_cocoa.mm b/chrome/browser/ui/cocoa/external_protocol_dialog_cocoa.mm index a53e065..6951e76b 100644 --- a/chrome/browser/ui/cocoa/external_protocol_dialog_cocoa.mm +++ b/chrome/browser/ui/cocoa/external_protocol_dialog_cocoa.mm
@@ -7,6 +7,7 @@ #include "base/message_loop/message_loop.h" #include "base/metrics/histogram_macros.h" #include "chrome/browser/external_protocol/external_protocol_handler.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/browser/shell_integration.h" #include "chrome/browser/tab_contents/tab_util.h" #include "chrome/grit/chromium_strings.h" @@ -94,9 +95,15 @@ NOTREACHED(); } + content::WebContents* web_contents = + tab_util::GetWebContentsByID(render_process_host_id_, routing_id_); + // Set the "don't warn me again" info. if ([[alert_ suppressionButton] state] == NSOnState) { - ExternalProtocolHandler::SetBlockState(url_.scheme(), blockState); + Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); + + ExternalProtocolHandler::SetBlockState(url_.scheme(), blockState, profile); ExternalProtocolHandler::RecordMetrics(true); } else { ExternalProtocolHandler::RecordMetrics(false); @@ -106,9 +113,6 @@ UMA_HISTOGRAM_LONG_TIMES("clickjacking.launch_url", base::Time::Now() - creation_time_); - content::WebContents* web_contents = - tab_util::GetWebContentsByID(render_process_host_id_, routing_id_); - ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck(url_, web_contents); }
diff --git a/chrome/browser/ui/external_protocol_dialog_delegate.cc b/chrome/browser/ui/external_protocol_dialog_delegate.cc index 20c662f..925c834 100644 --- a/chrome/browser/ui/external_protocol_dialog_delegate.cc +++ b/chrome/browser/ui/external_protocol_dialog_delegate.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/ui/external_protocol_dialog_delegate.h" #include "chrome/browser/external_protocol/external_protocol_handler.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/browser/tab_contents/tab_util.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" @@ -61,21 +62,29 @@ void ExternalProtocolDialogDelegate::DoAccept(const GURL& url, bool dont_block) const { - if (dont_block) { - ExternalProtocolHandler::SetBlockState(url.scheme(), - ExternalProtocolHandler::DONT_BLOCK); - } - content::WebContents* web_contents = tab_util::GetWebContentsByID( render_process_host_id_, render_view_routing_id_); + if (dont_block) { + Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); + + ExternalProtocolHandler::SetBlockState( + url.scheme(), ExternalProtocolHandler::DONT_BLOCK, profile); + } + ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck(url, web_contents); } void ExternalProtocolDialogDelegate::DoCancel(const GURL& url, bool dont_block) const { if (dont_block) { - ExternalProtocolHandler::SetBlockState(url.scheme(), - ExternalProtocolHandler::BLOCK); + content::WebContents* web_contents = tab_util::GetWebContentsByID( + render_process_host_id_, render_view_routing_id_); + Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); + + ExternalProtocolHandler::SetBlockState( + url.scheme(), ExternalProtocolHandler::BLOCK, profile); } }