diff --git a/DEPS b/DEPS index 0182c5b..7199c16d 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': 'a5fdc974a996dca79be8388e61db68043001760b', + 'skia_revision': 'db0e4f952a71a7a5009ec8276a234227e0ec18f6', # 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/browser/browsing_data/browsing_data_remover.h b/chrome/browser/browsing_data/browsing_data_remover.h index b291f46..335844d 100644 --- a/chrome/browser/browsing_data/browsing_data_remover.h +++ b/chrome/browser/browsing_data/browsing_data_remover.h
@@ -80,6 +80,7 @@ REMOVE_WEBAPP_DATA = 1 << 18, #endif REMOVE_DURABLE_PERMISSION = 1 << 19, + REMOVE_EXTERNAL_PROTOCOL_DATA = 1 << 20, // The following flag is used only in tests. In normal usage, hosted app // data is controlled by the REMOVE_COOKIES flag, applied to the @@ -101,7 +102,8 @@ REMOVE_WEBAPP_DATA | #endif REMOVE_SITE_USAGE_DATA | - REMOVE_DURABLE_PERMISSION, + REMOVE_DURABLE_PERMISSION | + REMOVE_EXTERNAL_PROTOCOL_DATA, // Datatypes protected by Important Sites. IMPORTANT_SITES_DATATYPES = REMOVE_SITE_DATA | REMOVE_CACHE,
diff --git a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc index bb4b12a1..69a1b303 100644 --- a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc +++ b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/browsing_data/browsing_data_remover_test_util.h" #include "chrome/browser/browsing_data/cache_counter.h" #include "chrome/browser/chrome_notification_types.h" +#include "chrome/browser/external_protocol/external_protocol_handler.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -274,6 +275,20 @@ EXPECT_EQ(0, GetCacheSize()); } +IN_PROC_BROWSER_TEST_F(BrowsingDataRemoverBrowserTest, + ExternalProtocolHandlerPrefs) { + Profile* profile = browser()->profile(); + base::DictionaryValue prefs; + prefs.SetBoolean("tel", true); + profile->GetPrefs()->Set(prefs::kExcludedSchemes, prefs); + ExternalProtocolHandler::BlockState block_state = + ExternalProtocolHandler::GetBlockState("tel", profile); + ASSERT_EQ(ExternalProtocolHandler::BLOCK, block_state); + RemoveAndWait(BrowsingDataRemover::REMOVE_SITE_DATA); + block_state = ExternalProtocolHandler::GetBlockState("tel", profile); + ASSERT_EQ(ExternalProtocolHandler::UNKNOWN, block_state); +} + // Verify that TransportSecurityState data is cleared for REMOVE_CACHE. IN_PROC_BROWSER_TEST_F(BrowsingDataRemoverTransportSecurityStateBrowserTest, ClearTransportSecurityState) {
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc index 2e75283..ceb6cd3 100644 --- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc +++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
@@ -17,6 +17,7 @@ #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/domain_reliability/service_factory.h" #include "chrome/browser/download/download_prefs.h" +#include "chrome/browser/external_protocol/external_protocol_handler.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/history/web_history_service_factory.h" #include "chrome/browser/io_thread.h" @@ -925,6 +926,11 @@ webapp_registry_->UnregisterWebappsForUrls(filter); #endif + ////////////////////////////////////////////////////////////////////////////// + // Remove external protocol data. + if (remove_mask & BrowsingDataRemover::REMOVE_EXTERNAL_PROTOCOL_DATA) + ExternalProtocolHandler::ClearData(profile_); + synchronous_clear_operations_.GetCompletionCallback().Run(); }
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc index cc3445c..26ddb051 100644 --- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc +++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
@@ -1056,6 +1056,23 @@ } #endif +TEST_F(ChromeBrowsingDataRemoverDelegateTest, RemoveExternalProtocolData) { + TestingProfile* profile = GetProfile(); + // Add external protocol data on profile. + base::DictionaryValue prefs; + prefs.SetBoolean("tel", true); + profile->GetPrefs()->Set(prefs::kExcludedSchemes, prefs); + + EXPECT_FALSE( + profile->GetPrefs()->GetDictionary(prefs::kExcludedSchemes)->empty()); + + BlockUntilBrowsingDataRemoved( + AnHourAgo(), base::Time::Max(), + BrowsingDataRemover::REMOVE_EXTERNAL_PROTOCOL_DATA, false); + EXPECT_TRUE( + profile->GetPrefs()->GetDictionary(prefs::kExcludedSchemes)->empty()); +} + // Test that clearing history deletes favicons not associated with bookmarks. TEST_F(ChromeBrowsingDataRemoverDelegateTest, RemoveFaviconsForever) { GURL page_url("http://a");
diff --git a/chrome/browser/extensions/api/browsing_data/browsing_data_test.cc b/chrome/browser/extensions/api/browsing_data/browsing_data_test.cc index 7cbdbbb..10efc18 100644 --- a/chrome/browser/extensions/api/browsing_data/browsing_data_test.cc +++ b/chrome/browser/extensions/api/browsing_data/browsing_data_test.cc
@@ -222,6 +222,7 @@ BrowsingDataRemover::REMOVE_WEBSQL) | GetAsMask(data_to_remove, "serverBoundCertificates", BrowsingDataRemover::REMOVE_CHANNEL_IDS); + EXPECT_EQ(expected_removal_mask, removal_mask); } @@ -288,21 +289,25 @@ browser())); EXPECT_EQ(base::Time::FromDoubleT(1.0), GetBeginTime()); - EXPECT_EQ((BrowsingDataRemover::REMOVE_SITE_DATA | - BrowsingDataRemover::REMOVE_CACHE | - BrowsingDataRemover::REMOVE_DOWNLOADS | - BrowsingDataRemover::REMOVE_FORM_DATA | - BrowsingDataRemover::REMOVE_HISTORY | - BrowsingDataRemover::REMOVE_PASSWORDS) & - // TODO(benwells): implement clearing of site usage data via the - // browsing data API. https://crbug.com/500801. - ~BrowsingDataRemover::REMOVE_SITE_USAGE_DATA & - // TODO(dmurph): implement clearing of durable storage permission - // via the browsing data API. https://crbug.com/500801. - ~BrowsingDataRemover::REMOVE_DURABLE_PERMISSION & - // We can't remove plugin data inside a test profile. - ~BrowsingDataRemover::REMOVE_PLUGIN_DATA, - GetRemovalMask()); + EXPECT_EQ( + (BrowsingDataRemover::REMOVE_SITE_DATA | + BrowsingDataRemover::REMOVE_CACHE | + BrowsingDataRemover::REMOVE_DOWNLOADS | + BrowsingDataRemover::REMOVE_FORM_DATA | + BrowsingDataRemover::REMOVE_HISTORY | + BrowsingDataRemover::REMOVE_PASSWORDS) & + // TODO(benwells): implement clearing of site usage data via the + // browsing data API. https://crbug.com/500801. + ~BrowsingDataRemover::REMOVE_SITE_USAGE_DATA & + // TODO(dmurph): implement clearing of durable storage permission + // via the browsing data API. https://crbug.com/500801. + ~BrowsingDataRemover::REMOVE_DURABLE_PERMISSION & + // We can't remove plugin data inside a test profile. + ~BrowsingDataRemover::REMOVE_PLUGIN_DATA & + // TODO(ramyasharma): implement clearing of external protocol data + // via the browsing data API. https://crbug.com/692850. + ~BrowsingDataRemover::REMOVE_EXTERNAL_PROTOCOL_DATA, + GetRemovalMask()); } IN_PROC_BROWSER_TEST_F(ExtensionBrowsingDataTest, BrowsingDataOriginTypeMask) { @@ -478,46 +483,46 @@ // Test cookie and app data settings. IN_PROC_BROWSER_TEST_F(ExtensionBrowsingDataTest, SettingsFunctionSiteData) { - int site_data_no_durable_or_usage = + int site_data_no_durable_or_usage_or_external = BrowsingDataRemover::REMOVE_SITE_DATA & ~BrowsingDataRemover::REMOVE_SITE_USAGE_DATA & - ~BrowsingDataRemover::REMOVE_DURABLE_PERMISSION; - int site_data_no_plugins_durable_usage = - site_data_no_durable_or_usage & ~BrowsingDataRemover::REMOVE_PLUGIN_DATA; + ~BrowsingDataRemover::REMOVE_DURABLE_PERMISSION & + ~BrowsingDataRemover::REMOVE_EXTERNAL_PROTOCOL_DATA; + int site_data_no_plugins_durable_usage_external = + site_data_no_durable_or_usage_or_external & + ~BrowsingDataRemover::REMOVE_PLUGIN_DATA; SetPrefsAndVerifySettings(BrowsingDataRemover::REMOVE_COOKIES, UNPROTECTED_WEB, - site_data_no_plugins_durable_usage); + site_data_no_plugins_durable_usage_external); SetPrefsAndVerifySettings( - BrowsingDataRemover::REMOVE_HOSTED_APP_DATA_TESTONLY, - PROTECTED_WEB, - site_data_no_plugins_durable_usage); + BrowsingDataRemover::REMOVE_HOSTED_APP_DATA_TESTONLY, PROTECTED_WEB, + site_data_no_plugins_durable_usage_external); SetPrefsAndVerifySettings( BrowsingDataRemover::REMOVE_COOKIES | BrowsingDataRemover::REMOVE_HOSTED_APP_DATA_TESTONLY, PROTECTED_WEB | UNPROTECTED_WEB, - site_data_no_plugins_durable_usage); - SetPrefsAndVerifySettings( - BrowsingDataRemover::REMOVE_COOKIES | - BrowsingDataRemover::REMOVE_PLUGIN_DATA, - UNPROTECTED_WEB, - site_data_no_durable_or_usage); + site_data_no_plugins_durable_usage_external); + SetPrefsAndVerifySettings(BrowsingDataRemover::REMOVE_COOKIES | + BrowsingDataRemover::REMOVE_PLUGIN_DATA, + UNPROTECTED_WEB, + site_data_no_durable_or_usage_or_external); } // Test an arbitrary assortment of settings. IN_PROC_BROWSER_TEST_F(ExtensionBrowsingDataTest, SettingsFunctionAssorted) { - int site_data_no_plugins_durable_usage = + int site_data_no_plugins_durable_usage_external = BrowsingDataRemover::REMOVE_SITE_DATA & ~BrowsingDataRemover::REMOVE_DURABLE_PERMISSION & ~BrowsingDataRemover::REMOVE_SITE_USAGE_DATA & - ~BrowsingDataRemover::REMOVE_PLUGIN_DATA; + ~BrowsingDataRemover::REMOVE_PLUGIN_DATA & + ~BrowsingDataRemover::REMOVE_EXTERNAL_PROTOCOL_DATA; - SetPrefsAndVerifySettings( - BrowsingDataRemover::REMOVE_COOKIES | - BrowsingDataRemover::REMOVE_HISTORY | - BrowsingDataRemover::REMOVE_DOWNLOADS, - UNPROTECTED_WEB, - site_data_no_plugins_durable_usage | - BrowsingDataRemover::REMOVE_HISTORY | - BrowsingDataRemover::REMOVE_DOWNLOADS); + SetPrefsAndVerifySettings(BrowsingDataRemover::REMOVE_COOKIES | + BrowsingDataRemover::REMOVE_HISTORY | + BrowsingDataRemover::REMOVE_DOWNLOADS, + UNPROTECTED_WEB, + site_data_no_plugins_durable_usage_external | + BrowsingDataRemover::REMOVE_HISTORY | + BrowsingDataRemover::REMOVE_DOWNLOADS); }
diff --git a/chrome/browser/external_protocol/external_protocol_handler.cc b/chrome/browser/external_protocol/external_protocol_handler.cc index 29f98ed..36b9fdc5 100644 --- a/chrome/browser/external_protocol/external_protocol_handler.cc +++ b/chrome/browser/external_protocol/external_protocol_handler.cc
@@ -345,3 +345,9 @@ void ExternalProtocolHandler::RegisterPrefs(PrefRegistrySimple* registry) { registry->RegisterDictionaryPref(prefs::kExcludedSchemes); } + +// static +void ExternalProtocolHandler::ClearData(Profile* profile) { + PrefService* prefs = profile->GetPrefs(); + prefs->ClearPref(prefs::kExcludedSchemes); +}
diff --git a/chrome/browser/external_protocol/external_protocol_handler.h b/chrome/browser/external_protocol/external_protocol_handler.h index 30a1600..671626f 100644 --- a/chrome/browser/external_protocol/external_protocol_handler.h +++ b/chrome/browser/external_protocol/external_protocol_handler.h
@@ -140,6 +140,9 @@ ui::PageTransition page_transition, bool has_user_gesture); + // Clears the external protocol handling data. + static void ClearData(Profile* profile); + private: DISALLOW_COPY_AND_ASSIGN(ExternalProtocolHandler); };
diff --git a/chrome/browser/external_protocol/external_protocol_handler_unittest.cc b/chrome/browser/external_protocol/external_protocol_handler_unittest.cc index 62e4c31f..150d509 100644 --- a/chrome/browser/external_protocol/external_protocol_handler_unittest.cc +++ b/chrome/browser/external_protocol/external_protocol_handler_unittest.cc
@@ -260,3 +260,14 @@ ASSERT_FALSE( profile_->GetPrefs()->GetDictionary(prefs::kExcludedSchemes)->empty()); } + +TEST_F(ExternalProtocolHandlerTest, TestClearProfileState) { + base::DictionaryValue prefs; + prefs.SetBoolean("tel", true); + profile_->GetPrefs()->Set(prefs::kExcludedSchemes, prefs); + ASSERT_FALSE( + profile_->GetPrefs()->GetDictionary(prefs::kExcludedSchemes)->empty()); + ExternalProtocolHandler::ClearData(profile_.get()); + ASSERT_TRUE( + profile_->GetPrefs()->GetDictionary(prefs::kExcludedSchemes)->empty()); +}
diff --git a/chrome/browser/signin/easy_unlock_service.cc b/chrome/browser/signin/easy_unlock_service.cc index 1679d36..b76ae430 100644 --- a/chrome/browser/signin/easy_unlock_service.cc +++ b/chrome/browser/signin/easy_unlock_service.cc
@@ -64,21 +64,10 @@ #include "components/signin/core/account_id/account_id.h" #endif -#if defined(OS_WIN) -#include "base/win/windows_version.h" -#endif - using proximity_auth::ScreenlockState; namespace { -enum BluetoothType { - BT_NO_ADAPTER, - BT_NORMAL, - BT_LOW_ENERGY_CAPABLE, - BT_MAX_TYPE -}; - PrefService* GetLocalState() { return g_browser_process ? g_browser_process->local_state() : NULL; } @@ -145,32 +134,17 @@ service_->OnBluetoothAdapterPresentChanged(); } - device::BluetoothAdapter* getAdapter() { - return adapter_.get(); - } - private: void OnAdapterInitialized(scoped_refptr<device::BluetoothAdapter> adapter) { adapter_ = adapter; adapter_->AddObserver(this); service_->OnBluetoothAdapterPresentChanged(); -#if !defined(OS_CHROMEOS) - // Bluetooth detection causes serious performance degradations on Mac - // and possibly other platforms as well: http://crbug.com/467316 - // Since this feature is currently only offered for ChromeOS we just - // turn it off on other platforms once the inforamtion about the - // adapter has been gathered and reported. - // TODO(bcwhite,xiyuan): Revisit when non-chromeos platforms are supported. - adapter_->RemoveObserver(this); - adapter_ = NULL; -#else // TODO(tengs): At the moment, there is no way for Bluetooth discoverability // to be turned on except through the Easy Unlock setup. If we step on any // toes in the future then we need to revisit this guard. if (adapter_->IsDiscoverable()) TurnOffBluetoothDiscoverability(); -#endif // !defined(OS_CHROMEOS) } // apps::AppLifetimeMonitor::Observer: @@ -744,31 +718,20 @@ CHECK(app_manager_.get()); InitializeInternal(); + +#if defined(OS_CHROMEOS) + // Only start Bluetooth detection for ChromeOS since the feature is + // only offered on ChromeOS. Enabling this on non-ChromeOS platforms + // previously introduced a performance regression: http://crbug.com/404482 + // Make sure not to reintroduce a performance regression if re-enabling on + // additional platforms. + // TODO(xiyuan): Revisit when non-chromeos platforms are supported. bluetooth_detector_->Initialize(); +#endif // defined(OS_CHROMEOS) } void EasyUnlockService::OnBluetoothAdapterPresentChanged() { UpdateAppState(); - - // Whether we've already passed Bluetooth availability information to UMA. - // This is static because there may be multiple instances and we want to - // report this system-level stat only once per run of Chrome. - static bool bluetooth_adapter_has_been_reported = false; - - if (!bluetooth_adapter_has_been_reported) { - bluetooth_adapter_has_been_reported = true; - int bttype = BT_NO_ADAPTER; - if (bluetooth_detector_->IsPresent()) { - bttype = BT_LOW_ENERGY_CAPABLE; -#if defined(OS_WIN) - if (base::win::GetVersion() < base::win::VERSION_WIN8) { - bttype = BT_NORMAL; - } -#endif - } - UMA_HISTOGRAM_ENUMERATION( - "EasyUnlock.BluetoothAvailability", bttype, BT_MAX_TYPE); - } } void EasyUnlockService::SetHardlockStateForUser(
diff --git a/third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h b/third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h index e329fe3..5d37829 100644 --- a/third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h +++ b/third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h
@@ -890,6 +890,7 @@ unsigned prefixLength = hyphenation.lastHyphenLocation( StringView(text.text(), start, len), std::min(maxPrefixLength, len - Hyphenation::minimumSuffixLength) + 1); + DCHECK_LE(prefixLength, maxPrefixLength); if (!prefixLength || prefixLength < Hyphenation::minimumPrefixLength) return false;
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn index 5b469fe..a7bae8a 100644 --- a/third_party/WebKit/Source/platform/BUILD.gn +++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -1509,6 +1509,7 @@ if (use_minikin_hyphenation) { sources += [ "text/hyphenation/HyphenationMinikin.cpp", + "text/hyphenation/HyphenationMinikin.h", "text/hyphenation/HyphenatorAOSP.cpp", "text/hyphenation/HyphenatorAOSP.h", ]
diff --git a/third_party/WebKit/Source/platform/text/HyphenationTest.cpp b/third_party/WebKit/Source/platform/text/HyphenationTest.cpp index f4acfb6..aca243d13 100644 --- a/third_party/WebKit/Source/platform/text/HyphenationTest.cpp +++ b/third_party/WebKit/Source/platform/text/HyphenationTest.cpp
@@ -7,6 +7,11 @@ #include "platform/LayoutLocale.h" #include "testing/gtest/include/gtest/gtest.h" +#if OS(ANDROID) +#include "base/files/file_path.h" +#include "platform/text/hyphenation/HyphenationMinikin.h" +#endif + namespace blink { class NoHyphenation : public Hyphenation { @@ -28,4 +33,52 @@ LayoutLocale::clearForTesting(); } +#if OS(ANDROID) || OS(MACOSX) +TEST(HyphenationTest, LastHyphenLocation) { +#if OS(ANDROID) + // Because the mojo service to open hyphenation dictionaries is not accessible + // from the unit test, open the dictionary file directly for testing. + base::FilePath path("/system/usr/hyphen-data/hyph-en-us.hyb"); + base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ); + if (!file.IsValid()) { + // Ignore this test on platforms without hyphenation dictionaries. + return; + } + RefPtr<Hyphenation> hyphenation = + HyphenationMinikin::fromFileForTesting(std::move(file)); +#else + const LayoutLocale* locale = LayoutLocale::get("en-us"); + ASSERT_TRUE(locale); + Hyphenation* hyphenation = locale->getHyphenation(); +#endif + ASSERT_TRUE(hyphenation) << "Cannot find the hyphenation engine"; + + // Get all hyphenation points by |hyphenLocations|. + const String word("hyphenation"); + Vector<size_t, 8> locations = hyphenation->hyphenLocations(word); + for (unsigned i = 1; i < locations.size(); i++) { + ASSERT_GT(locations[i - 1], locations[i]) + << "hyphenLocations must return locations in the descending order"; + } + + // Test |lastHyphenLocation| returns all hyphenation points. + locations.push_back(0); + size_t locationIndex = locations.size() - 1; + for (size_t beforeIndex = 0; beforeIndex < word.length(); beforeIndex++) { + size_t location = hyphenation->lastHyphenLocation(word, beforeIndex); + + if (location) + EXPECT_LT(location, beforeIndex); + + if (locationIndex > 0 && location == locations[locationIndex - 1]) + locationIndex--; + EXPECT_EQ(locations[locationIndex], location) << String::format( + "lastHyphenLocation(%s, %zd)", word.utf8().data(), beforeIndex); + } + + EXPECT_EQ(locationIndex, 0u) + << "Not all locations are found by lastHyphenLocation"; +} +#endif + } // namespace blink
diff --git a/third_party/WebKit/Source/platform/text/hyphenation/HyphenationMinikin.cpp b/third_party/WebKit/Source/platform/text/hyphenation/HyphenationMinikin.cpp index a930cc7..d6749b9 100644 --- a/third_party/WebKit/Source/platform/text/hyphenation/HyphenationMinikin.cpp +++ b/third_party/WebKit/Source/platform/text/hyphenation/HyphenationMinikin.cpp
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "platform/text/Hyphenation.h" +#include "platform/text/hyphenation/HyphenationMinikin.h" #include "base/files/file.h" #include "base/files/memory_mapped_file.h" @@ -18,23 +18,6 @@ using Hyphenator = android::Hyphenator; -class HyphenationMinikin : public Hyphenation { - public: - bool openDictionary(const AtomicString& locale); - - size_t lastHyphenLocation(const StringView& text, - size_t beforeIndex) const override; - Vector<size_t, 8> hyphenLocations(const StringView&) const override; - - private: - static base::File openDictionaryFile(const AtomicString& locale); - - std::vector<uint8_t> hyphenate(const StringView&) const; - - base::MemoryMappedFile m_file; - std::unique_ptr<Hyphenator> m_hyphenator; -}; - static mojom::blink::HyphenationPtr connectToRemoteService() { mojom::blink::HyphenationPtr service; Platform::current()->interfaceProvider()->getInterface( @@ -48,17 +31,17 @@ return service; } -base::File HyphenationMinikin::openDictionaryFile(const AtomicString& locale) { +bool HyphenationMinikin::openDictionary(const AtomicString& locale) { const mojom::blink::HyphenationPtr& service = getService(); base::File file; base::ElapsedTimer timer; service->OpenDictionary(locale, &file); UMA_HISTOGRAM_TIMES("Hyphenation.Open", timer.Elapsed()); - return file; + + return openDictionary(std::move(file)); } -bool HyphenationMinikin::openDictionary(const AtomicString& locale) { - base::File file = openDictionaryFile(locale); +bool HyphenationMinikin::openDictionary(base::File file) { if (!file.IsValid()) return false; if (!m_file.Initialize(std::move(file))) { @@ -87,14 +70,17 @@ size_t HyphenationMinikin::lastHyphenLocation(const StringView& text, size_t beforeIndex) const { - if (text.length() < minimumPrefixLength + minimumSuffixLength) + if (text.length() < minimumPrefixLength + minimumSuffixLength || + beforeIndex <= minimumPrefixLength) return 0; std::vector<uint8_t> result = hyphenate(text); - static_assert(minimumPrefixLength >= 1, - "Change the 'if' above if this fails"); - for (size_t i = text.length() - minimumSuffixLength - 1; - i >= minimumPrefixLength; i--) { + beforeIndex = + std::min<size_t>(beforeIndex, text.length() - minimumSuffixLength); + CHECK_LE(beforeIndex, result.size()); + CHECK_GE(beforeIndex, 1u); + static_assert(minimumPrefixLength >= 1, "|beforeIndex - 1| can underflow"); + for (size_t i = beforeIndex - 1; i >= minimumPrefixLength; i--) { if (result[i]) return i; } @@ -170,4 +156,12 @@ return nullptr; } +PassRefPtr<HyphenationMinikin> HyphenationMinikin::fromFileForTesting( + base::File file) { + RefPtr<HyphenationMinikin> hyphenation(adoptRef(new HyphenationMinikin)); + if (hyphenation->openDictionary(std::move(file))) + return hyphenation.release(); + return nullptr; +} + } // namespace blink
diff --git a/third_party/WebKit/Source/platform/text/hyphenation/HyphenationMinikin.h b/third_party/WebKit/Source/platform/text/hyphenation/HyphenationMinikin.h new file mode 100644 index 0000000..1f61b43 --- /dev/null +++ b/third_party/WebKit/Source/platform/text/hyphenation/HyphenationMinikin.h
@@ -0,0 +1,39 @@ +// Copyright 2017 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 "platform/text/Hyphenation.h" + +#include "base/files/memory_mapped_file.h" +#include "platform/PlatformExport.h" + +namespace base { +class File; +} // namespace base + +namespace android { +class Hyphenator; +} // namespace andorid + +namespace blink { + +class PLATFORM_EXPORT HyphenationMinikin : public Hyphenation { + public: + bool openDictionary(const AtomicString& locale); + + size_t lastHyphenLocation(const StringView& text, + size_t beforeIndex) const override; + Vector<size_t, 8> hyphenLocations(const StringView&) const override; + + static PassRefPtr<HyphenationMinikin> fromFileForTesting(base::File); + + private: + bool openDictionary(base::File); + + std::vector<uint8_t> hyphenate(const StringView&) const; + + base::MemoryMappedFile m_file; + std::unique_ptr<android::Hyphenator> m_hyphenator; +}; + +} // namespace blink
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index cbba338..f7fd8937 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -13578,6 +13578,9 @@ <histogram name="EasyUnlock.BluetoothAvailability" enum="EasyUnlockBluetoothType"> + <obsolete> + Deprecated as of 02/2017. + </obsolete> <owner>bcwhite@chromium.org</owner> <summary> Reports the type of Bluetooth adapter present in the device.