diff --git a/BUILD.gn b/BUILD.gn index 044f7c6..edce1e2 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -205,8 +205,10 @@ } else { deps += [ "//ios/net:ios_net_unittests", + "//ios/public/provider/chrome/browser", "//ios/public/provider/web", "//ios/testing:ocmock_support_unittest", + "//ios/web/shell:ios_web_shell", "//ios/web:ios_web_unittests", ] } @@ -389,7 +391,6 @@ "//chrome/test:sync_performance_tests", "//chrome/test/chromedriver:chromedriver", "//chrome/test/chromedriver:chromedriver_tests", - "//chrome/tools/profile_reset:jtl_compiler", "//components:components_perftests", "//content/test:content_gl_tests", "//content/test:content_gl_benchmark",
diff --git a/DEPS b/DEPS index 431a94c..b02f31e 100644 --- a/DEPS +++ b/DEPS
@@ -39,11 +39,11 @@ # 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': 'd6346290c2ef59abee453a72f3e91b4e7b62f4fa', + 'skia_revision': '195fe08421f3a6c52ed621be96dbcc5393b41e69', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '452eb33784734448cc9dca639dd6d44df49e4a4c', + 'v8_revision': '9ac4a7402201283527c49026ce31e232b325227d', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -187,10 +187,10 @@ Var('chromium_git') + '/webm/libvpx.git' + '@' + '0941ff72a00732cea6750477edfe649348e699de', 'src/third_party/ffmpeg': - Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + 'be6eebd8727037bd013e537e4783d2da6927293b', + Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + '3540f6b0097b03aae1f29e41d8d8433044ee8cdb', 'src/third_party/libjingle/source/talk': - Var('chromium_git') + '/external/webrtc/trunk/talk.git' + '@' + '146443f0b4ae5307b49b7500de975bc2e39cba4b', # commit position 10646 + Var('chromium_git') + '/external/webrtc/trunk/talk.git' + '@' + '4cccfb61750309f0ec44170fcc098297f955f4db', # commit position 10659 'src/third_party/usrsctp/usrsctplib': Var('chromium_git') + '/external/usrsctplib.git' + '@' + '36444a999739e9e408f8f587cb4c3ffeef2e50ac', # from svn revision 9215 @@ -214,7 +214,7 @@ Var('chromium_git') + '/native_client/src/third_party/scons-2.0.1.git' + '@' + '1c1550e17fc26355d08627fbdec13d8291227067', 'src/third_party/webrtc': - Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '74bf4845fb2878f04756169abf1f1da5ae9971d5', # commit position 10649 + Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '1b5ad57a60538686c1c8ee2f2122642950182cca', # commit position 10669 'src/third_party/openmax_dl': Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' + Var('openmax_dl_revision'),
diff --git a/WATCHLISTS b/WATCHLISTS index 6c8a2f7..4f2e178c 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -1168,9 +1168,6 @@ 'filepath': 'third_party/WebKit/LayoutTests/imported/' \ '|third_party/WebKit/Tools/Scripts/webkitpy/w3c/' }, - 'blink_web_idl': { - 'filepath': 'third_party/WebKit/Source/core/.*\.idl' - }, 'blink_webcomponents': { 'filepath': 'third_party/WebKit/Source/core/dom/shadow/' \ '|third_party/WebKit/Source/core/dom/custom/' \ @@ -1554,7 +1551,6 @@ 'mlamouri+watch-blink@chromium.org' ], 'blink_device_orientation': [ 'timvolodine@chromium.org', 'mvanouwerkerk+watch@chromium.org', - 'ch.dumez@samsung.com', 'mlamouri+watch-blink@chromium.org' ], 'blink_devtools': [ 'pfeldman+blink@chromium.org', 'apavlov+blink@chromium.org', @@ -1684,9 +1680,6 @@ 'blink_out_of_process_frames': [ 'dcheng@chromium.org', 'mlamouri+watch-blink@chromium.org' ], 'blink_screen_orientation': [ 'mlamouri+watch-blink@chromium.org' ], - 'blink_web_idl': [ 'ch.dumez@samsung.com', - 'vivekg@chromium.org', - 'vivek.vg@samsung.com' ], 'blink_websockets': [ 'tyoshino+watch@chromium.org', 'yhirano+watch@chromium.org' ], 'blink_workers': [ 'blink-worker-reviews@chromium.org',
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java index bec617c..c610d5a 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContents.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -930,8 +930,7 @@ Activity activity = ContentViewCore.activityFromContext(context); if (activity == null) { if (sCachedWindowAndroid == null) { - sCachedWindowAndroid = new WindowAndroidWrapper( - new WindowAndroid(context.getApplicationContext())); + sCachedWindowAndroid = new WindowAndroidWrapper(new WindowAndroid(context)); } return sCachedWindowAndroid; }
diff --git a/ash/display/window_tree_host_manager.cc b/ash/display/window_tree_host_manager.cc index af7d17c..aabf1b2 100644 --- a/ash/display/window_tree_host_manager.cc +++ b/ash/display/window_tree_host_manager.cc
@@ -286,6 +286,8 @@ } void WindowTreeHostManager::Shutdown() { + FOR_EACH_OBSERVER(Observer, observers_, OnWindowTreeHostManagerShutdown()); + // Unset the display manager's delegate here because // DisplayManager outlives WindowTreeHostManager. Shell::GetInstance()->display_manager()->set_delegate(nullptr);
diff --git a/ash/display/window_tree_host_manager.h b/ash/display/window_tree_host_manager.h index 5d276992..67ae28d 100644 --- a/ash/display/window_tree_host_manager.h +++ b/ash/display/window_tree_host_manager.h
@@ -72,7 +72,10 @@ // Invoked when the all display configuration changes // have been applied. - virtual void OnDisplayConfigurationChanged(){}; + virtual void OnDisplayConfigurationChanged() {} + + // Invoked in WindowTreeHostManager::Shutdown(). + virtual void OnWindowTreeHostManagerShutdown() {} protected: virtual ~Observer() {} @@ -225,7 +228,7 @@ // The mapping from display ID to its window tree host. WindowTreeHostMap window_tree_hosts_; - base::ObserverList<Observer> observers_; + base::ObserverList<Observer, true> observers_; // Store the primary window tree host temporarily while replacing // display.
diff --git a/ash/shell.cc b/ash/shell.cc index 27697f67..b021e7b 100644 --- a/ash/shell.cc +++ b/ash/shell.cc
@@ -1077,6 +1077,8 @@ // is started. display_manager_->CreateMirrorWindowAsyncIfAny(); + FOR_EACH_OBSERVER(ShellObserver, observers_, OnShellInitialized()); + user_metrics_recorder_->OnShellInitialized(); }
diff --git a/ash/shell_observer.h b/ash/shell_observer.h index 3ea105b..da53428 100644 --- a/ash/shell_observer.h +++ b/ash/shell_observer.h
@@ -63,6 +63,9 @@ // animating but have been restored. virtual void OnMaximizeModeEnded() {} + // Called at the end of Shell::Init. + virtual void OnShellInitialized() {} + protected: virtual ~ShellObserver() {} };
diff --git a/breakpad/BUILD.gn b/breakpad/BUILD.gn index 233c59715..08af6c7 100644 --- a/breakpad/BUILD.gn +++ b/breakpad/BUILD.gn
@@ -725,6 +725,7 @@ if (is_ios) { static_library("client") { + set_sources_assignment_filter([]) sources = [ "src/client/ios/Breakpad.h", "src/client/ios/Breakpad.mm", @@ -751,6 +752,8 @@ "src/client/minidump_file_writer.h", "src/common/convert_UTF.c", "src/common/convert_UTF.h", + "src/common/mac/GTMLogger.h", + "src/common/mac/GTMLogger.m", "src/common/mac/HTTPMultipartUpload.m", "src/common/mac/file_id.cc", "src/common/mac/file_id.h", @@ -770,12 +773,20 @@ "src/common/string_conversion.h", "src/google_breakpad/common/minidump_format.h", ] + set_sources_assignment_filter(sources_assignment_filter) include_dirs = [ "src", "src/client/mac/Framework", "src/common/mac", ] + + public_configs = [ ":client_config" ] + + if (is_clang) { + # See https://bugs.chromium.org/p/google-breakpad/issues/detail?id=675. + cflags = [ "-Wno-deprecated-declarations" ] + } } # TODO(GYP) There is some XCode-only targets like ninja-breakpad. }
diff --git a/breakpad/breakpad.gyp b/breakpad/breakpad.gyp index 52bf0db..5592748a 100644 --- a/breakpad/breakpad.gyp +++ b/breakpad/breakpad.gyp
@@ -310,8 +310,7 @@ ['OS=="ios"', { 'xcode_settings' : { 'WARNING_CFLAGS': [ - # MinidumpGenerator uses an API deprecated in iOS 7. - # crbug.com/408562 + # See https://bugs.chromium.org/p/google-breakpad/issues/detail?id=675. '-Wno-deprecated-declarations', ], },
diff --git a/build/all.gyp b/build/all.gyp index ecbe935..176e855 100644 --- a/build/all.gyp +++ b/build/all.gyp
@@ -109,7 +109,6 @@ 'dependencies': [ '../third_party/re2/re2.gyp:re2', '../chrome/chrome.gyp:*', - '../chrome/tools/profile_reset/jtl_compiler.gyp:*', '../cc/blink/cc_blink_tests.gyp:*', '../cc/cc_tests.gyp:*', '../device/usb/usb.gyp:*',
diff --git a/build/gn_migration.gypi b/build/gn_migration.gypi index 279d4c47..7c8b1a1 100644 --- a/build/gn_migration.gypi +++ b/build/gn_migration.gypi
@@ -356,7 +356,6 @@ '../chrome/chrome.gyp:performance_browser_tests', '../chrome/chrome.gyp:sync_integration_tests', '../chrome/chrome.gyp:sync_performance_tests', - '../chrome/tools/profile_reset/jtl_compiler.gyp:jtl_compiler', '../extensions/extensions_tests.gyp:extensions_browsertests', '../extensions/extensions_tests.gyp:extensions_unittests', '../gin/gin.gyp:gin_shell',
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/InvalidationGcmUpstreamSender.java b/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/InvalidationGcmUpstreamSender.java index 2a1ff4f..1613dd07 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/InvalidationGcmUpstreamSender.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/InvalidationGcmUpstreamSender.java
@@ -42,7 +42,7 @@ } // Attempt to retrieve a token for the user. - OAuth2TokenService.getOAuth2AccessToken(this, null, account, + OAuth2TokenService.getOAuth2AccessToken(this, account, SyncConstants.CHROME_SYNC_OAUTH2_SCOPE, new AccountManagerHelper.GetAuthTokenCallback() { @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/AndroidProfileOAuth2TokenServiceHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/AndroidProfileOAuth2TokenServiceHelper.java deleted file mode 100644 index 5a479887..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/AndroidProfileOAuth2TokenServiceHelper.java +++ /dev/null
@@ -1,52 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.signin; - -import android.accounts.Account; -import android.app.Activity; -import android.content.Context; - -import org.chromium.sync.signin.AccountManagerHelper; - -import java.util.concurrent.TimeUnit; - -import javax.annotation.Nullable; - -/** - * Temporary wrapper class until all callers have moved to use {@link OAuth2TokenService}. - * TODO(nyquist) Remove this class. - */ -public final class AndroidProfileOAuth2TokenServiceHelper { - - private AndroidProfileOAuth2TokenServiceHelper() {} - - /** - * Use {@link OAuth2TokenService#getOAuth2AccessToken} instead. - */ - @Deprecated - public static void getOAuth2AccessToken(Context context, @Nullable Activity activity, - Account account, String scope, AccountManagerHelper.GetAuthTokenCallback callback) { - OAuth2TokenService.getOAuth2AccessToken(context, activity, account, scope, callback); - } - - /** - * Use {@link OAuth2TokenService#invalidateOAuth2AuthToken} instead. - */ - @Deprecated - public static void invalidateOAuth2AuthToken(Context context, String accessToken) { - OAuth2TokenService.invalidateOAuth2AuthToken(context, accessToken); - } - - /** - * Use {@link OAuth2TokenService#getOAuth2AccessTokenWithTimeout} instead. - */ - @Deprecated - public static String getOAuth2AccessTokenWithTimeout(Context context, - @Nullable Activity activity, Account account, String scope, - long timeout, TimeUnit unit) { - return OAuth2TokenService.getOAuth2AccessTokenWithTimeout( - context, activity, account, scope, timeout, unit); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/OAuth2TokenService.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/OAuth2TokenService.java index 5103cdc..5cdc845 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/OAuth2TokenService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/OAuth2TokenService.java
@@ -5,7 +5,6 @@ package org.chromium.chrome.browser.signin; import android.accounts.Account; -import android.app.Activity; import android.content.Context; import android.preference.PreferenceManager; import android.util.Log; @@ -25,8 +24,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; -import javax.annotation.Nullable; - /** * Java instance for the native OAuth2TokenService. * <p/> @@ -165,13 +162,11 @@ /** * Call this method to retrieve an OAuth2 access token for the given account and scope. * - * @param activity the current activity. May be null. * @param account the account to get the access token for. * @param scope The scope to get an auth token for (without Android-style 'oauth2:' prefix). * @param callback called on successful and unsuccessful fetching of auth token. */ - public static void getOAuth2AccessToken( - Context context, @Nullable Activity activity, Account account, String scope, + public static void getOAuth2AccessToken(Context context, Account account, String scope, AccountManagerHelper.GetAuthTokenCallback callback) { String oauth2Scope = OAUTH2_SCOPE_PREFIX + scope; AccountManagerHelper.get(context).getAuthToken(account, oauth2Scope, callback); @@ -183,7 +178,6 @@ * * Given that this is a blocking method call, this should never be called from the UI thread. * - * @param activity the current activity. May be null. * @param account the account to get the access token for. * @param scope The scope to get an auth token for (without Android-style 'oauth2:' prefix). * @param timeout the timeout. @@ -191,13 +185,12 @@ */ @VisibleForTesting public static String getOAuth2AccessTokenWithTimeout( - Context context, @Nullable Activity activity, Account account, String scope, - long timeout, TimeUnit unit) { + Context context, Account account, String scope, long timeout, TimeUnit unit) { assert !ThreadUtils.runningOnUiThread(); final AtomicReference<String> result = new AtomicReference<String>(); final Semaphore semaphore = new Semaphore(0); getOAuth2AccessToken( - context, activity, account, scope, new AccountManagerHelper.GetAuthTokenCallback() { + context, account, scope, new AccountManagerHelper.GetAuthTokenCallback() { @Override public void tokenAvailable(String token) { result.set(token);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/OAuth2TokenServiceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/OAuth2TokenServiceTest.java index c08f7cf..432c62a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/OAuth2TokenServiceTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/OAuth2TokenServiceTest.java
@@ -115,9 +115,8 @@ .authToken(oauth2Scope, expectedToken).build(); mAccountManager.addAccountHolderExplicitly(accountHolder); - String accessToken = - OAuth2TokenService.getOAuth2AccessTokenWithTimeout( - mContext, null, account, scope, 5, TimeUnit.SECONDS); + String accessToken = OAuth2TokenService.getOAuth2AccessTokenWithTimeout( + mContext, account, scope, 5, TimeUnit.SECONDS); assertEquals(expectedToken, accessToken); } }
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index f2916db..63ff3cae 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -8259,6 +8259,7 @@ Unusual behavior detected </message> </if> + <!-- Upgrade bubble messages --> <message name="IDS_REENABLE_UPDATES" desc="Text for the button the user clicks to re-enable automatic updates."> Enable autoupdate @@ -10547,9 +10548,6 @@ </message> <!-- Reset Profile Settings strings --> - <message name="IDS_RESET_PROFILE_SETTINGS_BANNER_TEXT" desc="The text to show in a banner at the top of the chrome://settings page. The banner is displayed when Chrome detects that the settings might have been changed without the user's knowledge."> - Some of your settings may have been changed without your knowledge. - </message> <message name="IDS_RESET_PROFILE_SETTINGS_SECTION_TITLE" desc="The title of the section in chrome://settings that allows resetting some settings in a profile"> Reset settings </message>
diff --git a/chrome/browser/android/popular_sites.cc b/chrome/browser/android/popular_sites.cc index c18c146..adb98a4 100644 --- a/chrome/browser/android/popular_sites.cc +++ b/chrome/browser/android/popular_sites.cc
@@ -10,9 +10,11 @@ #include "base/files/file_util.h" #include "base/json/json_reader.h" #include "base/path_service.h" +#include "base/prefs/pref_service.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/task_runner_util.h" +#include "base/time/time.h" #include "base/values.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/net/file_downloader.h" @@ -21,6 +23,7 @@ #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" #include "components/google/core/browser/google_util.h" +#include "components/pref_registry/pref_registry_syncable.h" #include "components/search_engines/search_engine_type.h" #include "components/search_engines/template_url_prepopulate_data.h" #include "components/search_engines/template_url_service.h" @@ -38,6 +41,8 @@ const char kPopularSitesLocalFilename[] = "suggested_sites.json"; const int kPopularSitesRedownloadIntervalHours = 24; +const char kPopularSitesLastDownloadPref[] = "popular_sites_last_download"; + // Extract the country from the default search engine if the default search // engine is Google. std::string GetDefaultSearchEngineCountryCode(Profile* profile) { @@ -203,62 +208,66 @@ PopularSites::~PopularSites() {} +// static +void PopularSites::RegisterProfilePrefs( + user_prefs::PrefRegistrySyncable* user_prefs) { + user_prefs->RegisterInt64Pref(kPopularSitesLastDownloadPref, 0); +} + PopularSites::PopularSites(Profile* profile, const GURL& url, bool force_download, const FinishedCallback& callback) : callback_(callback), - redownload_interval_( - base::TimeDelta::FromHours(kPopularSitesRedownloadIntervalHours)), popular_sites_local_path_(GetPopularSitesPath()), + profile_(profile), weak_ptr_factory_(this) { // Re-download the file once on every Chrome startup, but use the cached // local file afterwards. static bool first_time = true; - FetchPopularSites(url, profile, first_time || force_download); + + const base::Time last_download_time = base::Time::FromInternalValue( + profile_->GetPrefs()->GetInt64(kPopularSitesLastDownloadPref)); + const base::TimeDelta time_since_last_download = + base::Time::Now() - last_download_time; + const base::TimeDelta redownload_interval = + base::TimeDelta::FromHours(kPopularSitesRedownloadIntervalHours); + const bool download_time_is_future = base::Time::Now() < last_download_time; + + const bool should_redownload_if_exists = + first_time || force_download || download_time_is_future || + (time_since_last_download > redownload_interval); + + FetchPopularSites(url, should_redownload_if_exists, false /* is_fallback */); first_time = false; } void PopularSites::FetchPopularSites(const GURL& url, - Profile* profile, - bool force_download) { - base::TimeDelta age = base::TimeTicks::Now() - last_download_time_; - bool redownload = force_download || (age > redownload_interval_); + bool force_download, + bool is_fallback) { downloader_.reset( - new FileDownloader(url, popular_sites_local_path_, redownload, - profile->GetRequestContext(), + new FileDownloader(url, popular_sites_local_path_, force_download, + profile_->GetRequestContext(), base::Bind(&PopularSites::OnDownloadDone, - base::Unretained(this), profile))); + base::Unretained(this), is_fallback))); } -void PopularSites::FetchFallbackSites(Profile* profile) { - downloader_.reset(new FileDownloader( - GetPopularSitesFallbackURL(profile), popular_sites_local_path_, - true /* force_download */, profile->GetRequestContext(), - base::Bind(&PopularSites::OnDownloadFallbackDone, - base::Unretained(this)))); -} - -void PopularSites::OnDownloadDone(Profile* profile, bool success) { +void PopularSites::OnDownloadDone(bool is_fallback, bool success) { + downloader_.reset(); if (success) { - last_download_time_ = base::TimeTicks::Now(); + profile_->GetPrefs()->SetInt64(kPopularSitesLastDownloadPref, + base::Time::Now().ToInternalValue()); ParseSiteList(popular_sites_local_path_); - downloader_.reset(); - } else { + } else if (!is_fallback) { DLOG(WARNING) << "Download country site list failed"; - FetchFallbackSites(profile); - } -} - -void PopularSites::OnDownloadFallbackDone(bool success) { - if (success) { - last_download_time_ = base::TimeTicks::Now(); - ParseSiteList(popular_sites_local_path_); + // It is fine to force the download as Fallback is only triggered after a + // failed download. + FetchPopularSites(GetPopularSitesFallbackURL(profile_), + true /* force_download */, true /* is_fallback */); } else { DLOG(WARNING) << "Download fallback site list failed"; callback_.Run(false); } - downloader_.reset(); } void PopularSites::ParseSiteList(const base::FilePath& path) {
diff --git a/chrome/browser/android/popular_sites.h b/chrome/browser/android/popular_sites.h index af57a79..606a7c19 100644 --- a/chrome/browser/android/popular_sites.h +++ b/chrome/browser/android/popular_sites.h
@@ -13,13 +13,16 @@ #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/strings/string16.h" -#include "base/time/time.h" #include "url/gurl.h" namespace net { class URLRequestContextGetter; } +namespace user_prefs { +class PrefRegistrySyncable; +} + class FileDownloader; class Profile; @@ -67,6 +70,10 @@ const std::vector<Site>& sites() const { return sites_; } + // Register preferences used by this class. + static void RegisterProfilePrefs( + user_prefs::PrefRegistrySyncable* user_prefs); + private: PopularSites(Profile* profile, const GURL& url, @@ -76,14 +83,12 @@ // Fetch the popular sites at the given URL. |force_download| should be true // if any previously downloaded site list should be overwritten. void FetchPopularSites(const GURL& url, - Profile* profile, - bool force_download); - void OnDownloadDone(Profile* profile, bool success); + bool force_download, + bool is_fallback); - // Fetch the default popular site list. This method will always overwrite - // a previously downloaded site list. - void FetchFallbackSites(Profile* profile); - void OnDownloadFallbackDone(bool success); + // If the download was not successful and it was not a fallback, attempt to + // download the fallback suggestions. + void OnDownloadDone(bool success, bool is_fallback); void ParseSiteList(const base::FilePath& path); void OnJsonParsed(scoped_ptr<std::vector<Site>> sites); @@ -91,11 +96,11 @@ FinishedCallback callback_; scoped_ptr<FileDownloader> downloader_; std::vector<Site> sites_; - base::TimeTicks last_download_time_; - base::TimeDelta redownload_interval_; base::FilePath popular_sites_local_path_; + Profile* profile_; + base::WeakPtrFactory<PopularSites> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(PopularSites);
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index 7e6595ac..04e83a76 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -403,10 +403,6 @@ </if> <if expr="_google_chrome"> <include name="IDR_PREF_HASH_SEED_BIN" file="resources\settings_internal\pref_hash_seed.bin" type="BINDATA" /> - <include name="IDR_AUTOMATIC_PROFILE_RESET_RULES" file="internal\resources\profile_reset\automatic_profile_reset_rules.dat" type="BINDATA" /> - <include name="IDR_AUTOMATIC_PROFILE_RESET_RULES_DRY" file="internal\resources\profile_reset\automatic_profile_reset_rules_dry.dat" type="BINDATA" /> - <include name="IDR_AUTOMATIC_PROFILE_RESET_HASH_SEED" file="internal\resources\profile_reset\automatic_profile_reset_rules.seed" type="BINDATA" /> - <include name="IDR_AUTOMATIC_PROFILE_RESET_HASH_SEED_DRY" file="internal\resources\profile_reset\automatic_profile_reset_rules_dry.seed" type="BINDATA" /> <include name="IDR_ADDITIONAL_MODULE_IDS" file="${additional_modules_list_file}" use_base_dir="false" type="BINDATA" /> </if> <if expr="chromeos">
diff --git a/chrome/browser/browsing_data/browsing_data_remover_unittest.cc b/chrome/browser/browsing_data/browsing_data_remover_unittest.cc index 16feeab..d62aa5f 100644 --- a/chrome/browser/browsing_data/browsing_data_remover_unittest.cc +++ b/chrome/browser/browsing_data/browsing_data_remover_unittest.cc
@@ -2124,7 +2124,7 @@ TEST_F(BrowsingDataRemoverTest, RemovePasswordStatistics) { PasswordStoreFactory::GetInstance()->SetTestingFactoryAndUse( GetProfile(), - password_manager::BuildPasswordStoreService< + password_manager::BuildPasswordStore< content::BrowserContext, password_manager::MockPasswordStore>); password_manager::MockPasswordStore* store = static_cast<password_manager::MockPasswordStore*>(
diff --git a/chrome/browser/chromeos/login/saml/saml_browsertest.cc b/chrome/browser/chromeos/login/saml/saml_browsertest.cc index 25f1e7d..fb3ca9ce 100644 --- a/chrome/browser/chromeos/login/saml/saml_browsertest.cc +++ b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
@@ -31,7 +31,9 @@ #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h" #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h" #include "chrome/browser/chromeos/login/ui/webui_login_display.h" +#include "chrome/browser/chromeos/login/users/chrome_user_manager.h" #include "chrome/browser/chromeos/login/wizard_controller.h" +#include "chrome/browser/chromeos/policy/affiliation_test_helper.h" #include "chrome/browser/chromeos/policy/device_policy_builder.h" #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h" #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h" @@ -133,6 +135,8 @@ const char kTestRefreshToken[] = "fake-refresh-token"; const char kPolicy[] = "{\"managed_users\": [\"*\"]}"; +const char kAffiliationID[] = "some-affiliation-id"; + // FakeSamlIdp serves IdP auth form and the form submission. The form is // served with the template's RelayState placeholder expanded to the real // RelayState parameter from request. The form submission redirects back to @@ -951,12 +955,10 @@ SamlTest::SetUpInProcessBrowserTestFixture(); // Initialize device policy. - test_helper_.InstallOwnerKey(); - test_helper_.MarkAsEnterpriseOwned(); - device_policy_->SetDefaultSigningKey(); - device_policy_->Build(); - fake_session_manager_client_->set_device_policy(device_policy_->GetBlob()); - fake_session_manager_client_->OnPropertyChangeComplete(true); + std::set<std::string> device_affiliation_ids; + device_affiliation_ids.insert(kAffiliationID); + policy::affiliation_test_helper::SetDeviceAffiliationID( + &test_helper_, fake_session_manager_client_, device_affiliation_ids); // Initialize user policy. EXPECT_CALL(provider_, IsInitializationComplete(_)) @@ -978,6 +980,18 @@ AccountId::FromUserEmail(kDifferentDomainSAMLUserEmail), user_manager::User::OAUTH2_TOKEN_STATUS_VALID); + // Give affiliated users appropriate affiliation IDs. + std::set<std::string> user_affiliation_ids; + user_affiliation_ids.insert(kAffiliationID); + chromeos::ChromeUserManager::Get()->SetUserAffiliation(kFirstSAMLUserEmail, + user_affiliation_ids); + chromeos::ChromeUserManager::Get()->SetUserAffiliation(kSecondSAMLUserEmail, + user_affiliation_ids); + chromeos::ChromeUserManager::Get()->SetUserAffiliation(kHTTPSAMLUserEmail, + user_affiliation_ids); + chromeos::ChromeUserManager::Get()->SetUserAffiliation(kNonSAMLUserEmail, + user_affiliation_ids); + // Set up fake networks. DBusThreadManager::Get() ->GetShillManagerClient()
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc index 7c2aa36..f06ccea 100644 --- a/chrome/browser/chromeos/login/session/user_session_manager.cc +++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -1017,14 +1017,14 @@ // authentication cookies set by a SAML IdP on subsequent logins after the // first. bool transfer_saml_auth_cookies_on_subsequent_login = false; - if (has_auth_cookies_ && - g_browser_process->platform_part() - ->browser_policy_connector_chromeos() - ->GetUserAffiliation(account_id.GetUserEmail()) == - policy::USER_AFFILIATION_MANAGED) { - CrosSettings::Get()->GetBoolean( - kAccountsPrefTransferSAMLCookies, - &transfer_saml_auth_cookies_on_subsequent_login); + if (has_auth_cookies_) { + const user_manager::User* user = + user_manager::UserManager::Get()->FindUser(account_id); + if (user->is_affiliated()) { + CrosSettings::Get()->GetBoolean( + kAccountsPrefTransferSAMLCookies, + &transfer_saml_auth_cookies_on_subsequent_login); + } } // Transfers authentication-related data from the profile that was used for
diff --git a/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc b/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc index 0bdb44b..2e81480c 100644 --- a/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc +++ b/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc
@@ -25,7 +25,6 @@ #include "chrome/browser/chromeos/certificate_provider/certificate_provider.h" #include "chrome/browser/chromeos/net/client_cert_filter_chromeos.h" #include "chrome/browser/chromeos/net/client_cert_store_chromeos.h" -#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.h" #include "chrome/browser/net/nss_context.h" @@ -778,12 +777,9 @@ chromeos::ProfileHelper::Get()->GetUserByProfile( Profile::FromBrowserContext(browser_context)); - // Use the device-wide system key slot only if the user is of the same - // domain as the device is registered to. - policy::BrowserPolicyConnectorChromeOS* connector = - g_browser_process->platform_part()->browser_policy_connector_chromeos(); - bool use_system_key_slot = connector->GetUserAffiliation(user->email()) == - policy::USER_AFFILIATION_MANAGED; + // Use the device-wide system key slot only if the user is affiliated on the + // device. + bool use_system_key_slot = user->is_affiliated(); scoped_ptr<SelectCertificatesState> state(new SelectCertificatesState( user->username_hash(), use_system_key_slot, cert_request_info, callback));
diff --git a/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl.cc b/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl.cc index 1c81969..672a6de 100644 --- a/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl.cc +++ b/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl.cc
@@ -156,11 +156,9 @@ } const user_manager::User* user = chromeos::ProfileHelper::Get()->GetUserByProfile(profile); - if (!user || - g_browser_process->platform_part()->browser_policy_connector_chromeos()-> - GetUserAffiliation(user->email()) != USER_AFFILIATION_MANAGED) { - // If the Profile belongs to a user who is not affiliated with the device's - // enrollment domain, ignore it. + if (!user || !user->is_affiliated()) { + // If the Profile belongs to a user who is not affiliated on the device, + // ignore it. return; }
diff --git a/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl_unittest.cc b/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl_unittest.cc index 9009677..e0f9010 100644 --- a/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl_unittest.cc +++ b/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl_unittest.cc
@@ -87,8 +87,10 @@ void SetUp() override; void TearDown() override; - // Ownership is not passed. The Profile is owned by the global ProfileManager. - Profile* LogInAndReturnProfile(const std::string& user_id); + // Both functions don't pass ownership of the profile. The Profile is owned + // by the global ProfileManager. + Profile* LogInAndReturnAffiliatedProfile(const std::string& user_id); + Profile* LogInAndReturnNonAffiliatedProfile(const std::string& user_id); // Logs in as an affiliated user and indicates that the per-profile // invalidation service for this user connected. Verifies that this @@ -116,6 +118,9 @@ bool create); protected: + // Ownership is not passed. The Profile is owned by the global ProfileManager. + Profile* LogInAndReturnProfile(const std::string& user_id, + bool is_affiliated); scoped_ptr<AffiliatedInvalidationServiceProviderImpl> provider_; scoped_ptr<FakeConsumer> consumer_; invalidation::TiclInvalidationService* device_invalidation_service_; @@ -220,9 +225,22 @@ chromeos::SystemSaltGetter::Shutdown(); } -Profile* AffiliatedInvalidationServiceProviderImplTest::LogInAndReturnProfile( +Profile* +AffiliatedInvalidationServiceProviderImplTest::LogInAndReturnAffiliatedProfile( const std::string& user_id) { - fake_user_manager_->AddUser(AccountId::FromUserEmail(user_id)); + return LogInAndReturnProfile(user_id, true); +} + +Profile* AffiliatedInvalidationServiceProviderImplTest:: + LogInAndReturnNonAffiliatedProfile(const std::string& user_id) { + return LogInAndReturnProfile(user_id, false); +} + +Profile* AffiliatedInvalidationServiceProviderImplTest::LogInAndReturnProfile( + const std::string& user_id, + bool is_affiliated) { + fake_user_manager_->AddUserWithAffiliation(AccountId::FromUserEmail(user_id), + is_affiliated); Profile* profile = profile_manager_.CreateTestingProfile(user_id); content::NotificationService::current()->Notify( chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, @@ -234,7 +252,7 @@ void AffiliatedInvalidationServiceProviderImplTest:: LogInAsAffiliatedUserAndConnectInvalidationService() { // Log in as an affiliated user. - Profile* profile = LogInAndReturnProfile(kAffiliatedUserID1); + Profile* profile = LogInAndReturnAffiliatedProfile(kAffiliatedUserID1); EXPECT_TRUE(profile); // Verify that a per-profile invalidation service has been created. @@ -260,7 +278,7 @@ void AffiliatedInvalidationServiceProviderImplTest:: LogInAsUnaffiliatedUserAndConnectInvalidationService() { // Log in as an unaffiliated user. - Profile* profile = LogInAndReturnProfile(kUnaffiliatedUserID); + Profile* profile = LogInAndReturnNonAffiliatedProfile(kUnaffiliatedUserID); EXPECT_TRUE(profile); // Verify that a per-profile invalidation service has been created. @@ -335,7 +353,7 @@ EXPECT_FALSE(provider_->GetDeviceInvalidationServiceForTest()); // Log in as an affiliated user. - EXPECT_TRUE(LogInAndReturnProfile(kAffiliatedUserID1)); + EXPECT_TRUE(LogInAndReturnAffiliatedProfile(kAffiliatedUserID1)); // Verify that no device-global invalidation service has been created. EXPECT_FALSE(provider_->GetDeviceInvalidationServiceForTest()); @@ -506,7 +524,7 @@ LogInAsAffiliatedUserAndConnectInvalidationService(); // Log in as a second affiliated user. - Profile* second_profile = LogInAndReturnProfile(kAffiliatedUserID2); + Profile* second_profile = LogInAndReturnAffiliatedProfile(kAffiliatedUserID2); EXPECT_TRUE(second_profile); // Verify that the device-global invalidation service still does not exist. @@ -605,7 +623,7 @@ EXPECT_FALSE(provider_->GetDeviceInvalidationServiceForTest()); // Log in as a second affiliated user. - Profile* second_profile = LogInAndReturnProfile(kAffiliatedUserID2); + Profile* second_profile = LogInAndReturnAffiliatedProfile(kAffiliatedUserID2); EXPECT_TRUE(second_profile); // Verify that the device-global invalidation service still does not exist.
diff --git a/chrome/browser/chromeos/policy/affiliation_test_helper.cc b/chrome/browser/chromeos/policy/affiliation_test_helper.cc new file mode 100644 index 0000000..bfedc57d --- /dev/null +++ b/chrome/browser/chromeos/policy/affiliation_test_helper.cc
@@ -0,0 +1,138 @@ +// Copyright 2015 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/chromeos/policy/affiliation_test_helper.h" + +#include <string> +#include <vector> + +#include "base/command_line.h" +#include "base/files/file_path.h" +#include "base/path_service.h" +#include "base/prefs/pref_service.h" +#include "base/prefs/scoped_user_pref_update.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/chrome_notification_types.h" +#include "chrome/browser/chromeos/login/existing_user_controller.h" +#include "chrome/browser/chromeos/login/session/user_session_manager_test_api.h" +#include "chrome/browser/chromeos/login/startup_utils.h" +#include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h" +#include "chrome/browser/chromeos/policy/device_policy_builder.h" +#include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h" +#include "chromeos/chromeos_paths.h" +#include "chromeos/chromeos_switches.h" +#include "chromeos/dbus/cryptohome_client.h" +#include "chromeos/dbus/fake_session_manager_client.h" +#include "chromeos/dbus/session_manager_client.h" +#include "chromeos/login/auth/key.h" +#include "chromeos/login/auth/user_context.h" +#include "components/policy/core/common/cloud/cloud_policy_core.h" +#include "components/policy/core/common/cloud/cloud_policy_store.h" +#include "components/policy/core/common/cloud/policy_builder.h" +#include "content/public/browser/notification_service.h" +#include "content/public/test/test_utils.h" +#include "crypto/rsa_private_key.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace policy { + +namespace affiliation_test_helper { + +const char kFakeRefreshToken[] = "fake-refresh-token"; +const char kEnterpriseUser[] = "testuser@example.com"; + +void SetUserKeys(policy::UserPolicyBuilder* user_policy) { + std::string username = user_policy->policy_data().username(); + base::FilePath user_keys_dir; + ASSERT_TRUE(PathService::Get(chromeos::DIR_USER_POLICY_KEYS, &user_keys_dir)); + const std::string sanitized_username = + chromeos::CryptohomeClient::GetStubSanitizedUsername(username); + const base::FilePath user_key_file = + user_keys_dir.AppendASCII(sanitized_username).AppendASCII("policy.pub"); + std::vector<uint8> user_key_bits; + ASSERT_TRUE(user_policy->GetSigningKey()->ExportPublicKey(&user_key_bits)); + ASSERT_TRUE(base::CreateDirectory(user_key_file.DirName())); + ASSERT_EQ(base::WriteFile(user_key_file, + reinterpret_cast<const char*>(user_key_bits.data()), + user_key_bits.size()), + static_cast<int>(user_key_bits.size())); +} + +void SetDeviceAffiliationID( + policy::DevicePolicyCrosTestHelper* test_helper, + chromeos::FakeSessionManagerClient* fake_session_manager_client, + const std::set<std::string>& device_affiliation_ids) { + test_helper->InstallOwnerKey(); + test_helper->MarkAsEnterpriseOwned(); + + policy::DevicePolicyBuilder* device_policy = test_helper->device_policy(); + for (const auto& device_affiliation_id : device_affiliation_ids) { + device_policy->policy_data().add_device_affiliation_ids( + device_affiliation_id); + } + device_policy->SetDefaultSigningKey(); + device_policy->Build(); + + fake_session_manager_client->set_device_policy(device_policy->GetBlob()); + fake_session_manager_client->OnPropertyChangeComplete(true); +} + +void SetUserAffiliationIDs( + policy::UserPolicyBuilder* user_policy, + chromeos::FakeSessionManagerClient* fake_session_manager_client, + const std::string& user_email, + const std::set<std::string>& user_affiliation_ids) { + user_policy->policy_data().set_username(user_email); + SetUserKeys(user_policy); + for (const auto& user_affiliation_id : user_affiliation_ids) { + user_policy->policy_data().add_user_affiliation_ids(user_affiliation_id); + } + user_policy->Build(); + fake_session_manager_client->set_user_policy(user_email, + user_policy->GetBlob()); +} + +void PreLoginUser(const std::string& user_id) { + ListPrefUpdate users_pref(g_browser_process->local_state(), "LoggedInUsers"); + users_pref->AppendIfNotPresent(new base::StringValue(user_id)); + chromeos::StartupUtils::MarkOobeCompleted(); +} + +void LoginUser(const std::string& user_id) { + chromeos::test::UserSessionManagerTestApi session_manager_test_api( + chromeos::UserSessionManager::GetInstance()); + session_manager_test_api.SetShouldObtainTokenHandleInTests(false); + + chromeos::UserContext user_context(AccountId::FromUserEmail(user_id)); + user_context.SetGaiaID("gaia-id-" + user_id); + user_context.SetKey(chromeos::Key("password")); + if (user_id == kEnterpriseUser) { + user_context.SetRefreshToken(kFakeRefreshToken); + } + chromeos::ExistingUserController* controller = + chromeos::ExistingUserController::current_controller(); + CHECK(controller); + content::WindowedNotificationObserver observer( + chrome::NOTIFICATION_SESSION_STARTED, + content::NotificationService::AllSources()); + controller->Login(user_context, chromeos::SigninSpecifics()); + observer.Wait(); + + const user_manager::UserList& logged_users = + user_manager::UserManager::Get()->GetLoggedInUsers(); + for (user_manager::UserList::const_iterator it = logged_users.begin(); + it != logged_users.end(); ++it) { + if ((*it)->email() == user_context.GetAccountId().GetUserEmail()) + return; + } + ADD_FAILURE() << user_id << " was not added via PreLoginUser()"; +} + +void AppendCommandLineSwitchesForLoginManager(base::CommandLine* command_line) { + command_line->AppendSwitch(chromeos::switches::kLoginManager); + command_line->AppendSwitch(chromeos::switches::kForceLoginManagerInTests); +} + +} // namespace affiliation_test_helper + +} // namespace policy
diff --git a/chrome/browser/chromeos/policy/affiliation_test_helper.h b/chrome/browser/chromeos/policy/affiliation_test_helper.h new file mode 100644 index 0000000..ee4624a2 --- /dev/null +++ b/chrome/browser/chromeos/policy/affiliation_test_helper.h
@@ -0,0 +1,108 @@ +// Copyright 2015 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_CHROMEOS_POLICY_AFFILIATION_TEST_HELPER_H_ +#define CHROME_BROWSER_CHROMEOS_POLICY_AFFILIATION_TEST_HELPER_H_ + +#include <set> +#include <string> +#include "components/policy/core/common/cloud/policy_builder.h" + +namespace base { +class CommandLine; +} // namespace base + +namespace chromeos { +class FakeSessionManagerClient; +} // namespace chromeos + +namespace policy { + +class DevicePolicyCrosTestHelper; + +namespace affiliation_test_helper { + +// Creates policy key file for the user specified in |user_policy|. +// TODO(peletskyi): Replace pointer with const reference and replace this +// boilerplate in other places (http://crbug.com/549111). +void SetUserKeys(policy::UserPolicyBuilder* user_policy); + +// Sets device affiliation ID to |fake_session_manager| from +// |device_affiliation_ids| and modifies |test_helper| so that it contains +// correct values of device affiliation IDs for future use. To add some device +// policies and have device affiliation ID valid please use |test_helper| +// modified by this function. Example: +// +// FakeSessionManagerClient* fake_session_manager_client = +// new chromeos::FakeSessionManagerClient; +// DBusThreadManager::GetSetterForTesting()->SetSessionManagerClient( +// scoped_ptr<SessionManagerClient>(fake_session_manager_client)); +// +// policy::DevicePolicyCrosTestHelper test_helper; +// std::set<std::string> device_affiliation_ids; +// device_affiliation_ids.insert(some-affiliation-id); +// +// affiliation_test_helper::SetDeviceAffiliationID(&test_helper, +// fake_session_manager_client, +// device_affiliation_ids); +// +// If it is used together with SetUserAffiliationIDs() (which is the most common +// case) |fake_session_manager_client| must point to the same object as in +// SetUserAffiliationIDs() call. +// In browser tests one can call this function from +// SetUpInProcessBrowserTestFixture(). +void SetDeviceAffiliationID( + policy::DevicePolicyCrosTestHelper* test_helper, + chromeos::FakeSessionManagerClient* fake_session_manager_client, + const std::set<std::string>& device_affiliation_ids); + +// Sets user affiliation ID for |user_name| to |fake_session_manager| from +// |user_affiliation_ids| and modifies |user_policy| so that it contains +// correct values of user affiliation IDs for future use. To add user policies +// and have user affiliation IDs valid please use |user_policy| modified by this +// function. Example: +// +// FakeSessionManagerClient* fake_session_manager_client = +// new chromeos::FakeSessionManagerClient; +// DBusThreadManager::GetSetterForTesting()->SetSessionManagerClient( +// scoped_ptr<SessionManagerClient>(fake_session_manager_client)); +// +// policy::UserPolicyBuilder user_policy; +// std::set<std::string> user_affiliation_ids; +// user_affiliation_ids.insert("some-affiliation-id"); +// +// affiliation_test_helper::SetUserAffiliationIDs( +// &user_policy, fake_session_manager_client, "user@example.com", +// user_affiliation_ids); +// +// If it is used together SetDeviceAffiliationID() (which is the most common +// case) |fake_session_manager_client| must point to the same object as in +// SetDeviceAffiliationID() call. +// In browser tests one can call this function from +// SetUpInProcessBrowserTestFixture(). +void SetUserAffiliationIDs( + policy::UserPolicyBuilder* user_policy, + chromeos::FakeSessionManagerClient* fake_session_manager_client, + const std::string& user_email, + const std::set<std::string>& user_affiliation_ids); + +// Registers the user with the given |user_id| on the device and marks OOBE +// as completed. This method should be called in PRE_* test. +void PreLoginUser(const std::string& user_id); + +// Log in user with |user_id|. User should be registered using PreLoginUser(). +void LoginUser(const std::string& user_id); + +// Set necessary for login command line switches. Execute it in +// SetUpCommandLine(). +void AppendCommandLineSwitchesForLoginManager(base::CommandLine* command_line); + +extern const char kFakeRefreshToken[]; +extern const char kEnterpriseUser[]; + +} // namespace affiliation_test_helper + +} // namespace policy + +#endif // CHROME_BROWSER_CHROMEOS_POLICY_AFFILIATION_TEST_HELPER_H_
diff --git a/chrome/browser/chromeos/policy/blocking_login_browsertest.cc b/chrome/browser/chromeos/policy/blocking_login_browsertest.cc index f3ce1e1..47f0a65 100644 --- a/chrome/browser/chromeos/policy/blocking_login_browsertest.cc +++ b/chrome/browser/chromeos/policy/blocking_login_browsertest.cc
@@ -243,8 +243,6 @@ EXPECT_TRUE(browser_policy_connector()->IsEnterpriseManaged()); EXPECT_EQ(kDomain, browser_policy_connector()->GetEnterpriseDomain()); EXPECT_FALSE(profile_added_); - EXPECT_EQ(policy::USER_AFFILIATION_MANAGED, - browser_policy_connector()->GetUserAffiliation(kUsername)); RunUntilIdle(); EXPECT_FALSE( user_manager->IsKnownUser(AccountId::FromUserEmail(kUsername)));
diff --git a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc index 7005f7f2..8ed5b15 100644 --- a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc +++ b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc
@@ -284,25 +284,6 @@ return EnrollmentConfig(); } -UserAffiliation BrowserPolicyConnectorChromeOS::GetUserAffiliation( - const std::string& user_name) { - // An empty username means incognito user in case of ChromiumOS and - // no logged-in user in case of Chromium (SigninService). Many tests use - // nonsense email addresses (e.g. 'test') so treat those as non-enterprise - // users. - if (user_name.empty() || user_name.find('@') == std::string::npos) - return USER_AFFILIATION_NONE; - - if (install_attributes_ && - (gaia::ExtractDomainName(gaia::CanonicalizeEmail(user_name)) == - install_attributes_->GetDomain() || - policy::IsDeviceLocalAccountUser(user_name, NULL))) { - return USER_AFFILIATION_MANAGED; - } - - return USER_AFFILIATION_NONE; -} - void BrowserPolicyConnectorChromeOS::SetUserPolicyDelegate( ConfigurationPolicyProvider* user_policy_provider) { global_user_cloud_policy_provider_->SetDelegate(user_policy_provider);
diff --git a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h index 6242695..41164c2 100644 --- a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h +++ b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h
@@ -84,10 +84,6 @@ // for details. EnrollmentConfig GetPrescribedEnrollmentConfig() const; - // Works out the user affiliation by checking the given |user_name| against - // the installation attributes. - UserAffiliation GetUserAffiliation(const std::string& user_name); - DeviceCloudPolicyManagerChromeOS* GetDeviceCloudPolicyManager() { return device_cloud_policy_manager_; }
diff --git a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc index f7f4019..7358ab0 100644 --- a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc +++ b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
@@ -121,10 +121,12 @@ #include "extensions/browser/app_window/app_window.h" #include "extensions/browser/app_window/app_window_registry.h" #include "extensions/browser/app_window/native_app_window.h" +#include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" #include "extensions/browser/install/crx_install_error.h" #include "extensions/browser/management_policy.h" #include "extensions/browser/notification_types.h" +#include "extensions/browser/test_extension_registry_observer.h" #include "extensions/common/constants.h" #include "extensions/common/extension.h" #include "net/base/url_util.h" @@ -373,13 +375,6 @@ } } -bool DoesInstallSuccessReferToId(const std::string& id, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - return content::Details<const extensions::InstalledExtensionInfo>(details)-> - extension->id() == id; -} - bool DoesInstallFailureReferToId(const std::string& id, const content::NotificationSource& source, const content::NotificationDetails& details) { @@ -811,6 +806,71 @@ return user_manager::UserManager::Get()->IsKnownUser(account_id); } +// Helper that listen extension installation when new profile is created. +class ExtensionInstallObserver : public content::NotificationObserver, + public extensions::ExtensionRegistryObserver { + public: + explicit ExtensionInstallObserver(const std::string& extension_id) + : registry_(nullptr), + waiting_extension_id_(extension_id), + observed_(false) { + registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED, + content::NotificationService::AllSources()); + } + + ~ExtensionInstallObserver() override { + if (registry_ != nullptr) + registry_->RemoveObserver(this); + } + + // Wait until an extension with |extension_id| is installed. + void Wait() { + if (!observed_) + run_loop_.Run(); + } + + private: + // extensions::ExtensionRegistryObserver: + void OnExtensionWillBeInstalled(content::BrowserContext* browser_context, + const extensions::Extension* extension, + bool is_update, + bool from_ephemeral, + const std::string& old_name) override { + if (waiting_extension_id_ == extension->id()) { + observed_ = true; + run_loop_.Quit(); + } + } + + // content::NotificationObserver: + void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) override { + DCHECK_EQ(chrome::NOTIFICATION_PROFILE_CREATED, type); + + Profile* profile = content::Source<Profile>(source).ptr(); + registry_ = extensions::ExtensionRegistry::Get(profile); + + // Check if extension is already installed with newly created profile. + if (registry_->GetInstalledExtension(waiting_extension_id_)) { + observed_ = true; + run_loop_.Quit(); + return; + } + + // Start listening for extension installation. + registry_->AddObserver(this); + } + + extensions::ExtensionRegistry* registry_; + base::RunLoop run_loop_; + content::NotificationRegistrar registrar_; + std::string waiting_extension_id_; + bool observed_; + + DISALLOW_COPY_AND_ASSIGN(ExtensionInstallObserver); +}; + IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, LoginScreen) { AddPublicSessionToDevicePolicy(kAccountId1); AddPublicSessionToDevicePolicy(kAccountId2); @@ -1046,19 +1106,16 @@ WaitForPolicy(); // Start listening for app/extension installation results. - content::WindowedNotificationObserver hosted_app_observer( - extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED, - base::Bind(DoesInstallSuccessReferToId, kHostedAppID)); + ExtensionInstallObserver install_observer(kHostedAppID); content::WindowedNotificationObserver extension_observer( extensions::NOTIFICATION_EXTENSION_INSTALL_ERROR, base::Bind(DoesInstallFailureReferToId, kGoodExtensionID)); - ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string())); // Wait for the hosted app installation to succeed and the extension // installation to fail (because hosted apps are whitelisted for use in // device-local accounts and extensions are not). - hosted_app_observer.Wait(); + install_observer.Wait(); extension_observer.Wait(); // Verify that the hosted app was installed. @@ -1127,9 +1184,7 @@ WaitForPolicy(); // Start listening for app/extension installation results. - content::WindowedNotificationObserver hosted_app_observer( - extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED, - base::Bind(DoesInstallSuccessReferToId, kHostedAppID)); + ExtensionInstallObserver install_observer(kHostedAppID); content::WindowedNotificationObserver extension_observer( extensions::NOTIFICATION_EXTENSION_INSTALL_ERROR, base::Bind(DoesInstallFailureReferToId, kGoodExtensionID)); @@ -1138,7 +1193,7 @@ // Wait for the hosted app installation to succeed and the extension // installation to fail. - hosted_app_observer.Wait(); + install_observer.Wait(); extension_observer.Wait(); // Verify that the hosted app was installed. @@ -1258,9 +1313,7 @@ WaitForPolicy(); // Start listening for app/extension installation results. - content::WindowedNotificationObserver hosted_app_observer( - extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED, - base::Bind(DoesInstallSuccessReferToId, kHostedAppID)); + ExtensionInstallObserver install_observer(kHostedAppID); content::WindowedNotificationObserver extension_observer( extensions::NOTIFICATION_EXTENSION_INSTALL_ERROR, base::Bind(DoesInstallFailureReferToId, kGoodExtensionID)); @@ -1270,7 +1323,7 @@ // Wait for the hosted app installation to succeed and the extension // installation to fail (because hosted apps are whitelisted for use in // device-local accounts and extensions are not). - hosted_app_observer.Wait(); + install_observer.Wait(); extension_observer.Wait(); // Verify that the extension was kept in the local cache. @@ -2199,12 +2252,10 @@ WaitForPolicy(); // Observe the app installation after login. - content::WindowedNotificationObserver extension_observer( - extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED, - base::Bind(DoesInstallSuccessReferToId, kShowManagedStorageID)); + ExtensionInstallObserver install_observer(kShowManagedStorageID); ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string())); WaitForSessionStart(); - extension_observer.Wait(); + install_observer.Wait(); // Verify that the app was installed. Profile* profile = GetProfileForTest();
diff --git a/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc b/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc index 3b15701..03ea6c0 100644 --- a/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc +++ b/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc
@@ -809,6 +809,18 @@ new base::StringValue(container.login_screen_domain_auto_complete()), nullptr); } + + if (policy.has_display_rotation_default()) { + const em::DisplayRotationDefaultProto& container( + policy.display_rotation_default()); + policies->Set( + key::kDisplayRotationDefault, + POLICY_LEVEL_MANDATORY, + POLICY_SCOPE_MACHINE, + POLICY_SOURCE_CLOUD, + DecodeIntegerValue(container.display_rotation_default()).release(), + nullptr); + } } } // namespace
diff --git a/chrome/browser/chromeos/policy/display_rotation_default_handler.cc b/chrome/browser/chromeos/policy/display_rotation_default_handler.cc new file mode 100644 index 0000000..03f72fb --- /dev/null +++ b/chrome/browser/chromeos/policy/display_rotation_default_handler.cc
@@ -0,0 +1,109 @@ +// Copyright 2015 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/chromeos/policy/display_rotation_default_handler.h" + +#include <stddef.h> + +#include "ash/display/display_manager.h" +#include "ash/shell.h" +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/location.h" +#include "base/logging.h" +#include "base/memory/ref_counted.h" +#include "base/single_thread_task_runner.h" +#include "base/thread_task_runner_handle.h" +#include "chromeos/settings/cros_settings_names.h" + +namespace policy { + +DisplayRotationDefaultHandler::DisplayRotationDefaultHandler() { + ash::Shell::GetInstance()->window_tree_host_manager()->AddObserver(this); + ash::Shell::GetInstance()->AddShellObserver(this); + settings_observer_ = chromeos::CrosSettings::Get()->AddSettingsObserver( + chromeos::kDisplayRotationDefault, + base::Bind(&DisplayRotationDefaultHandler::OnCrosSettingsChanged, + base::Unretained(this))); +} + +DisplayRotationDefaultHandler::~DisplayRotationDefaultHandler() { +} + +void DisplayRotationDefaultHandler::OnShellInitialized() { + UpdateFromCrosSettings(); + RotateDisplays(); +} + +void DisplayRotationDefaultHandler::OnDisplayConfigurationChanged() { + RotateDisplays(); +} + +void DisplayRotationDefaultHandler::OnWindowTreeHostManagerShutdown() { + ash::Shell::GetInstance()->window_tree_host_manager()->RemoveObserver(this); + ash::Shell::GetInstance()->RemoveShellObserver(this); + settings_observer_.reset(); + base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this); +} + +void DisplayRotationDefaultHandler::OnCrosSettingsChanged() { + if (!UpdateFromCrosSettings()) + return; + // Policy changed, so reset all displays. + rotated_displays_.clear(); + RotateDisplays(); +} + +void DisplayRotationDefaultHandler::RotateDisplays() { + if (!policy_enabled_ || rotation_in_progress_) + return; + + // Avoid nested calls of this function due to OnDisplayConfigurationChanged + // being called by rotations here. + rotation_in_progress_ = true; + + ash::DisplayManager* const display_manager = + ash::Shell::GetInstance()->display_manager(); + const size_t num_displays = display_manager->GetNumDisplays(); + for (size_t i = 0; i < num_displays; ++i) { + const gfx::Display& display = display_manager->GetDisplayAt(i); + const int64_t id = display.id(); + if (rotated_displays_.find(id) == rotated_displays_.end()) { + rotated_displays_.insert(id); + if (display.rotation() != display_rotation_default_) { + display_manager->SetDisplayRotation(id, display_rotation_default_, + gfx::Display::ROTATION_SOURCE_ACTIVE); + } + } + } + rotation_in_progress_ = false; +} + +bool DisplayRotationDefaultHandler::UpdateFromCrosSettings() { + int new_rotation; + bool new_policy_enabled = chromeos::CrosSettings::Get()->GetInteger( + chromeos::kDisplayRotationDefault, &new_rotation); + gfx::Display::Rotation new_display_rotation_default = gfx::Display::ROTATE_0; + if (new_policy_enabled) { + if (new_rotation >= gfx::Display::ROTATE_0 && + new_rotation <= gfx::Display::ROTATE_270) { + new_display_rotation_default = + static_cast<gfx::Display::Rotation>(new_rotation); + } else { + LOG(ERROR) << "CrosSettings contains invalid value " << new_rotation + << " for DisplayRotationDefault. Ignoring setting."; + new_policy_enabled = false; + } + } + if (new_policy_enabled != policy_enabled_ || + (new_policy_enabled && + new_display_rotation_default != display_rotation_default_)) { + policy_enabled_ = new_policy_enabled; + display_rotation_default_ = new_display_rotation_default; + return true; + } + return false; +} + +} // namespace policy
diff --git a/chrome/browser/chromeos/policy/display_rotation_default_handler.h b/chrome/browser/chromeos/policy/display_rotation_default_handler.h new file mode 100644 index 0000000..8c9bcd0 --- /dev/null +++ b/chrome/browser/chromeos/policy/display_rotation_default_handler.h
@@ -0,0 +1,70 @@ +// Copyright 2015 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_CHROMEOS_POLICY_DISPLAY_ROTATION_DEFAULT_HANDLER_H_ +#define CHROME_BROWSER_CHROMEOS_POLICY_DISPLAY_ROTATION_DEFAULT_HANDLER_H_ + +#include <stdint.h> + +#include <set> + +#include "ash/display/window_tree_host_manager.h" +#include "ash/shell_observer.h" +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "chrome/browser/chromeos/settings/cros_settings.h" +#include "ui/gfx/display.h" + +namespace policy { + +// Enforces the device policy DisplayRotationDefault. +// This class is created in ChromeShellDelegate::PreInit() and registers +// itself with WindowTreeHostManager as Observer for display changes, and +// with CrosSettings as Observer for setting changes. Whenever there is a change +// in the display configuration, any new display with an id that is not already +// in rotated_displays_ will be rotated according to the policy. When there is a +// change to the CrosSettings, the new policy is applied to all connected +// displays. +// This class owns itself and destroys itself when OnShutdown is called by +// WindowTreeHostManager. +class DisplayRotationDefaultHandler + : public ash::WindowTreeHostManager::Observer, + public ash::ShellObserver { + public: + DisplayRotationDefaultHandler(); + ~DisplayRotationDefaultHandler() override; + + // ash::ShellObserver: + void OnShellInitialized() override; + + // ash::WindowTreeHostManager::Observer: + void OnDisplayConfigurationChanged() override; + void OnWindowTreeHostManagerShutdown() override; + + private: + // Callback function for settings_observer_. + void OnCrosSettingsChanged(); + + // Applies the policy to all connected displays as necessary. + void RotateDisplays(); + + // Reads |chromeos::kDisplayRotationDefault| from CrosSettings and stores + // its value, and whether it has a value, in member variables + // |display_rotation_default_| and |policy_enabled_|. Returns true if the + // setting changed. + bool UpdateFromCrosSettings(); + + bool policy_enabled_ = false; + gfx::Display::Rotation display_rotation_default_ = gfx::Display::ROTATE_0; + std::set<int64_t> rotated_displays_; + bool rotation_in_progress_ = false; + + scoped_ptr<chromeos::CrosSettings::ObserverSubscription> settings_observer_; + + DISALLOW_COPY_AND_ASSIGN(DisplayRotationDefaultHandler); +}; + +} // namespace policy + +#endif // CHROME_BROWSER_CHROMEOS_POLICY_DISPLAY_ROTATION_DEFAULT_HANDLER_H_
diff --git a/chrome/browser/chromeos/policy/display_rotation_default_handler_browsertest.cc b/chrome/browser/chromeos/policy/display_rotation_default_handler_browsertest.cc new file mode 100644 index 0000000..1686ff3 --- /dev/null +++ b/chrome/browser/chromeos/policy/display_rotation_default_handler_browsertest.cc
@@ -0,0 +1,234 @@ +// Copyright 2015 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/chromeos/policy/display_rotation_default_handler.h" + +#include "ash/display/display_manager.h" +#include "ash/shell.h" +#include "base/bind.h" +#include "base/command_line.h" +#include "base/location.h" +#include "base/message_loop/message_loop.h" +#include "chrome/browser/chromeos/login/ui/login_display_host_impl.h" +#include "chrome/browser/chromeos/policy/device_policy_builder.h" +#include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h" +#include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h" +#include "chrome/browser/lifetime/application_lifetime.h" +#include "chromeos/chromeos_switches.h" +#include "chromeos/settings/cros_settings_names.h" +#include "content/public/test/test_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace em = enterprise_management; + +namespace policy { + +class DisplayRotationDefaultTest + : public policy::DevicePolicyCrosBrowserTest, + public testing::WithParamInterface<gfx::Display::Rotation> { + public: + DisplayRotationDefaultTest() {} + + void SetUpCommandLine(base::CommandLine* command_line) override { + command_line->AppendSwitch(chromeos::switches::kLoginManager); + command_line->AppendSwitch(chromeos::switches::kForceLoginManagerInTests); + } + + void SetUpInProcessBrowserTestFixture() override { + InstallOwnerKey(); + MarkAsEnterpriseOwned(); + DevicePolicyCrosBrowserTest::SetUpInProcessBrowserTestFixture(); + } + + void TearDownOnMainThread() override { + // If the login display is still showing, exit gracefully. + if (chromeos::LoginDisplayHostImpl::default_host()) { + base::MessageLoop::current()->PostTask(FROM_HERE, + base::Bind(&chrome::AttemptExit)); + content::RunMessageLoop(); + } + } + + protected: + void SetPolicy(int rotation) { + em::ChromeDeviceSettingsProto& proto(device_policy()->payload()); + proto.mutable_display_rotation_default()->set_display_rotation_default( + static_cast<em::DisplayRotationDefaultProto::Rotation>(rotation)); + RefreshPolicyAndWaitUntilDeviceSettingsUpdated(); + } + + // This is needed to test that refreshing the settings without change to the + // DisplayRotationDefault policy will not rotate the display again. + void SetADifferentPolicy() { + em::ChromeDeviceSettingsProto& proto(device_policy()->payload()); + const bool clock24 = proto.use_24hour_clock().use_24hour_clock(); + proto.mutable_use_24hour_clock()->set_use_24hour_clock(!clock24); + RefreshPolicyAndWaitUntilDeviceSettingsUpdated(); + } + + void UnsetPolicy() { + em::ChromeDeviceSettingsProto& proto(device_policy()->payload()); + proto.clear_display_rotation_default(); + RefreshPolicyAndWaitUntilDeviceSettingsUpdated(); + } + + ash::DisplayManager* GetDisplayManager() const { + return ash::Shell::GetInstance()->display_manager(); + } + + gfx::Display::Rotation GetRotationOfFirstDisplay() const { + const ash::DisplayManager* const display_manager = GetDisplayManager(); + const int64_t first_display_id = display_manager->first_display_id(); + const gfx::Display& first_display = + display_manager->GetDisplayForId(first_display_id); + return first_display.rotation(); + } + + // Fails the test and returns ROTATE_0 if there is no second display. + gfx::Display::Rotation GetRotationOfSecondDisplay() const { + const ash::DisplayManager* const display_manager = GetDisplayManager(); + if (display_manager->GetNumDisplays() < 2) { + ADD_FAILURE() + << "Requested rotation of second display while there was only one."; + return gfx::Display::ROTATE_0; + } + const ash::DisplayIdPair display_id_pair = + display_manager->GetCurrentDisplayIdPair(); + const gfx::Display& second_display = + display_manager->GetDisplayForId(display_id_pair.second); + return second_display.rotation(); + } + + // Creates second display if there is none yet, or removes it if there is one. + void ToggleSecondDisplay() { + GetDisplayManager()->AddRemoveDisplay(); + base::RunLoop run_loop; + run_loop.RunUntilIdle(); + } + + void RefreshPolicyAndWaitUntilDeviceSettingsUpdated() { + base::RunLoop run_loop; + // For calls from SetPolicy(). + scoped_ptr<chromeos::CrosSettings::ObserverSubscription> observer = + chromeos::CrosSettings::Get()->AddSettingsObserver( + chromeos::kDisplayRotationDefault, run_loop.QuitClosure()); + // For calls from SetADifferentPolicy(). + scoped_ptr<chromeos::CrosSettings::ObserverSubscription> observer2 = + chromeos::CrosSettings::Get()->AddSettingsObserver( + chromeos::kSystemUse24HourClock, run_loop.QuitClosure()); + RefreshDevicePolicy(); + run_loop.Run(); + } + + private: + DISALLOW_COPY_AND_ASSIGN(DisplayRotationDefaultTest); +}; + +// If gfx::Display::Rotation is ever modified and this test fails, there are +// hardcoded enum-values in the following files that might need adjustment: +// * this file: range check in this function, initializations, expected values, +// the list of parameters at the bottom of the file +// * display_rotation_default_handler.cc: Range check in UpdateFromCrosSettings, +// initialization to ROTATE_0 +// * display_rotation_default_handler.h: initialization to ROTATE_0 +// * chrome/browser/chromeos/policy/proto/chrome_device_policy.proto: +// DisplayRotationDefaultProto::Rotation should match one to one +IN_PROC_BROWSER_TEST_P(DisplayRotationDefaultTest, EnumsInSync) { + const gfx::Display::Rotation rotation = GetParam(); + EXPECT_EQ(em::DisplayRotationDefaultProto::Rotation_ARRAYSIZE, + gfx::Display::ROTATE_270 + 1) + << "Enums gfx::Display::Rotation and " + << "em::DisplayRotationDefaultProto::Rotation are not in sync."; + EXPECT_TRUE(em::DisplayRotationDefaultProto::Rotation_IsValid(rotation)) + << rotation << " is invalid as rotation. All valid values lie in " + << "the range from " << em::DisplayRotationDefaultProto::Rotation_MIN + << " to " << em::DisplayRotationDefaultProto::Rotation_MAX << "."; +} + +IN_PROC_BROWSER_TEST_P(DisplayRotationDefaultTest, FirstDisplay) { + const gfx::Display::Rotation policy_rotation = GetParam(); + EXPECT_EQ(gfx::Display::ROTATE_0, GetRotationOfFirstDisplay()) + << "Initial primary rotation before policy"; + + SetPolicy(policy_rotation); + int settings_rotation; + EXPECT_TRUE(chromeos::CrosSettings::Get()->GetInteger( + chromeos::kDisplayRotationDefault, &settings_rotation)); + EXPECT_EQ(policy_rotation, settings_rotation) + << "Value of CrosSettings after policy value changed"; + EXPECT_EQ(policy_rotation, GetRotationOfFirstDisplay()) + << "Rotation of primary display after policy"; +} + +IN_PROC_BROWSER_TEST_P(DisplayRotationDefaultTest, RefreshSecondDisplay) { + const gfx::Display::Rotation policy_rotation = GetParam(); + ToggleSecondDisplay(); + EXPECT_EQ(gfx::Display::ROTATE_0, GetRotationOfSecondDisplay()) + << "Rotation of secondary display before policy"; + SetPolicy(policy_rotation); + EXPECT_EQ(policy_rotation, GetRotationOfSecondDisplay()) + << "Rotation of already connected secondary display after policy"; +} + +IN_PROC_BROWSER_TEST_P(DisplayRotationDefaultTest, ConnectSecondDisplay) { + const gfx::Display::Rotation policy_rotation = GetParam(); + SetPolicy(policy_rotation); + ToggleSecondDisplay(); + EXPECT_EQ(policy_rotation, GetRotationOfFirstDisplay()) + << "Rotation of primary display after policy"; + EXPECT_EQ(policy_rotation, GetRotationOfSecondDisplay()) + << "Rotation of newly connected secondary display after policy"; +} + +IN_PROC_BROWSER_TEST_P(DisplayRotationDefaultTest, UserInteraction) { + const gfx::Display::Rotation policy_rotation = GetParam(); + const gfx::Display::Rotation user_rotation = gfx::Display::ROTATE_90; + GetDisplayManager()->SetDisplayRotation( + GetDisplayManager()->first_display_id(), user_rotation, + gfx::Display::ROTATION_SOURCE_USER); + EXPECT_EQ(user_rotation, GetRotationOfFirstDisplay()) + << "Rotation of primary display after user change"; + SetPolicy(policy_rotation); + EXPECT_EQ(policy_rotation, GetRotationOfFirstDisplay()) + << "Rotation of primary display after policy overrode user change"; + GetDisplayManager()->SetDisplayRotation( + GetDisplayManager()->first_display_id(), user_rotation, + gfx::Display::ROTATION_SOURCE_USER); + EXPECT_EQ(user_rotation, GetRotationOfFirstDisplay()) + << "Rotation of primary display after user overrode policy change"; + SetADifferentPolicy(); + EXPECT_EQ(user_rotation, GetRotationOfFirstDisplay()) + << "Rotation of primary display after policy reloaded without change"; +} + +IN_PROC_BROWSER_TEST_P(DisplayRotationDefaultTest, SetAndUnsetPolicy) { + const gfx::Display::Rotation policy_rotation = GetParam(); + SetPolicy(policy_rotation); + UnsetPolicy(); + EXPECT_EQ(policy_rotation, GetRotationOfFirstDisplay()) + << "Rotation of primary display after policy was set and removed."; +} + +IN_PROC_BROWSER_TEST_P(DisplayRotationDefaultTest, + SetAndUnsetPolicyWithUserInteraction) { + const gfx::Display::Rotation policy_rotation = GetParam(); + const gfx::Display::Rotation user_rotation = gfx::Display::ROTATE_90; + SetPolicy(policy_rotation); + GetDisplayManager()->SetDisplayRotation( + GetDisplayManager()->first_display_id(), user_rotation, + gfx::Display::ROTATION_SOURCE_USER); + UnsetPolicy(); + EXPECT_EQ(user_rotation, GetRotationOfFirstDisplay()) + << "Rotation of primary display after policy was set to " + << policy_rotation << ", user changed the rotation to " << user_rotation + << ", and policy was removed."; +} + +INSTANTIATE_TEST_CASE_P(PolicyDisplayRotationDefault, + DisplayRotationDefaultTest, + testing::Values(gfx::Display::ROTATE_0, + gfx::Display::ROTATE_90, + gfx::Display::ROTATE_180, + gfx::Display::ROTATE_270)); +} // namespace policy
diff --git a/chrome/browser/chromeos/policy/proto/chrome_device_policy.proto b/chrome/browser/chromeos/policy/proto/chrome_device_policy.proto index 4c20c27..a2a365f 100644 --- a/chrome/browser/chromeos/policy/proto/chrome_device_policy.proto +++ b/chrome/browser/chromeos/policy/proto/chrome_device_policy.proto
@@ -631,6 +631,23 @@ optional bool system_log_upload_enabled = 1 [default = false]; } +// This setting is controlled by the device policy DisplayRotationDefault. +// If the policy is set and therefore display_rotation_default contains a value, +// all displays will be rotated clockwise to the specified orientation at +// reboot, when first connected, or when the setting is changed. +// If the optional field |Rotation display_rotation_default = 1| is not present, +// no changes are done to the rotation. +message DisplayRotationDefaultProto { + // This enum corresponds to gfx::Display::Rotation in ui/gfx/display.h. + enum Rotation { + ROTATE_0 = 0; + ROTATE_90 = 1; + ROTATE_180 = 2; + ROTATE_270 = 3; + }; + optional Rotation display_rotation_default = 1; +} + message ChromeDeviceSettingsProto { optional DevicePolicyRefreshRateProto device_policy_refresh_rate = 1; optional UserWhitelistProto user_whitelist = 2; @@ -674,4 +691,5 @@ optional LoginScreenDomainAutoCompleteProto login_screen_domain_auto_complete = 37; optional DeviceLogUploadSettingsProto device_log_upload_settings = 38; + optional DisplayRotationDefaultProto display_rotation_default = 39; }
diff --git a/chrome/browser/chromeos/policy/user_affiliation_browsertest.cc b/chrome/browser/chromeos/policy/user_affiliation_browsertest.cc new file mode 100644 index 0000000..8c9e368 --- /dev/null +++ b/chrome/browser/chromeos/policy/user_affiliation_browsertest.cc
@@ -0,0 +1,93 @@ +// Copyright 2015 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 "base/memory/scoped_ptr.h" +#include "chrome/browser/chromeos/policy/affiliation_test_helper.h" +#include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h" +#include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/fake_session_manager_client.h" +#include "chromeos/dbus/session_manager_client.h" +#include "components/user_manager/user.h" +#include "components/user_manager/user_manager.h" +#include "content/public/test/test_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace policy { + +namespace { + +const char kAffiliatedUser[] = "affiliated-user@example.com"; +const char kAffiliationID[] = "some-affiliation-id"; +const char kAnotherAffiliationID[] = "another-affiliation-id"; +struct Params { + explicit Params(bool affiliated) : affiliated_(affiliated) {} + bool affiliated_; +}; + +} // namespace + +class UserAffiliationBrowserTest + : public InProcessBrowserTest, + public ::testing::WithParamInterface<Params> { + public: + UserAffiliationBrowserTest() { set_exit_when_last_browser_closes(false); } + + protected: + // InProcessBrowserTest + void SetUpCommandLine(base::CommandLine* command_line) override { + InProcessBrowserTest::SetUpCommandLine(command_line); + affiliation_test_helper::AppendCommandLineSwitchesForLoginManager( + command_line); + } + + // InProcessBrowserTest + void SetUpInProcessBrowserTestFixture() override { + InProcessBrowserTest::SetUpInProcessBrowserTestFixture(); + + chromeos::FakeSessionManagerClient* fake_session_manager_client = + new chromeos::FakeSessionManagerClient; + chromeos::DBusThreadManager::GetSetterForTesting()->SetSessionManagerClient( + make_scoped_ptr<chromeos::SessionManagerClient>( + fake_session_manager_client)); + + UserPolicyBuilder user_policy; + DevicePolicyCrosTestHelper test_helper; + + std::set<std::string> device_affiliation_ids; + device_affiliation_ids.insert(kAffiliationID); + affiliation_test_helper::SetDeviceAffiliationID( + &test_helper, fake_session_manager_client, device_affiliation_ids); + + std::set<std::string> user_affiliation_ids; + if (GetParam().affiliated_) { + user_affiliation_ids.insert(kAffiliationID); + } else { + user_affiliation_ids.insert(kAnotherAffiliationID); + } + affiliation_test_helper::SetUserAffiliationIDs( + &user_policy, fake_session_manager_client, kAffiliatedUser, + user_affiliation_ids); + } + + private: + DISALLOW_COPY_AND_ASSIGN(UserAffiliationBrowserTest); +}; + +IN_PROC_BROWSER_TEST_P(UserAffiliationBrowserTest, PRE_Affiliated) { + affiliation_test_helper::PreLoginUser(kAffiliatedUser); +} + +IN_PROC_BROWSER_TEST_P(UserAffiliationBrowserTest, Affiliated) { + affiliation_test_helper::LoginUser(kAffiliatedUser); + EXPECT_EQ(GetParam().affiliated_, + user_manager::UserManager::Get() + ->FindUser(AccountId::FromUserEmail(kAffiliatedUser)) + ->is_affiliated()); +} + +INSTANTIATE_TEST_CASE_P(AffiliationCheck, + UserAffiliationBrowserTest, + ::testing::Values(Params(true), Params(false))); + +} // namespace policy
diff --git a/chrome/browser/chromeos/proxy_config_service_impl.cc b/chrome/browser/chromeos/proxy_config_service_impl.cc index d5b69a6..4e63069 100644 --- a/chrome/browser/chromeos/proxy_config_service_impl.cc +++ b/chrome/browser/chromeos/proxy_config_service_impl.cc
@@ -13,7 +13,6 @@ #include "base/values.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/net/proxy_config_handler.h" -#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/common/pref_names.h" #include "chromeos/network/network_profile.h" #include "chromeos/network/network_profile_handler.h" @@ -152,12 +151,9 @@ return false; } if (onc_source == ::onc::ONC_SOURCE_DEVICE_POLICY) { - policy::BrowserPolicyConnectorChromeOS* connector = - g_browser_process->platform_part()->browser_policy_connector_chromeos(); const user_manager::User* logged_in_user = user_manager::UserManager::Get()->GetLoggedInUser(); - if (connector->GetUserAffiliation(logged_in_user->email()) == - policy::USER_AFFILIATION_MANAGED) { + if (logged_in_user->is_affiliated()) { VLOG(1) << "Respecting proxy for network, as logged-in user belongs to " << "the domain the device is enrolled to."; return false;
diff --git a/chrome/browser/chromeos/settings/device_settings_provider.cc b/chrome/browser/chromeos/settings/device_settings_provider.cc index 6cf0395..df7694f37 100644 --- a/chrome/browser/chromeos/settings/device_settings_provider.cc +++ b/chrome/browser/chromeos/settings/device_settings_provider.cc
@@ -59,6 +59,7 @@ kDeviceDisabled, kDeviceDisabledMessage, kDeviceOwner, + kDisplayRotationDefault, kExtensionCacheSize, kHeartbeatEnabled, kHeartbeatFrequency, @@ -440,6 +441,13 @@ kExtensionCacheSize, policy.extension_cache_size().extension_cache_size()); } + + if (policy.has_display_rotation_default() && + policy.display_rotation_default().has_display_rotation_default()) { + new_values_cache->SetInteger( + kDisplayRotationDefault, + policy.display_rotation_default().display_rotation_default()); + } } void DecodeLogUploadPolicies(const em::ChromeDeviceSettingsProto& policy,
diff --git a/chrome/browser/component_updater/supervised_user_whitelist_installer.cc b/chrome/browser/component_updater/supervised_user_whitelist_installer.cc index 61e3841..a266eec 100644 --- a/chrome/browser/component_updater/supervised_user_whitelist_installer.cc +++ b/chrome/browser/component_updater/supervised_user_whitelist_installer.cc
@@ -24,6 +24,7 @@ #include "base/thread_task_runner_handle.h" #include "chrome/browser/profiles/profile_info_cache.h" #include "chrome/browser/profiles/profile_info_cache_observer.h" +#include "chrome/browser/supervised_user/supervised_user_whitelist_service.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/pref_names.h" #include "components/component_updater/component_updater_paths.h" @@ -386,29 +387,42 @@ } void SupervisedUserWhitelistInstallerImpl::RegisterComponents() { + const std::map<std::string, std::string> command_line_whitelists = + SupervisedUserWhitelistService::GetWhitelistsFromCommandLine(); + std::set<std::string> registered_whitelists; - const base::DictionaryValue* whitelists = - local_state_->GetDictionary(prefs::kRegisteredSupervisedUserWhitelists); + std::set<std::string> stale_whitelists; + DictionaryPrefUpdate update(local_state_, + prefs::kRegisteredSupervisedUserWhitelists); + base::DictionaryValue* whitelists = update.Get(); for (base::DictionaryValue::Iterator it(*whitelists); !it.IsAtEnd(); it.Advance()) { const base::DictionaryValue* dict = nullptr; it.value().GetAsDictionary(&dict); + const std::string& id = it.key(); + // Skip whitelists with no clients. This can happen when a whitelist was - // previously registered with an empty client ID. + // previously registered on the command line but isn't anymore. const base::ListValue* clients = nullptr; - if (!dict->GetList(kClients, &clients) || clients->empty()) + if ((!dict->GetList(kClients, &clients) || clients->empty()) && + command_line_whitelists.count(id) == 0) { + stale_whitelists.insert(id); continue; + } std::string name; bool result = dict->GetString(kName, &name); DCHECK(result); - const std::string& id = it.key(); RegisterComponent(id, name, base::Closure()); registered_whitelists.insert(id); } + // Clean up stale whitelists as determined above. + for (const std::string& id : stale_whitelists) + whitelists->RemoveWithoutPathExpansion(id, nullptr); + cus_->GetSequencedTaskRunner()->PostTask( FROM_HERE, base::Bind(&RemoveUnregisteredWhitelistsOnTaskRunner, registered_whitelists));
diff --git a/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_api.cc b/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_api.cc index fe3bc1b..a0024f73 100644 --- a/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_api.cc +++ b/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_api.cc
@@ -17,19 +17,12 @@ namespace { -// Checks for the current browser context if the user is affiliated and the -// device is enterprise managed. +// Checks for the current browser context if the user is affiliated. bool IsPermittedToGetDeviceId(content::BrowserContext* context) { - policy::BrowserPolicyConnectorChromeOS* connector = - g_browser_process->platform_part()->browser_policy_connector_chromeos(); - const user_manager::User* user = chromeos::ProfileHelper::Get()->GetUserByProfile( Profile::FromBrowserContext(context)); - - return connector->IsEnterpriseManaged() && - connector->GetUserAffiliation(user->email()) == - policy::USER_AFFILIATION_MANAGED; + return user->is_affiliated(); } // Returns the directory device id for the permitted extensions or an empty
diff --git a/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc b/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc index 19d0ebf..685e0d7 100644 --- a/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc +++ b/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc
@@ -2,22 +2,27 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/prefs/pref_service.h" #include "base/strings/stringprintf.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/chromeos/policy/affiliation_test_helper.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h" #include "chrome/browser/chromeos/policy/stub_enterprise_install_attributes.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/net/url_request_mock_util.h" +#include "chrome/test/base/ui_test_utils.h" #include "chromeos/dbus/fake_session_manager_client.h" #include "chromeos/login/user_names.h" #include "components/policy/core/common/mock_configuration_policy_provider.h" -#include "components/policy/core/common/policy_types.h" #include "components/signin/core/account_id/account_id.h" +#include "components/user_manager/user_manager.h" #include "content/public/browser/notification_service.h" #include "content/public/test/test_utils.h" #include "extensions/browser/api_test_utils.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/test_extension_registry_observer.h" +#include "extensions/test/result_catcher.h" #include "net/test/url_request/url_request_mock_http_job.h" #include "policy/policy_constants.h" @@ -29,34 +34,71 @@ const base::FilePath::CharType kUpdateManifestFileName[] = FILE_PATH_LITERAL("update_manifest.xml"); +const char kAffiliatedUserEmail[] = "user@example.com"; +const char kAffiliationID[] = "some-affiliation-id"; +const char kAnotherAffiliationID[] = "another-affiliation-id"; + // The managed_storage extension has a key defined in its manifest, so that // its extension ID is well-known and the policy system can push policies for // the extension. const char kTestExtensionID[] = "nbiliclbejdndfpchgkbmfoppjplbdok"; +struct Params { + explicit Params(bool affiliated) : affiliated_(affiliated) {} + bool affiliated_; +}; + } // namespace namespace extensions { -class EnterpriseDeviceAttributesTest : public ExtensionApiTest { +class EnterpriseDeviceAttributesTest : + public ExtensionApiTest, + public ::testing::WithParamInterface<Params> { public: - explicit EnterpriseDeviceAttributesTest(const std::string& domain) - : fake_session_manager_client_(new chromeos::FakeSessionManagerClient), - test_domain_(domain) {} + EnterpriseDeviceAttributesTest() { + set_exit_when_last_browser_closes(false); + set_chromeos_user_ = false; + } protected: + // ExtensionApiTest + void SetUpCommandLine(base::CommandLine* command_line) override { + ExtensionApiTest::SetUpCommandLine(command_line); + policy::affiliation_test_helper:: + AppendCommandLineSwitchesForLoginManager(command_line); + } + void SetUpInProcessBrowserTestFixture() override { - chromeos::DBusThreadManager::GetSetterForTesting()->SetSessionManagerClient( - make_scoped_ptr(fake_session_manager_client_)); ExtensionApiTest::SetUpInProcessBrowserTestFixture(); + chromeos::FakeSessionManagerClient* fake_session_manager_client = + new chromeos::FakeSessionManagerClient; + chromeos::DBusThreadManager::GetSetterForTesting()->SetSessionManagerClient( + scoped_ptr<chromeos::SessionManagerClient>( + fake_session_manager_client)); + + std::set<std::string> device_affiliation_ids; + device_affiliation_ids.insert(kAffiliationID); + policy::affiliation_test_helper::SetDeviceAffiliationID( + &test_helper_, fake_session_manager_client, device_affiliation_ids); + + std::set<std::string> user_affiliation_ids; + if (GetParam().affiliated_) { + user_affiliation_ids.insert(kAffiliationID); + } else { + user_affiliation_ids.insert(kAnotherAffiliationID); + } + policy::UserPolicyBuilder user_policy; + policy::affiliation_test_helper::SetUserAffiliationIDs( + &user_policy, fake_session_manager_client, + affiliated_account_id_.GetUserEmail(), user_affiliation_ids); + // Set up fake install attributes. scoped_ptr<policy::StubEnterpriseInstallAttributes> attributes( new policy::StubEnterpriseInstallAttributes()); - attributes->SetDomain(test_domain_); - attributes->SetRegistrationUser( - chromeos::login::StubAccountId().GetUserEmail()); + attributes->SetRegistrationUser(affiliated_account_id_.GetUserEmail()); policy::BrowserPolicyConnectorChromeOS::SetInstallAttributesForTesting( attributes.release()); @@ -67,8 +109,8 @@ device_policy->policy_data().set_directory_api_id(kDeviceId); device_policy->Build(); - fake_session_manager_client_->set_device_policy(device_policy->GetBlob()); - fake_session_manager_client_->OnPropertyChangeComplete(true); + fake_session_manager_client->set_device_policy(device_policy->GetBlob()); + fake_session_manager_client->OnPropertyChangeComplete(true); // Init the user policy provider. EXPECT_CALL(policy_provider_, IsInitializationComplete(testing::_)) @@ -79,18 +121,16 @@ } void SetUpOnMainThread() override { + const base::ListValue* users = + g_browser_process->local_state()->GetList("LoggedInUsers"); + if (!users->empty()) { + policy::affiliation_test_helper::LoginUser( + affiliated_account_id_.GetUserEmail()); + } + ExtensionApiTest::SetUpOnMainThread(); - - // Enable the URLRequestMock, which is required for force-installing the - // test extension through policy. - content::BrowserThread::PostTask( - content::BrowserThread::IO, FROM_HERE, - base::Bind(chrome_browser_net::SetUrlRequestMocksEnabled, true)); - - SetPolicy(); } - private: void SetPolicy() { // Extensions that are force-installed come from an update URL, which // defaults to the webstore. Use a mock URL for this test with an update @@ -116,46 +156,59 @@ observer.WaitForExtensionLoaded(); } - chromeos::FakeSessionManagerClient* const fake_session_manager_client_; + // Load |page_url| in |browser| and wait for PASSED or FAILED notification. + // The functionality of this function is reduced functionality of + // RunExtensionSubtest(), but we don't use it here because it requires + // function InProcessBrowserTest::browser() to return non-NULL pointer. + // Unfortunately it returns the value which is set in constructor and can't be + // modified. Because on login flow there is no browser, the function + // InProcessBrowserTest::browser() always returns NULL. Besides this we need + // only very little functionality from RunExtensionSubtest(). Thus so that + // don't make RunExtensionSubtest() to complex we just introduce a new + // function. + bool TestExtension(Browser* browser, const std::string& page_url) { + DCHECK(!page_url.empty()) << "page_url cannot be empty"; + + extensions::ResultCatcher catcher; + ui_test_utils::NavigateToURL(browser, GURL(page_url)); + + if (!catcher.GetNextResult()) { + message_ = catcher.message(); + return false; + } + return true; + } + + const AccountId affiliated_account_id_ = + AccountId::FromUserEmail(kAffiliatedUserEmail); + + private: policy::MockConfigurationPolicyProvider policy_provider_; policy::DevicePolicyCrosTestHelper test_helper_; - const std::string test_domain_; }; -// Creates affiliated user before browser initializes. -class EnterpriseDeviceAttributesAffiliatedTest - : public EnterpriseDeviceAttributesTest { - public: - EnterpriseDeviceAttributesAffiliatedTest() - : EnterpriseDeviceAttributesTest("gmail.com") {} -}; - -// Creates non-affiliated user before browser init. -class EnterpriseDeviceAttributesNonAffiliatedTest - : public EnterpriseDeviceAttributesTest { - public: - EnterpriseDeviceAttributesNonAffiliatedTest() - : EnterpriseDeviceAttributesTest("example.com") {} -}; - -// Tests the case of an affiliated user and pre-installed extension. Fetches -// the valid cloud directory device id. -IN_PROC_BROWSER_TEST_F(EnterpriseDeviceAttributesAffiliatedTest, Success) { - // Pass the expected value (device_id) to test. - ASSERT_TRUE(RunExtensionSubtest( - "", base::StringPrintf("chrome-extension://%s/basic.html?%s", - kTestExtensionID, kDeviceId))) - << message_; +IN_PROC_BROWSER_TEST_P(EnterpriseDeviceAttributesTest, PRE_Success) { + policy::affiliation_test_helper::PreLoginUser( + affiliated_account_id_.GetUserEmail()); } -// Test the case of non-affiliated user and pre-installed by policy extension. -// Extension API is available, but fetches the empty string. -IN_PROC_BROWSER_TEST_F(EnterpriseDeviceAttributesNonAffiliatedTest, - EmptyString) { - // Pass the expected value (empty string) to test. - ASSERT_TRUE(RunExtensionSubtest( - "", base::StringPrintf("chrome-extension://%s/basic.html?%s", - kTestExtensionID, ""))) +IN_PROC_BROWSER_TEST_P(EnterpriseDeviceAttributesTest, Success) { + content::BrowserThread::PostTask( + content::BrowserThread::IO, FROM_HERE, + base::Bind(chrome_browser_net::SetUrlRequestMocksEnabled, true)); + + SetPolicy(); + + EXPECT_EQ(GetParam().affiliated_, user_manager::UserManager::Get()-> + FindUser(affiliated_account_id_)->is_affiliated()); + + // Device ID is available only for affiliated user. + std::string device_id = GetParam().affiliated_ ? kDeviceId : ""; + + // Pass the expected value (device_id) to test. + ASSERT_TRUE(TestExtension(CreateBrowser(profile()), + base::StringPrintf("chrome-extension://%s/basic.html?%s", + kTestExtensionID, device_id.c_str()))) << message_; } @@ -183,4 +236,8 @@ extension->install_warnings()[0].message); } +// Both cases of affiliated and non-affiliated on the device user are tested. +INSTANTIATE_TEST_CASE_P(AffiliationCheck, + EnterpriseDeviceAttributesTest, + ::testing::Values(Params(true), Params(false))); } // namespace extensions
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc index c936d30..acbdb81 100644 --- a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc +++ b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc
@@ -5,29 +5,51 @@ #include <cryptohi.h> #include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "base/path_service.h" +#include "base/prefs/pref_service.h" #include "base/strings/stringprintf.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/chromeos/login/test/https_forwarder.h" +#include "chrome/browser/chromeos/policy/affiliation_test_helper.h" #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/net/nss_context.h" #include "chrome/browser/net/url_request_mock_util.h" +#include "chrome/common/chrome_paths.h" +#include "chrome/test/base/ui_test_utils.h" #include "chromeos/chromeos_switches.h" +#include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/fake_session_manager_client.h" +#include "chromeos/dbus/session_manager_client.h" #include "chromeos/login/user_names.h" #include "components/policy/core/browser/browser_policy_connector.h" #include "components/policy/core/common/mock_configuration_policy_provider.h" #include "components/policy/core/common/policy_map.h" -#include "components/policy/core/common/policy_types.h" #include "components/signin/core/account_id/account_id.h" +#include "components/user_manager/user_manager.h" #include "content/public/common/content_switches.h" -#include "content/public/test/test_utils.h" #include "crypto/nss_util_internal.h" #include "crypto/scoped_test_system_nss_key_slot.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/test_extension_registry_observer.h" +#include "extensions/browser/test_extension_registry_observer.h" +#include "extensions/test/result_catcher.h" +#include "google_apis/gaia/fake_gaia.h" +#include "google_apis/gaia/gaia_constants.h" +#include "google_apis/gaia/gaia_switches.h" +#include "google_apis/gaia/gaia_urls.h" #include "net/base/net_errors.h" #include "net/cert/nss_cert_database.h" +#include "net/dns/mock_host_resolver.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "net/test/embedded_test_server/http_request.h" +#include "net/test/embedded_test_server/http_response.h" #include "net/test/url_request/url_request_mock_http_job.h" #include "policy/policy_constants.h" #include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + namespace { @@ -134,6 +156,10 @@ // its extension ID is well-known and the policy system can push policies for // the extension. const char kTestExtensionID[] = "aecpbnckhoppanpmefllkdkohionpmig"; +const char kAffiliationID[] = "some-affiliation-id"; +const char kTestUserinfoToken[] = "fake-userinfo-token"; + +using policy::affiliation_test_helper::kEnterpriseUser; enum SystemToken { SYSTEM_TOKEN_EXISTS, @@ -167,7 +193,34 @@ : public ExtensionApiTest, public ::testing::WithParamInterface<Params> { public: - EnterprisePlatformKeysTest() {} + EnterprisePlatformKeysTest() { + // Command line should not be tweaked as if user is already logged in. + set_chromeos_user_ = false; + // We log in without running browser. + set_exit_when_last_browser_closes(false); + } + + void SetUp() override { + base::FilePath test_data_dir; + PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir); + embedded_test_server()->ServeFilesFromDirectory(test_data_dir); + + embedded_test_server()->RegisterRequestHandler( + base::Bind(&FakeGaia::HandleRequest, + base::Unretained(&fake_gaia_))); + + // Don't spin up the IO thread yet since no threads are allowed while + // spawning sandbox host process. See crbug.com/322732. + ASSERT_TRUE(embedded_test_server()->InitializeAndListen()); + + // Start https wrapper here so that the URLs can be pointed at it in + // SetUpCommandLine(). + ASSERT_TRUE(gaia_https_forwarder_.Initialize( + GaiaUrls::GetInstance()->gaia_url().host(), + embedded_test_server()->base_url())); + + ExtensionApiTest::SetUp(); + } void SetUpCommandLine(base::CommandLine* command_line) override { ExtensionApiTest::SetUpCommandLine(command_line); @@ -176,27 +229,49 @@ command_line->AppendSwitch( switches::kEnableExperimentalWebPlatformFeatures); - std::string user_email = "someuser@anydomain.com"; + policy::affiliation_test_helper:: + AppendCommandLineSwitchesForLoginManager(command_line); - // The command line flag kLoginUser determines the user's email and thus - // his affiliation to the domain that the device is enrolled to. - if (GetParam().user_affiliation_ == USER_AFFILIATION_ENROLLED_DOMAIN) - user_email = chromeos::login::StubAccountId().GetUserEmail(); + const GURL gaia_url = gaia_https_forwarder_.GetURLForSSLHost(std::string()); + command_line->AppendSwitchASCII(::switches::kGaiaUrl, gaia_url.spec()); + command_line->AppendSwitchASCII(::switches::kLsoUrl, gaia_url.spec()); + command_line->AppendSwitchASCII(::switches::kGoogleApisUrl, + gaia_url.spec()); - command_line->AppendSwitchASCII(chromeos::switches::kLoginUser, user_email); + fake_gaia_.Initialize(); + fake_gaia_.set_issue_oauth_code_cookie(true); } void SetUpInProcessBrowserTestFixture() override { ExtensionApiTest::SetUpInProcessBrowserTestFixture(); - if (GetParam().device_status_ == DEVICE_STATUS_ENROLLED) { - device_policy_test_helper_.device_policy()->policy_data().set_username( - chromeos::login::StubAccountId().GetUserEmail()); + host_resolver()->AddRule("*", "127.0.0.1"); - device_policy_test_helper_.device_policy()->Build(); - device_policy_test_helper_.MarkAsEnterpriseOwned(); + chromeos::FakeSessionManagerClient* fake_session_manager_client = + new chromeos::FakeSessionManagerClient; + chromeos::DBusThreadManager::GetSetterForTesting()->SetSessionManagerClient( + scoped_ptr<chromeos::SessionManagerClient>( + fake_session_manager_client)); + + if (GetParam().device_status_ == DEVICE_STATUS_ENROLLED) { + std::set<std::string> device_affiliation_ids; + device_affiliation_ids.insert(kAffiliationID); + policy::affiliation_test_helper::SetDeviceAffiliationID( + &device_policy_test_helper_, fake_session_manager_client, + device_affiliation_ids); } + + if (GetParam().user_affiliation_ == USER_AFFILIATION_ENROLLED_DOMAIN) { + std::set<std::string> user_affiliation_ids; + user_affiliation_ids.insert(kAffiliationID); + policy::UserPolicyBuilder user_policy; + policy::affiliation_test_helper::SetUserAffiliationIDs( + &user_policy, fake_session_manager_client, kEnterpriseUser, + user_affiliation_ids); + } + + EXPECT_CALL(policy_provider_, IsInitializationComplete(testing::_)) .WillRepeatedly(testing::Return(true)); policy_provider_.SetAutoRefresh(); @@ -205,6 +280,31 @@ } void SetUpOnMainThread() override { + // Start the accept thread as the sandbox host process has already been + // spawned. + embedded_test_server()->StartAcceptingConnections(); + + FakeGaia::AccessTokenInfo token_info; + token_info.scopes.insert(GaiaConstants::kDeviceManagementServiceOAuth); + token_info.scopes.insert(GaiaConstants::kOAuthWrapBridgeUserInfoScope); + token_info.audience = GaiaUrls::GetInstance()->oauth2_chrome_client_id(); + token_info.token = kTestUserinfoToken; + token_info.email = kEnterpriseUser; + fake_gaia_.IssueOAuthToken( + policy::affiliation_test_helper::kFakeRefreshToken, + token_info); + + // On PRE_ test stage list of users is empty at this point. Then in the body + // of PRE_ test kEnterpriseUser is added. Afterwards in the main test flow + // after PRE_ test the list of user contains one kEnterpriseUser user. + // This user logs in. + const base::ListValue* users = + g_browser_process->local_state()->GetList("LoggedInUsers"); + + // This condition is not held in PRE_ test. + if (!users->empty()) + policy::affiliation_test_helper::LoginUser(kEnterpriseUser); + if (GetParam().system_token_ == SYSTEM_TOKEN_EXISTS) { base::RunLoop loop; content::BrowserThread::PostTask( @@ -212,31 +312,11 @@ FROM_HERE, base::Bind(&EnterprisePlatformKeysTest::SetUpTestSystemSlotOnIO, base::Unretained(this), - browser()->profile()->GetResourceContext(), loop.QuitClosure())); loop.Run(); } ExtensionApiTest::SetUpOnMainThread(); - - // Enable the URLRequestMock, which is required for force-installing the - // test extension through policy. - content::BrowserThread::PostTask( - content::BrowserThread::IO, - FROM_HERE, - base::Bind(chrome_browser_net::SetUrlRequestMocksEnabled, true)); - - { - base::RunLoop loop; - GetNSSCertDatabaseForProfile( - browser()->profile(), - base::Bind(&EnterprisePlatformKeysTest::DidGetCertDatabase, - base::Unretained(this), - loop.QuitClosure())); - loop.Run(); - } - - SetPolicy(); } void TearDownOnMainThread() override { @@ -252,9 +332,9 @@ loop.QuitClosure())); loop.Run(); } + EXPECT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete()); } - private: void DidGetCertDatabase(const base::Closure& done_callback, net::NSSCertDatabase* cert_db) { // In order to use a prepared certificate, import a private key to the @@ -265,28 +345,6 @@ done_callback.Run(); } - void SetUpTestSystemSlotOnIO(content::ResourceContext* context, - const base::Closure& done_callback) { - test_system_slot_.reset(new crypto::ScopedTestSystemNSSKeySlot()); - ASSERT_TRUE(test_system_slot_->ConstructedSuccessfully()); - - // Import a private key to the system slot. The Javascript part of this - // test has a prepared certificate for this key. - ImportPrivateKeyPKCS8ToSlot(privateKeyPkcs8System, - arraysize(privateKeyPkcs8System), - test_system_slot_->slot()); - - content::BrowserThread::PostTask( - content::BrowserThread::UI, FROM_HERE, done_callback); - } - - void TearDownTestSystemSlotOnIO(const base::Closure& done_callback) { - test_system_slot_.reset(); - - content::BrowserThread::PostTask( - content::BrowserThread::UI, FROM_HERE, done_callback); - } - void SetPolicy() { // Extensions that are force-installed come from an update URL, which // defaults to the webstore. Use a mock URL for this test with an update @@ -315,14 +373,84 @@ observer.WaitForExtensionWillBeInstalled(); } + // Load |page_url| in |browser| and wait for PASSED or FAILED notification. + // The functionality of this function is reduced functionality of + // RunExtensionSubtest(), but we don't use it here because it requires + // function InProcessBrowserTest::browser() to return non-NULL pointer. + // Unfortunately it returns the value which is set in constructor and can't be + // modified. Because on login flow there is no browser, the function + // InProcessBrowserTest::browser() always returns NULL. Besides this we need + // only very little functionality from RunExtensionSubtest(). Thus so that + // don't make RunExtensionSubtest() to complex we just introduce a new + // function. + bool TestExtension(Browser* browser, const std::string& page_url) { + DCHECK(!page_url.empty()) << "page_url cannot be empty"; + + extensions::ResultCatcher catcher; + ui_test_utils::NavigateToURL(browser, GURL(page_url)); + + if (!catcher.GetNextResult()) { + message_ = catcher.message(); + return false; + } + return true; + } + + private: + + void SetUpTestSystemSlotOnIO(const base::Closure& done_callback) { + test_system_slot_.reset(new crypto::ScopedTestSystemNSSKeySlot()); + ASSERT_TRUE(test_system_slot_->ConstructedSuccessfully()); + + // Import a private key to the system slot. The Javascript part of this + // test has a prepared certificate for this key. + ImportPrivateKeyPKCS8ToSlot(privateKeyPkcs8System, + arraysize(privateKeyPkcs8System), + test_system_slot_->slot()); + + content::BrowserThread::PostTask( + content::BrowserThread::UI, FROM_HERE, done_callback); + } + + void TearDownTestSystemSlotOnIO(const base::Closure& done_callback) { + test_system_slot_.reset(); + + content::BrowserThread::PostTask( + content::BrowserThread::UI, FROM_HERE, done_callback); + } + policy::DevicePolicyCrosTestHelper device_policy_test_helper_; scoped_ptr<crypto::ScopedTestSystemNSSKeySlot> test_system_slot_; policy::MockConfigurationPolicyProvider policy_provider_; + FakeGaia fake_gaia_; + chromeos::HTTPSForwarder gaia_https_forwarder_; }; } // namespace +IN_PROC_BROWSER_TEST_P(EnterprisePlatformKeysTest, PRE_Basic) { + policy::affiliation_test_helper::PreLoginUser(kEnterpriseUser); +} + IN_PROC_BROWSER_TEST_P(EnterprisePlatformKeysTest, Basic) { + // Enable the URLRequestMock, which is required for force-installing the + // test extension through policy. + content::BrowserThread::PostTask( + content::BrowserThread::IO, + FROM_HERE, + base::Bind(chrome_browser_net::SetUrlRequestMocksEnabled, true)); + + { + base::RunLoop loop; + GetNSSCertDatabaseForProfile( + profile(), + base::Bind(&EnterprisePlatformKeysTest::DidGetCertDatabase, + base::Unretained(this), + loop.QuitClosure())); + loop.Run(); + } + SetPolicy(); + // By default, the system token is disabled. std::string system_token_availability = ""; @@ -335,8 +463,7 @@ system_token_availability = "systemTokenEnabled"; } - ASSERT_TRUE(RunExtensionSubtest( - "", + ASSERT_TRUE(TestExtension(CreateBrowser(profile()), base::StringPrintf("chrome-extension://%s/basic.html?%s", kTestExtensionID, system_token_availability.c_str())))
diff --git a/chrome/browser/extensions/api/image_writer_private/operation.cc b/chrome/browser/extensions/api/image_writer_private/operation.cc index 0fec496..5c4ce7c5 100644 --- a/chrome/browser/extensions/api/image_writer_private/operation.cc +++ b/chrome/browser/extensions/api/image_writer_private/operation.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/extensions/api/image_writer_private/error_messages.h" #include "chrome/browser/extensions/api/image_writer_private/operation_manager.h" #include "content/public/browser/browser_thread.h" +#include "third_party/zlib/google/zip_reader.h" namespace extensions { namespace image_writer { @@ -41,7 +42,8 @@ device_path_(device_path), #endif stage_(image_writer_api::STAGE_UNKNOWN), - progress_(0) { + progress_(0), + zip_reader_(new zip::ZipReader) { } Operation::~Operation() {} @@ -105,20 +107,20 @@ SetStage(image_writer_api::STAGE_UNZIP); - if (!(zip_reader_.Open(image_path_) && zip_reader_.AdvanceToNextEntry() && - zip_reader_.OpenCurrentEntryInZip())) { + if (!(zip_reader_->Open(image_path_) && zip_reader_->AdvanceToNextEntry() && + zip_reader_->OpenCurrentEntryInZip())) { Error(error::kUnzipGenericError); return; } - if (zip_reader_.HasMore()) { + if (zip_reader_->HasMore()) { Error(error::kUnzipInvalidArchive); return; } // Create a new target to unzip to. The original file is opened by the // zip_reader_. - zip::ZipReader::EntryInfo* entry_info = zip_reader_.current_entry_info(); + zip::ZipReader::EntryInfo* entry_info = zip_reader_->current_entry_info(); if (entry_info) { image_path_ = temp_dir_.path().Append(entry_info->file_path().BaseName()); } else { @@ -126,13 +128,13 @@ return; } - zip_reader_.ExtractCurrentEntryToFilePathAsync( + zip_reader_->ExtractCurrentEntryToFilePathAsync( image_path_, base::Bind(&Operation::CompleteAndContinue, this, continuation), base::Bind(&Operation::OnUnzipFailure, this), base::Bind(&Operation::OnUnzipProgress, this, - zip_reader_.current_entry_info()->original_size())); + zip_reader_->current_entry_info()->original_size())); } void Operation::Finish() {
diff --git a/chrome/browser/extensions/api/image_writer_private/operation.h b/chrome/browser/extensions/api/image_writer_private/operation.h index f4e025d..bb0afbc2 100644 --- a/chrome/browser/extensions/api/image_writer_private/operation.h +++ b/chrome/browser/extensions/api/image_writer_private/operation.h
@@ -14,7 +14,7 @@ #include "base/task/cancelable_task_tracker.h" #include "chrome/browser/extensions/api/image_writer_private/image_writer_utility_client.h" #include "chrome/common/extensions/api/image_writer_private.h" -#include "third_party/zlib/google/zip_reader.h" + namespace image_writer_api = extensions::api::image_writer_private; @@ -22,6 +22,10 @@ class FilePath; } // namespace base +namespace zip { +class ZipReader; +} + namespace extensions { namespace image_writer { @@ -207,8 +211,10 @@ // memory here. This requires that we only do one MD5 sum at a time. base::MD5Context md5_context_; - // Zip reader for unzip operations. - zip::ZipReader zip_reader_; + // Zip reader for unzip operations. The reason for using a pointer is that we + // don't want to include zip_reader.h here which can mangle definitions in + // jni.h when included in the same file. See crbug.com/554199. + scoped_ptr<zip::ZipReader> zip_reader_; // CleanUp operations that must be run. All these functions are run on the // FILE thread.
diff --git a/chrome/browser/memory/tab_manager_web_contents_data.cc b/chrome/browser/memory/tab_manager_web_contents_data.cc index b33f220..4338a21 100644 --- a/chrome/browser/memory/tab_manager_web_contents_data.cc +++ b/chrome/browser/memory/tab_manager_web_contents_data.cc
@@ -52,14 +52,22 @@ void TabManager::WebContentsData::SetDiscardState(bool state) { if (tab_data_.is_discarded_ && !state) { static int reload_count = 0; + tab_data_.last_reload_time_ = NowTicks(); UMA_HISTOGRAM_CUSTOM_COUNTS("TabManager.Discarding.ReloadCount", ++reload_count, 1, 1000, 50); - auto delta = NowTicks() - tab_data_.last_discard_time_; + auto delta = tab_data_.last_reload_time_ - tab_data_.last_discard_time_; // Capped to one day for now, will adjust if necessary. UMA_HISTOGRAM_CUSTOM_TIMES("TabManager.Discarding.DiscardToReloadTime", delta, base::TimeDelta::FromSeconds(1), base::TimeDelta::FromDays(1), 100); - tab_data_.last_reload_time_ = NowTicks(); + + if (tab_data_.last_inactive_time_ != base::TimeTicks::UnixEpoch()) { + delta = tab_data_.last_reload_time_ - tab_data_.last_inactive_time_; + UMA_HISTOGRAM_CUSTOM_TIMES("TabManager.Discarding.InactiveToReloadTime", + delta, base::TimeDelta::FromSeconds(1), + base::TimeDelta::FromDays(1), 100); + } + } else if (!tab_data_.is_discarded_ && state) { static int discard_count = 0; UMA_HISTOGRAM_CUSTOM_COUNTS("TabManager.Discarding.DiscardCount",
diff --git a/chrome/browser/memory/tab_manager_web_contents_data_unittest.cc b/chrome/browser/memory/tab_manager_web_contents_data_unittest.cc index 69f5474..0aa9e05c 100644 --- a/chrome/browser/memory/tab_manager_web_contents_data_unittest.cc +++ b/chrome/browser/memory/tab_manager_web_contents_data_unittest.cc
@@ -184,4 +184,24 @@ histograms.ExpectBucketCount(kHistogramName, 13000, 1); } +TEST_F(TabManagerWebContentsDataTest, HistogramsInactiveToReloadTime) { + const char kHistogramName[] = "TabManager.Discarding.InactiveToReloadTime"; + + base::HistogramTester histograms; + + EXPECT_TRUE(histograms.GetTotalCountsForPrefix(kHistogramName).empty()); + + tab_data()->SetLastInactiveTime(test_clock().NowTicks()); + test_clock().Advance(base::TimeDelta::FromSeconds(5)); + tab_data()->SetDiscardState(true); + tab_data()->IncrementDiscardCount(); + test_clock().Advance(base::TimeDelta::FromSeconds(7)); + tab_data()->SetDiscardState(false); + + EXPECT_EQ(1, + histograms.GetTotalCountsForPrefix(kHistogramName).begin()->second); + + histograms.ExpectBucketCount(kHistogramName, 12000, 1); +} + } // namespace memory
diff --git a/chrome/browser/password_manager/password_manager_test_base.cc b/chrome/browser/password_manager/password_manager_test_base.cc index 2ad437a6..0a875de 100644 --- a/chrome/browser/password_manager/password_manager_test_base.cc +++ b/chrome/browser/password_manager/password_manager_test_base.cc
@@ -191,7 +191,7 @@ // PasswordStore has not completed. PasswordStoreFactory::GetInstance()->SetTestingFactory( browser()->profile(), - password_manager::BuildPasswordStoreService< + password_manager::BuildPasswordStore< content::BrowserContext, password_manager::TestPasswordStore>); ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); ASSERT_FALSE(base::CommandLine::ForCurrentProcess()->HasSwitch(
diff --git a/chrome/browser/password_manager/password_store_factory.cc b/chrome/browser/password_manager/password_store_factory.cc index 72da4bf..2048d88 100644 --- a/chrome/browser/password_manager/password_store_factory.cc +++ b/chrome/browser/password_manager/password_store_factory.cc
@@ -24,7 +24,6 @@ #include "components/password_manager/core/browser/password_store.h" #include "components/password_manager/core/browser/password_store_default.h" #include "components/password_manager/core/browser/password_store_factory_util.h" -#include "components/password_manager/core/browser/password_store_service.h" #include "components/password_manager/core/common/password_manager_pref_names.h" #include "components/pref_registry/pref_registry_syncable.h" #include "content/public/browser/browser_thread.h" @@ -66,12 +65,14 @@ scoped_refptr<PasswordStore> PasswordStoreFactory::GetForProfile( Profile* profile, ServiceAccessType access_type) { - password_manager::PasswordStoreService* service = - static_cast<password_manager::PasswordStoreService*>( - GetInstance()->GetServiceForBrowserContext(profile, true)); - - return password_manager::GetPasswordStoreFromService( - service, access_type, profile->IsOffTheRecord()); + // |profile| gets always redirected to a non-Incognito profile below, so + // Incognito & IMPLICIT_ACCESS means that incognito browsing session would + // result in traces in the normal profile without the user knowing it. + if (access_type == ServiceAccessType::IMPLICIT_ACCESS && + profile->IsOffTheRecord()) + return nullptr; + return make_scoped_refptr(static_cast<password_manager::PasswordStore*>( + GetInstance()->GetServiceForBrowserContext(profile, true).get())); } // static @@ -108,9 +109,9 @@ } PasswordStoreFactory::PasswordStoreFactory() - : BrowserContextKeyedServiceFactory( - "PasswordStore", - BrowserContextDependencyManager::GetInstance()) { + : RefcountedBrowserContextKeyedServiceFactory( + "PasswordStore", + BrowserContextDependencyManager::GetInstance()) { DependsOn(WebDataServiceFactory::GetInstance()); } @@ -138,7 +139,8 @@ } #endif -KeyedService* PasswordStoreFactory::BuildServiceInstanceFor( +scoped_refptr<RefcountedKeyedService> +PasswordStoreFactory::BuildServiceInstanceFor( content::BrowserContext* context) const { #if defined(OS_WIN) password_manager_util_win::DelayReportOsPassword(); @@ -256,10 +258,15 @@ #else NOTIMPLEMENTED(); #endif - return password_manager::BuildServiceInstanceFromStore( - ps, - sync_start_util::GetFlareForSyncableService(profile->GetPath())) - .release(); + DCHECK(ps); + if (!ps->Init( + sync_start_util::GetFlareForSyncableService(profile->GetPath()))) { + // TODO(crbug.com/479725): Remove the LOG once this error is visible in the + // UI. + LOG(WARNING) << "Could not initialize password store."; + return nullptr; + } + return ps; } void PasswordStoreFactory::RegisterProfilePrefs(
diff --git a/chrome/browser/password_manager/password_store_factory.h b/chrome/browser/password_manager/password_store_factory.h index 23037f6d..07c0246 100644 --- a/chrome/browser/password_manager/password_store_factory.h +++ b/chrome/browser/password_manager/password_store_factory.h
@@ -9,7 +9,7 @@ #include "base/basictypes.h" #include "base/memory/singleton.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" +#include "components/keyed_service/content/refcounted_browser_context_keyed_service_factory.h" #include "components/keyed_service/core/service_access_type.h" #if defined(USE_X11) @@ -32,7 +32,8 @@ // Singleton that owns all PasswordStores and associates them with // Profiles. -class PasswordStoreFactory : public BrowserContextKeyedServiceFactory { +class PasswordStoreFactory + : public RefcountedBrowserContextKeyedServiceFactory { public: static scoped_refptr<password_manager::PasswordStore> GetForProfile( Profile* profile, @@ -58,8 +59,8 @@ LocalProfileId GetLocalProfileId(PrefService* prefs) const; #endif - // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( + // RefcountedBrowserContextKeyedServiceFactory: + scoped_refptr<RefcountedKeyedService> BuildServiceInstanceFor( content::BrowserContext* context) const override; void RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) override;
diff --git a/chrome/browser/password_manager/password_store_mac_unittest.cc b/chrome/browser/password_manager/password_store_mac_unittest.cc index fb73ec0..996adef 100644 --- a/chrome/browser/password_manager/password_store_mac_unittest.cc +++ b/chrome/browser/password_manager/password_store_mac_unittest.cc
@@ -1231,7 +1231,7 @@ if (!store_) return; - store_->Shutdown(); + store_->ShutdownOnUIThread(); store_ = nullptr; }
diff --git a/chrome/browser/password_manager/password_store_proxy_mac.cc b/chrome/browser/password_manager/password_store_proxy_mac.cc index ecbf1a6..34e6079 100644 --- a/chrome/browser/password_manager/password_store_proxy_mac.cc +++ b/chrome/browser/password_manager/password_store_proxy_mac.cc
@@ -56,9 +56,9 @@ static_cast<MigrationStatus>(migration_status_.GetValue()))); } -void PasswordStoreProxyMac::Shutdown() { +void PasswordStoreProxyMac::ShutdownOnUIThread() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - PasswordStore::Shutdown(); + PasswordStore::ShutdownOnUIThread(); thread_->Stop(); // Execute the task which are still pending. @@ -71,7 +71,7 @@ // another. GetBackend() returns the correct result. // The backend doesn't need the background thread as PasswordStore::Init() and // other public methods were never called on it. - GetBackend()->Shutdown(); + GetBackend()->ShutdownOnUIThread(); } scoped_refptr<base::SingleThreadTaskRunner> @@ -106,8 +106,8 @@ status = MigrationStatus::MIGRATED; // Switch from |password_store_mac_| to |password_store_simple_|. password_store_mac_->set_login_metadata_db(nullptr); - pending_ui_tasks_.push_back( - base::Bind(&PasswordStoreMac::Shutdown, password_store_mac_)); + pending_ui_tasks_.push_back(base::Bind( + &PasswordStoreMac::ShutdownOnUIThread, password_store_mac_)); password_store_mac_ = nullptr; DCHECK(!password_store_simple_); password_store_simple_ = new SimplePasswordStoreMac(
diff --git a/chrome/browser/password_manager/password_store_proxy_mac.h b/chrome/browser/password_manager/password_store_proxy_mac.h index 10e08eb..c2b57998 100644 --- a/chrome/browser/password_manager/password_store_proxy_mac.h +++ b/chrome/browser/password_manager/password_store_proxy_mac.h
@@ -38,7 +38,7 @@ PrefService* prefs); bool Init(const syncer::SyncableService::StartSyncFlare& flare) override; - void Shutdown() override; + void ShutdownOnUIThread() override; scoped_refptr<base::SingleThreadTaskRunner> GetBackgroundTaskRunner() override;
diff --git a/chrome/browser/password_manager/password_store_proxy_mac_unittest.cc b/chrome/browser/password_manager/password_store_proxy_mac_unittest.cc index cab284ce..204c9c7 100644 --- a/chrome/browser/password_manager/password_store_proxy_mac_unittest.cc +++ b/chrome/browser/password_manager/password_store_proxy_mac_unittest.cc
@@ -163,7 +163,7 @@ void PasswordStoreProxyMacTest::ClosePasswordStore() { if (!store_) return; - store_->Shutdown(); + store_->ShutdownOnUIThread(); EXPECT_FALSE(store_->GetBackgroundTaskRunner()); store_ = nullptr; } @@ -257,9 +257,9 @@ // ----------- Tests ------------- TEST_P(PasswordStoreProxyMacTest, StartAndStop) { - // PasswordStore::Shutdown() immediately follows PasswordStore::Init(). The - // message loop isn't running in between. Anyway, PasswordStore should end up - // in the right state. + // PasswordStore::ShutdownOnUIThread() immediately follows + // PasswordStore::Init(). The message loop isn't running in between. Anyway, + // PasswordStore should end up in the right state. ClosePasswordStore(); int status = testing_prefs_.GetInteger(
diff --git a/chrome/browser/password_manager/password_store_win.cc b/chrome/browser/password_manager/password_store_win.cc index fdb887d..db9076f 100644 --- a/chrome/browser/password_manager/password_store_win.cc +++ b/chrome/browser/password_manager/password_store_win.cc
@@ -68,7 +68,7 @@ scoped_refptr<PasswordWebDataService> web_data_service_; // This creates a cycle between us and PasswordStore. The cycle is broken - // from PasswordStoreWin::Shutdown, which deletes us. + // from PasswordStoreWin::ShutdownOnUIThread, which deletes us. scoped_refptr<PasswordStoreWin> password_store_; PendingRequestMap pending_requests_; @@ -186,11 +186,11 @@ db_handler_.reset(); } -void PasswordStoreWin::Shutdown() { +void PasswordStoreWin::ShutdownOnUIThread() { BrowserThread::PostTask( BrowserThread::DB, FROM_HERE, base::Bind(&PasswordStoreWin::ShutdownOnDBThread, this)); - PasswordStoreDefault::Shutdown(); + PasswordStoreDefault::ShutdownOnUIThread(); } void PasswordStoreWin::GetLoginsImpl(const PasswordForm& form,
diff --git a/chrome/browser/password_manager/password_store_win.h b/chrome/browser/password_manager/password_store_win.h index 3501b2e..6287177 100644 --- a/chrome/browser/password_manager/password_store_win.h +++ b/chrome/browser/password_manager/password_store_win.h
@@ -32,14 +32,14 @@ const scoped_refptr<PasswordWebDataService>& web_data_service); // PasswordStore: - void Shutdown() override; + void ShutdownOnUIThread() override; private: class DBHandler; ~PasswordStoreWin() override; - // Invoked from Shutdown, but run on the DB thread. + // Invoked from ShutdownOnUIThread, but run on the DB thread. void ShutdownOnDBThread(); // password_manager::PasswordStore:
diff --git a/chrome/browser/password_manager/password_store_win_unittest.cc b/chrome/browser/password_manager/password_store_win_unittest.cc index 4f82876..16208a7 100644 --- a/chrome/browser/password_manager/password_store_win_unittest.cc +++ b/chrome/browser/password_manager/password_store_win_unittest.cc
@@ -137,7 +137,7 @@ void TearDown() override { if (store_.get()) - store_->Shutdown(); + store_->ShutdownOnUIThread(); wds_->ShutdownOnUIThread(); wdbs_->ShutdownDatabase(); wds_ = nullptr; @@ -285,7 +285,7 @@ store_->GetLogins(*form, PasswordStore::DISALLOW_PROMPT, &consumer); // Release the PSW and the WDS before the query can return. - store_->Shutdown(); + store_->ShutdownOnUIThread(); store_ = nullptr; wds_ = nullptr;
diff --git a/chrome/browser/password_manager/password_store_x_unittest.cc b/chrome/browser/password_manager/password_store_x_unittest.cc index 9567d82b..2c2a16c 100644 --- a/chrome/browser/password_manager/password_store_x_unittest.cc +++ b/chrome/browser/password_manager/password_store_x_unittest.cc
@@ -375,7 +375,7 @@ store->RemoveObserver(&observer); - store->Shutdown(); + store->ShutdownOnUIThread(); } TEST_P(PasswordStoreXTest, NativeMigration) { @@ -478,7 +478,7 @@ EXPECT_EQ(db_file_start_info.size, db_file_end_info.size); } - store->Shutdown(); + store->ShutdownOnUIThread(); } INSTANTIATE_TEST_CASE_P(NoBackend,
diff --git a/chrome/browser/password_manager/simple_password_store_mac_unittest.cc b/chrome/browser/password_manager/simple_password_store_mac_unittest.cc index 4e82e06..26f459b 100644 --- a/chrome/browser/password_manager/simple_password_store_mac_unittest.cc +++ b/chrome/browser/password_manager/simple_password_store_mac_unittest.cc
@@ -61,7 +61,7 @@ } void TearDown() override { - store_->Shutdown(); + store_->ShutdownOnUIThread(); EXPECT_TRUE(store_->GetBackgroundTaskRunner()); store_ = nullptr; }
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc index db32c9f..b5220e0 100644 --- a/chrome/browser/policy/policy_browsertest.cc +++ b/chrome/browser/policy/policy_browsertest.cc
@@ -2915,9 +2915,9 @@ Mock::VerifyAndClearExpectations(&observer); } -// Disabled, see http://crbug.com/315308. +// Disabled, see http://crbug.com/554728. IN_PROC_BROWSER_TEST_F(PolicyTest, - DISABLED_PRE_WaitForInitialUserActivityUsatisfied) { + DISABLED_PRE_WaitForInitialUserActivityUnsatisfied) { // Indicate that the session started 2 hours ago and no user activity has // occurred yet. g_browser_process->local_state()->SetInt64( @@ -2926,9 +2926,9 @@ .ToInternalValue()); } -// Disabled, see http://crbug.com/315308. +// Disabled, see http://crbug.com/554728. IN_PROC_BROWSER_TEST_F(PolicyTest, - DISABLED_WaitForInitialUserActivityUsatisfied) { + DISABLED_WaitForInitialUserActivityUnsatisfied) { content::MockNotificationObserver observer; content::NotificationRegistrar registrar; registrar.Add(&observer,
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index 32950be7..90a75997 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -141,8 +141,8 @@ #include "chrome/browser/android/bookmarks/partner_bookmarks_shim.h" #include "chrome/browser/android/most_visited_sites.h" #include "chrome/browser/android/new_tab_page_prefs.h" +#include "chrome/browser/android/popular_sites.h" #else -#include "chrome/browser/profile_resetter/automatic_profile_resetter_factory.h" #include "chrome/browser/ui/startup/startup_browser_creator.h" #include "chrome/browser/upgrade_detector.h" #endif @@ -289,7 +289,6 @@ #endif // defined(ENABLE_TASK_MANAGER) #if !defined(OS_ANDROID) - AutomaticProfileResetterFactory::RegisterPrefs(registry); BackgroundModeManager::RegisterPrefs(registry); ChromeTracingDelegate::RegisterPrefs(registry); RegisterBrowserPrefs(registry); @@ -458,6 +457,7 @@ MostVisitedSites::RegisterProfilePrefs(registry); NewTabPagePrefs::RegisterProfilePrefs(registry); PartnerBookmarksShim::RegisterProfilePrefs(registry); + PopularSites::RegisterProfilePrefs(registry); #else AppShortcutManager::RegisterProfilePrefs(registry); DeviceIDFetcher::RegisterProfilePrefs(registry);
diff --git a/chrome/browser/prefs/chrome_pref_service_factory.cc b/chrome/browser/prefs/chrome_pref_service_factory.cc index fc2dcc8..4b313f43 100644 --- a/chrome/browser/prefs/chrome_pref_service_factory.cc +++ b/chrome/browser/prefs/chrome_pref_service_factory.cc
@@ -166,12 +166,6 @@ PrefHashFilter::TRACKING_STRATEGY_ATOMIC, PrefHashFilter::VALUE_IMPERSONAL }, - { - 13, prefs::kProfileResetPromptMementoInProfilePrefs, - PrefHashFilter::ENFORCE_ON_LOAD, - PrefHashFilter::TRACKING_STRATEGY_ATOMIC, - PrefHashFilter::VALUE_IMPERSONAL - }, #endif { 14, DefaultSearchManager::kDefaultSearchProviderDataPrefName,
diff --git a/chrome/browser/profile_resetter/automatic_profile_resetter.cc b/chrome/browser/profile_resetter/automatic_profile_resetter.cc deleted file mode 100644 index 9386b27..0000000 --- a/chrome/browser/profile_resetter/automatic_profile_resetter.cc +++ /dev/null
@@ -1,764 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/profile_resetter/automatic_profile_resetter.h" - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/logging.h" -#include "base/memory/ref_counted.h" -#include "base/metrics/field_trial.h" -#include "base/metrics/histogram.h" -#include "base/metrics/sparse_histogram.h" -#include "base/prefs/pref_service.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_util.h" -#include "base/task_runner.h" -#include "base/task_runner_util.h" -#include "base/threading/sequenced_worker_pool.h" -#include "base/time/time.h" -#include "base/timer/elapsed_timer.h" -#include "base/values.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/profile_resetter/automatic_profile_resetter_delegate.h" -#include "chrome/browser/profile_resetter/jtl_interpreter.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/search_engines/template_url_service_factory.h" -#include "components/search_engines/template_url_service.h" -#include "components/variations/variations_associated_data.h" -#include "content/public/browser/browser_thread.h" -#include "grit/browser_resources.h" -#include "ui/base/resource/resource_bundle.h" - - -// Helpers ------------------------------------------------------------------- - -namespace { - -// Name constants for the field trial behind which we enable this feature. -const char kAutomaticProfileResetStudyName[] = "AutomaticProfileReset"; -const char kAutomaticProfileResetStudyDryRunGroupName[] = "DryRun"; -const char kAutomaticProfileResetStudyEnabledGroupName[] = "Enabled"; -#if defined(GOOGLE_CHROME_BUILD) -const char kAutomaticProfileResetStudyProgramParameterName[] = "program"; -const char kAutomaticProfileResetStudyHashSeedParameterName[] = "hash_seed"; -#endif - -// How long to wait after start-up before unleashing the evaluation flow. -const int64 kEvaluationFlowDelayInSeconds = 55; - -// Keys used in the input dictionary of the program. -const char kDefaultSearchProviderKey[] = "default_search_provider"; -const char kDefaultSearchProviderIsUserControlledKey[] = - "default_search_provider_iuc"; -const char kLoadedModuleDigestsKey[] = "loaded_modules"; -const char kLocalStateKey[] = "local_state"; -const char kLocalStateIsUserControlledKey[] = "local_state_iuc"; -const char kSearchProvidersKey[] = "search_providers"; -const char kUserPreferencesKey[] = "preferences"; -const char kUserPreferencesIsUserControlledKey[] = "preferences_iuc"; - -// Keys used in the output dictionary of the program. -const char kCombinedStatusMaskKeyPrefix[] = "combined_status_mask_bit"; -const char kHadPromptedAlreadyKey[] = "had_prompted_already"; -const char kShouldPromptKey[] = "should_prompt"; -const char kSatisfiedCriteriaMaskKeyPrefix[] = "satisfied_criteria_mask_bit"; - -// Keys used in both the input and output dictionary of the program. -const char kMementoValueInFileKey[] = "memento_value_in_file"; -const char kMementoValueInLocalStateKey[] = "memento_value_in_local_state"; -const char kMementoValueInPrefsKey[] = "memento_value_in_prefs"; - -// Number of bits, and maximum value (exclusive) for the mask whose bits -// indicate which of reset criteria were satisfied. -const size_t kSatisfiedCriteriaMaskNumberOfBits = 5u; -const uint32 kSatisfiedCriteriaMaskMaximumValue = - (1u << kSatisfiedCriteriaMaskNumberOfBits); - -// Number of bits, and maximum value (exclusive) for the mask whose bits -// indicate if any of reset criteria were satisfied, and which of the mementos -// were already present. -const size_t kCombinedStatusMaskNumberOfBits = 4u; -const uint32 kCombinedStatusMaskMaximumValue = - (1u << kCombinedStatusMaskNumberOfBits); - -// Returns whether or not a dry-run shall be performed. -bool ShouldPerformDryRun() { - return base::StartsWith( - base::FieldTrialList::FindFullName(kAutomaticProfileResetStudyName), - kAutomaticProfileResetStudyDryRunGroupName, base::CompareCase::SENSITIVE); -} - -// Returns whether or not a live-run shall be performed. -bool ShouldPerformLiveRun() { - return base::StartsWith( - base::FieldTrialList::FindFullName(kAutomaticProfileResetStudyName), - kAutomaticProfileResetStudyEnabledGroupName, - base::CompareCase::SENSITIVE); -} - -// If the currently active experiment group prescribes a |program| and -// |hash_seed| to use instead of the baked-in ones, retrieves those and returns -// true. Otherwise, returns false. -bool GetProgramAndHashSeedOverridesFromExperiment(std::string* program, - std::string* hash_seed) { - DCHECK(program); - DCHECK(hash_seed); -#if defined(GOOGLE_CHROME_BUILD) - std::map<std::string, std::string> params; - variations::GetVariationParams(kAutomaticProfileResetStudyName, ¶ms); - if (params.count(kAutomaticProfileResetStudyProgramParameterName) && - params.count(kAutomaticProfileResetStudyHashSeedParameterName)) { - program->swap(params[kAutomaticProfileResetStudyProgramParameterName]); - hash_seed->swap(params[kAutomaticProfileResetStudyHashSeedParameterName]); - return true; - } -#endif - return false; -} - -// Takes |pref_name_to_value_map|, which shall be a deep-copy of all preferences -// in |source| without path expansion; and (1.) creates a sub-tree from it named -// |value_tree_key| in |target_dictionary| with path expansion, and (2.) also -// creates an isomorphic sub-tree under the key |is_user_controlled_tree_key| -// that contains only Boolean values indicating whether or not the corresponding -// preference is coming from the 'user' PrefStore. -void BuildSubTreesFromPreferences( - scoped_ptr<base::DictionaryValue> pref_name_to_value_map, - const PrefService* source, - const char* value_tree_key, - const char* is_user_controlled_tree_key, - base::DictionaryValue* target_dictionary) { - std::vector<std::string> pref_names; - pref_names.reserve(pref_name_to_value_map->size()); - for (base::DictionaryValue::Iterator it(*pref_name_to_value_map); - !it.IsAtEnd(); it.Advance()) - pref_names.push_back(it.key()); - - base::DictionaryValue* value_tree = new base::DictionaryValue; - base::DictionaryValue* is_user_controlled_tree = new base::DictionaryValue; - for (std::vector<std::string>::const_iterator it = pref_names.begin(); - it != pref_names.end(); ++it) { - scoped_ptr<base::Value> pref_value_owned; - if (pref_name_to_value_map->RemoveWithoutPathExpansion(*it, - &pref_value_owned)) { - value_tree->Set(*it, pref_value_owned.release()); - const PrefService::Preference* pref = source->FindPreference(it->c_str()); - is_user_controlled_tree->Set( - *it, new base::FundamentalValue(pref->IsUserControlled())); - } - } - target_dictionary->Set(value_tree_key, value_tree); - target_dictionary->Set(is_user_controlled_tree_key, is_user_controlled_tree); -} - -} // namespace - - -// AutomaticProfileResetter::InputBuilder ------------------------------------ - -// Collects all the information that is required by the evaluator program to -// assess whether or not the conditions for showing the reset prompt are met. -// -// This necessitates a lot of work that has to be performed on the UI thread, -// such as: accessing the Preferences, Local State, and TemplateURLService. -// In order to keep the browser responsive, the UI thread shall not be blocked -// for long consecutive periods of time. Unfortunately, we cannot reduce the -// total amount of work. Instead, what this class does is to split the work into -// shorter tasks that are posted one-at-a-time to the UI thread in a serial -// fashion, so as to give a chance to run other tasks that have accumulated in -// the meantime. -class AutomaticProfileResetter::InputBuilder - : public base::SupportsWeakPtr<InputBuilder> { - public: - typedef base::Callback<void(scoped_ptr<base::DictionaryValue>)> - ProgramInputCallback; - - // The dependencies must have been initialized through |delegate|, i.e. the - // RequestCallback[...] methods must have already fired before calling this. - InputBuilder(Profile* profile, AutomaticProfileResetterDelegate* delegate) - : profile_(profile), - delegate_(delegate), - memento_in_prefs_(profile_), - memento_in_local_state_(profile_), - memento_in_file_(profile_) {} - ~InputBuilder() {} - - // Assembles the data required by the evaluator program into a dictionary - // format, and posts it back to the UI thread with |callback| once ready. In - // order not to block the UI thread for long consecutive periods of time, the - // work is divided into smaller tasks, see class comment above for details. - // It is safe to destroy |this| immediately from within the |callback|. - void BuildEvaluatorProgramInput(const ProgramInputCallback& callback) { - DCHECK(!data_); - DCHECK(!callback.is_null()); - data_.reset(new base::DictionaryValue); - callback_ = callback; - - AddAsyncTask(base::Bind(&InputBuilder::IncludeMementoValues, AsWeakPtr())); - AddTask(base::Bind(&InputBuilder::IncludeUserPreferences, AsWeakPtr())); - AddTask(base::Bind(&InputBuilder::IncludeLocalState, AsWeakPtr())); - AddTask(base::Bind(&InputBuilder::IncludeSearchEngines, AsWeakPtr())); - AddTask(base::Bind(&InputBuilder::IncludeLoadedModules, AsWeakPtr())); - - // Each task will post the next one. Just trigger the chain reaction. - PostNextTask(); - } - - private: - // Asynchronous task that includes memento values (or empty strings in case - // mementos are not there). - void IncludeMementoValues() { - data_->SetString(kMementoValueInPrefsKey, memento_in_prefs_.ReadValue()); - data_->SetString(kMementoValueInLocalStateKey, - memento_in_local_state_.ReadValue()); - memento_in_file_.ReadValue(base::Bind( - &InputBuilder::IncludeFileBasedMementoCallback, AsWeakPtr())); - } - - // Called back by |memento_in_file_| once the |memento_value| has been read. - void IncludeFileBasedMementoCallback(const std::string& memento_value) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - data_->SetString(kMementoValueInFileKey, memento_value); - // As an asynchronous task, we need to take care of posting the next task. - PostNextTask(); - } - - // Task that includes all user (i.e. profile-specific) preferences, along with - // information about whether the value is coming from the 'user' PrefStore. - // This is the most expensive operation, so it is itself split into two parts. - void IncludeUserPreferences() { - PrefService* prefs = profile_->GetPrefs(); - DCHECK(prefs); - scoped_ptr<base::DictionaryValue> pref_name_to_value_map( - prefs->GetPreferenceValuesWithoutPathExpansion()); - AddTask(base::Bind(&InputBuilder::IncludeUserPreferencesPartTwo, - AsWeakPtr(), - base::Passed(&pref_name_to_value_map))); - } - - // Second part to above. - void IncludeUserPreferencesPartTwo( - scoped_ptr<base::DictionaryValue> pref_name_to_value_map) { - PrefService* prefs = profile_->GetPrefs(); - DCHECK(prefs); - BuildSubTreesFromPreferences( - pref_name_to_value_map.Pass(), - prefs, - kUserPreferencesKey, - kUserPreferencesIsUserControlledKey, - data_.get()); - } - - // Task that includes all local state (i.e. shared) preferences, along with - // information about whether the value is coming from the 'user' PrefStore. - void IncludeLocalState() { - PrefService* local_state = g_browser_process->local_state(); - DCHECK(local_state); - scoped_ptr<base::DictionaryValue> pref_name_to_value_map( - local_state->GetPreferenceValuesWithoutPathExpansion()); - BuildSubTreesFromPreferences( - pref_name_to_value_map.Pass(), - local_state, - kLocalStateKey, - kLocalStateIsUserControlledKey, - data_.get()); - } - - // Task that includes all information related to search engines. - void IncludeSearchEngines() { - scoped_ptr<base::DictionaryValue> default_search_provider_details( - delegate_->GetDefaultSearchProviderDetails()); - data_->Set(kDefaultSearchProviderKey, - default_search_provider_details.release()); - - scoped_ptr<base::ListValue> search_providers_details( - delegate_->GetPrepopulatedSearchProvidersDetails()); - data_->Set(kSearchProvidersKey, search_providers_details.release()); - - data_->SetBoolean(kDefaultSearchProviderIsUserControlledKey, - !delegate_->IsDefaultSearchProviderManaged()); - } - - // Task that includes information about loaded modules. - void IncludeLoadedModules() { - scoped_ptr<base::ListValue> loaded_module_digests( - delegate_->GetLoadedModuleNameDigests()); - data_->Set(kLoadedModuleDigestsKey, loaded_module_digests.release()); - } - - // ------------------------------------------------------------------------- - - // Adds a |task| that can do as much asynchronous processing as it wants, but - // will need to finally call PostNextTask() on the UI thread when done. - void AddAsyncTask(const base::Closure& task) { - task_queue_.push(task); - } - - // Convenience wrapper for synchronous tasks. - void SynchronousTaskWrapper(const base::Closure& task) { - base::ElapsedTimer timer; - task.Run(); - UMA_HISTOGRAM_CUSTOM_TIMES( - "AutomaticProfileReset.InputBuilder.TaskDuration", - timer.Elapsed(), - base::TimeDelta::FromMilliseconds(1), - base::TimeDelta::FromSeconds(2), - 50); - PostNextTask(); - } - - // Adds a task that needs to finish synchronously. In exchange, PostNextTask() - // is called automatically when the |task| returns, and execution time is - // measured. - void AddTask(const base::Closure& task) { - task_queue_.push( - base::Bind(&InputBuilder::SynchronousTaskWrapper, AsWeakPtr(), task)); - } - - // Posts the next task from the |task_queue_|, unless it is exhausted, in - // which case it posts |callback_| to return with the results. - void PostNextTask() { - base::Closure next_task; - if (task_queue_.empty()) { - next_task = base::Bind(callback_, base::Passed(&data_)); - } else { - next_task = task_queue_.front(); - task_queue_.pop(); - } - content::BrowserThread::PostTask( - content::BrowserThread::UI, FROM_HERE, next_task); - } - - Profile* profile_; - AutomaticProfileResetterDelegate* delegate_; - ProgramInputCallback callback_; - - PreferenceHostedPromptMemento memento_in_prefs_; - LocalStateHostedPromptMemento memento_in_local_state_; - FileHostedPromptMemento memento_in_file_; - - scoped_ptr<base::DictionaryValue> data_; - std::queue<base::Closure> task_queue_; - - DISALLOW_COPY_AND_ASSIGN(InputBuilder); -}; - - -// AutomaticProfileResetter::EvaluationResults ------------------------------- - -// Encapsulates the output values extracted from the evaluator program. -struct AutomaticProfileResetter::EvaluationResults { - EvaluationResults() - : should_prompt(false), - had_prompted_already(false), - satisfied_criteria_mask(0), - combined_status_mask(0) {} - - std::string memento_value_in_prefs; - std::string memento_value_in_local_state; - std::string memento_value_in_file; - - bool should_prompt; - bool had_prompted_already; - uint32 satisfied_criteria_mask; - uint32 combined_status_mask; -}; - - -// AutomaticProfileResetter -------------------------------------------------- - -AutomaticProfileResetter::AutomaticProfileResetter(Profile* profile) - : profile_(profile), - state_(STATE_UNINITIALIZED), - enumeration_of_loaded_modules_ready_(false), - template_url_service_ready_(false), - has_already_dismissed_prompt_(false), - should_show_reset_banner_(false), - weak_ptr_factory_(this) { - DCHECK(profile_); -} - -AutomaticProfileResetter::~AutomaticProfileResetter() {} - -void AutomaticProfileResetter::Initialize() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK_EQ(state_, STATE_UNINITIALIZED); - - if (!ShouldPerformDryRun() && !ShouldPerformLiveRun()) { - state_ = STATE_DISABLED; - return; - } - - if (!GetProgramAndHashSeedOverridesFromExperiment(&program_, &hash_seed_)) { - ui::ResourceBundle& resources(ui::ResourceBundle::GetSharedInstance()); - if (ShouldPerformLiveRun()) { - program_ = resources.GetRawDataResource( - IDR_AUTOMATIC_PROFILE_RESET_RULES).as_string(); - hash_seed_ = resources.GetRawDataResource( - IDR_AUTOMATIC_PROFILE_RESET_HASH_SEED).as_string(); - } else { // ShouldPerformDryRun() - program_ = resources.GetRawDataResource( - IDR_AUTOMATIC_PROFILE_RESET_RULES_DRY).as_string(); - hash_seed_ = resources.GetRawDataResource( - IDR_AUTOMATIC_PROFILE_RESET_HASH_SEED_DRY).as_string(); - } - } - - delegate_.reset(new AutomaticProfileResetterDelegateImpl( - profile_, ProfileResetter::ALL)); - task_runner_for_waiting_ = - content::BrowserThread::GetMessageLoopProxyForThread( - content::BrowserThread::UI); - - state_ = STATE_INITIALIZED; -} - -void AutomaticProfileResetter::Activate() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK(state_ == STATE_INITIALIZED || state_ == STATE_DISABLED); - - if (state_ == STATE_INITIALIZED) { - if (!program_.empty()) { - // Some steps in the flow (e.g. loaded modules, file-based memento) are - // IO-intensive, so defer execution until some time later. - task_runner_for_waiting_->PostDelayedTask( - FROM_HERE, - base::Bind(&AutomaticProfileResetter::PrepareEvaluationFlow, - weak_ptr_factory_.GetWeakPtr()), - base::TimeDelta::FromSeconds(kEvaluationFlowDelayInSeconds)); - } else { - // Terminate early if there is no program included (nor set by tests). - state_ = STATE_DISABLED; - } - } -} - -void AutomaticProfileResetter::TriggerProfileReset(bool send_feedback) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK_EQ(state_, STATE_HAS_SHOWN_BUBBLE); - - state_ = STATE_PERFORMING_RESET; - should_show_reset_banner_ = false; - - ReportPromptResult(PROMPT_ACTION_RESET); - delegate_->TriggerProfileSettingsReset( - send_feedback, - base::Bind(&AutomaticProfileResetter::OnProfileSettingsResetCompleted, - weak_ptr_factory_.GetWeakPtr())); -} - -void AutomaticProfileResetter::SkipProfileReset() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK_EQ(state_, STATE_HAS_SHOWN_BUBBLE); - - should_show_reset_banner_ = false; - - ReportPromptResult(PROMPT_ACTION_NO_RESET); - delegate_->DismissPrompt(); - FinishResetPromptFlow(); -} - -bool AutomaticProfileResetter::IsResetPromptFlowActive() const { - return state_ == STATE_HAS_TRIGGERED_PROMPT || - state_ == STATE_HAS_SHOWN_BUBBLE; -} - -bool AutomaticProfileResetter::ShouldShowResetBanner() const { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - return should_show_reset_banner_ && ShouldPerformLiveRun(); -} - -void AutomaticProfileResetter::NotifyDidShowResetBubble() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK_EQ(state_, STATE_HAS_TRIGGERED_PROMPT); - - state_ = STATE_HAS_SHOWN_BUBBLE; - - PersistMementos(); - ReportPromptResult(PROMPT_SHOWN_BUBBLE); -} - -void AutomaticProfileResetter::NotifyDidOpenWebUIResetDialog() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - // This notification is invoked unconditionally by the WebUI, only care about - // it when the prompt flow is currently active (and not yet resetting). - if (state_ == STATE_HAS_TRIGGERED_PROMPT || - state_ == STATE_HAS_SHOWN_BUBBLE) { - has_already_dismissed_prompt_ = true; - delegate_->DismissPrompt(); - } -} - -void AutomaticProfileResetter::NotifyDidCloseWebUIResetDialog( - bool performed_reset) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - // This notification is invoked unconditionally by the WebUI, only care about - // it when the prompt flow is currently active (and not yet resetting). - if (state_ == STATE_HAS_TRIGGERED_PROMPT || - state_ == STATE_HAS_SHOWN_BUBBLE) { - if (!has_already_dismissed_prompt_) - delegate_->DismissPrompt(); - if (state_ == STATE_HAS_TRIGGERED_PROMPT) { - PersistMementos(); - ReportPromptResult(performed_reset ? - PROMPT_NOT_SHOWN_BUBBLE_BUT_HAD_WEBUI_RESET : - PROMPT_NOT_SHOWN_BUBBLE_BUT_HAD_WEBUI_NO_RESET); - } else { // if (state_ == STATE_HAS_SHOWN_PROMPT) - ReportPromptResult(performed_reset ? - PROMPT_FOLLOWED_BY_WEBUI_RESET : - PROMPT_FOLLOWED_BY_WEBUI_NO_RESET); - } - FinishResetPromptFlow(); - } -} - -void AutomaticProfileResetter::NotifyDidCloseWebUIResetBanner() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - should_show_reset_banner_ = false; -} - -void AutomaticProfileResetter::SetProgramForTesting( - const std::string& program) { - program_ = program; -} - -void AutomaticProfileResetter::SetHashSeedForTesting( - const std::string& hash_key) { - hash_seed_ = hash_key; -} - -void AutomaticProfileResetter::SetDelegateForTesting( - scoped_ptr<AutomaticProfileResetterDelegate> delegate) { - delegate_ = delegate.Pass(); -} - -void AutomaticProfileResetter::SetTaskRunnerForWaitingForTesting( - const scoped_refptr<base::TaskRunner>& task_runner) { - task_runner_for_waiting_ = task_runner; -} - -void AutomaticProfileResetter::Shutdown() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - // We better not do anything substantial at this point. The metrics service - // has already been shut down; and local state has already been commited to - // file (in the regular fashion) for the last time. - - state_ = STATE_DISABLED; - - weak_ptr_factory_.InvalidateWeakPtrs(); - delegate_.reset(); -} - -void AutomaticProfileResetter::PrepareEvaluationFlow() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK_EQ(state_, STATE_INITIALIZED); - - state_ = STATE_WAITING_ON_DEPENDENCIES; - - delegate_->RequestCallbackWhenTemplateURLServiceIsLoaded( - base::Bind(&AutomaticProfileResetter::OnTemplateURLServiceIsLoaded, - weak_ptr_factory_.GetWeakPtr())); - delegate_->RequestCallbackWhenLoadedModulesAreEnumerated( - base::Bind(&AutomaticProfileResetter::OnLoadedModulesAreEnumerated, - weak_ptr_factory_.GetWeakPtr())); - delegate_->LoadTemplateURLServiceIfNeeded(); - delegate_->EnumerateLoadedModulesIfNeeded(); -} - -void AutomaticProfileResetter::OnTemplateURLServiceIsLoaded() { - template_url_service_ready_ = true; - OnDependencyIsReady(); -} - -void AutomaticProfileResetter::OnLoadedModulesAreEnumerated() { - enumeration_of_loaded_modules_ready_ = true; - OnDependencyIsReady(); -} - -void AutomaticProfileResetter::OnDependencyIsReady() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK_EQ(state_, STATE_WAITING_ON_DEPENDENCIES); - - if (template_url_service_ready_ && enumeration_of_loaded_modules_ready_) { - state_ = STATE_READY; - content::BrowserThread::PostTask( - content::BrowserThread::UI, - FROM_HERE, - base::Bind(&AutomaticProfileResetter::BeginEvaluationFlow, - weak_ptr_factory_.GetWeakPtr())); - } -} - -void AutomaticProfileResetter::BeginEvaluationFlow() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK_EQ(state_, STATE_READY); - DCHECK(!program_.empty()); - DCHECK(!input_builder_); - - state_ = STATE_EVALUATING_CONDITIONS; - - input_builder_.reset(new InputBuilder(profile_, delegate_.get())); - input_builder_->BuildEvaluatorProgramInput( - base::Bind(&AutomaticProfileResetter::ContinueWithEvaluationFlow, - weak_ptr_factory_.GetWeakPtr())); -} - -void AutomaticProfileResetter::ContinueWithEvaluationFlow( - scoped_ptr<base::DictionaryValue> program_input) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK_EQ(state_, STATE_EVALUATING_CONDITIONS); - - input_builder_.reset(); - - base::SequencedWorkerPool* blocking_pool = - content::BrowserThread::GetBlockingPool(); - scoped_refptr<base::TaskRunner> task_runner = - blocking_pool->GetTaskRunnerWithShutdownBehavior( - base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); - - base::PostTaskAndReplyWithResult( - task_runner.get(), - FROM_HERE, - base::Bind(&EvaluateConditionsOnWorkerPoolThread, - hash_seed_, - program_, - base::Passed(&program_input)), - base::Bind(&AutomaticProfileResetter::FinishEvaluationFlow, - weak_ptr_factory_.GetWeakPtr())); -} - -// static -scoped_ptr<AutomaticProfileResetter::EvaluationResults> - AutomaticProfileResetter::EvaluateConditionsOnWorkerPoolThread( - const std::string& hash_seed, - const std::string& program, - scoped_ptr<base::DictionaryValue> program_input) { - JtlInterpreter interpreter(hash_seed, program, program_input.get()); - interpreter.Execute(); - UMA_HISTOGRAM_ENUMERATION("AutomaticProfileReset.InterpreterResult", - interpreter.result(), - JtlInterpreter::RESULT_MAX); - UMA_HISTOGRAM_SPARSE_SLOWLY("AutomaticProfileReset.ProgramChecksum", - interpreter.CalculateProgramChecksum()); - - // In each case below, the respective field in result originally contains the - // default, so if the getter fails, we still have the correct value there. - scoped_ptr<EvaluationResults> results(new EvaluationResults); - interpreter.GetOutputBoolean(kShouldPromptKey, &results->should_prompt); - interpreter.GetOutputBoolean(kHadPromptedAlreadyKey, - &results->had_prompted_already); - interpreter.GetOutputString(kMementoValueInPrefsKey, - &results->memento_value_in_prefs); - interpreter.GetOutputString(kMementoValueInLocalStateKey, - &results->memento_value_in_local_state); - interpreter.GetOutputString(kMementoValueInFileKey, - &results->memento_value_in_file); - for (size_t i = 0; i < kCombinedStatusMaskNumberOfBits; ++i) { - bool flag = false; - std::string mask_i_th_bit_key = - kCombinedStatusMaskKeyPrefix + base::SizeTToString(i + 1); - if (interpreter.GetOutputBoolean(mask_i_th_bit_key, &flag) && flag) - results->combined_status_mask |= (1 << i); - } - for (size_t i = 0; i < kSatisfiedCriteriaMaskNumberOfBits; ++i) { - bool flag = false; - std::string mask_i_th_bit_key = - kSatisfiedCriteriaMaskKeyPrefix + base::SizeTToString(i + 1); - if (interpreter.GetOutputBoolean(mask_i_th_bit_key, &flag) && flag) - results->satisfied_criteria_mask |= (1 << i); - } - return results.Pass(); -} - -void AutomaticProfileResetter::ReportStatistics(uint32 satisfied_criteria_mask, - uint32 combined_status_mask) { - UMA_HISTOGRAM_ENUMERATION("AutomaticProfileReset.SatisfiedCriteriaMask", - satisfied_criteria_mask, - kSatisfiedCriteriaMaskMaximumValue); - UMA_HISTOGRAM_ENUMERATION("AutomaticProfileReset.CombinedStatusMask", - combined_status_mask, - kCombinedStatusMaskMaximumValue); -} - -void AutomaticProfileResetter::FinishEvaluationFlow( - scoped_ptr<EvaluationResults> results) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK_EQ(state_, STATE_EVALUATING_CONDITIONS); - - ReportStatistics(results->satisfied_criteria_mask, - results->combined_status_mask); - - if (results->should_prompt) - should_show_reset_banner_ = true; - - if (results->should_prompt && !results->had_prompted_already) { - evaluation_results_ = results.Pass(); - BeginResetPromptFlow(); - } else { - state_ = STATE_DONE; - } -} - -void AutomaticProfileResetter::BeginResetPromptFlow() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK_EQ(state_, STATE_EVALUATING_CONDITIONS); - - state_ = STATE_HAS_TRIGGERED_PROMPT; - - if (ShouldPerformLiveRun() && delegate_->TriggerPrompt()) { - // Start fetching the brandcoded default settings speculatively in the - // background, so as to reduce waiting time if the user chooses to go - // through with the reset. - delegate_->FetchBrandcodedDefaultSettingsIfNeeded(); - } else { - PersistMementos(); - ReportPromptResult(PROMPT_NOT_TRIGGERED); - FinishResetPromptFlow(); - } -} - -void AutomaticProfileResetter::OnProfileSettingsResetCompleted() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK_EQ(state_, STATE_PERFORMING_RESET); - - delegate_->DismissPrompt(); - FinishResetPromptFlow(); -} - -void AutomaticProfileResetter::ReportPromptResult(PromptResult result) { - UMA_HISTOGRAM_ENUMERATION( - "AutomaticProfileReset.PromptResult", result, PROMPT_RESULT_MAX); -} - -void AutomaticProfileResetter::PersistMementos() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK(state_ == STATE_HAS_TRIGGERED_PROMPT || - state_ == STATE_HAS_SHOWN_BUBBLE); - DCHECK(evaluation_results_); - - PreferenceHostedPromptMemento memento_in_prefs(profile_); - LocalStateHostedPromptMemento memento_in_local_state(profile_); - FileHostedPromptMemento memento_in_file(profile_); - - memento_in_prefs.StoreValue(evaluation_results_->memento_value_in_prefs); - memento_in_local_state.StoreValue( - evaluation_results_->memento_value_in_local_state); - memento_in_file.StoreValue(evaluation_results_->memento_value_in_file); - - evaluation_results_.reset(); -} - -void AutomaticProfileResetter::FinishResetPromptFlow() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK(state_ == STATE_HAS_TRIGGERED_PROMPT || - state_ == STATE_HAS_SHOWN_BUBBLE || - state_ == STATE_PERFORMING_RESET); - DCHECK(!evaluation_results_); - - state_ = STATE_DONE; -}
diff --git a/chrome/browser/profile_resetter/automatic_profile_resetter.h b/chrome/browser/profile_resetter/automatic_profile_resetter.h deleted file mode 100644 index 0e43a1b5..0000000 --- a/chrome/browser/profile_resetter/automatic_profile_resetter.h +++ /dev/null
@@ -1,268 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_H_ -#define CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_H_ - -#include <string> - -#include "base/basictypes.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/memory/weak_ptr.h" -#include "base/strings/string_piece.h" -#include "base/task_runner.h" -#include "chrome/browser/profile_resetter/automatic_profile_resetter_mementos.h" -#include "components/keyed_service/core/keyed_service.h" - -class AutomaticProfileResetterDelegate; -class Profile; - -namespace base { -class DictionaryValue; -class ListValue; -} - -// This service is responsible for evaluating whether the criteria for showing -// the one-time profile reset prompt are satisfied, and for potentially -// triggering the prompt. To ensure that the prompt only appears at most once -// for any given profile, a "memento" that the prompt has appeared is written to -// the profile on disk; see automatic_profile_resetter_mementos.h for details. -// The service is created automatically with the Profile and is activated right -// away by its factory. To avoid delaying start-up, however, it will only start -// working after a short delay. -// All methods in this class shall be called on the UI thread, except when noted -// otherwise. -class AutomaticProfileResetter : public KeyedService { - public: - // Enumeration listing the possible outcomes of triggering the profile reset - // prompt. - enum PromptResult { - // The reset prompt was not triggered because only a dry-run was performed, - // or because it was not supported on the current platform. - PROMPT_NOT_TRIGGERED, - // The reset bubble actually got shown. In contrast to the wrench menu item - // that can always be shown, the bubble might be delayed or might never be - // shown if another bubble was shown at the time of triggering the prompt. - // This enumeration value is usually recorded in conjunction with another - // PromptResult, the absence of which indicates that the prompt was ignored. - PROMPT_SHOWN_BUBBLE, - // The user selected "Reset" or "No, thanks" (respectively) directly from - // within the bubble. - PROMPT_ACTION_RESET, - PROMPT_ACTION_NO_RESET, - // The reset bubble was shown, then dismissed without taking definitive - // action. Then, however, the user initiated or refrained from doing a reset - // (respectively) from the conventional, WebUI-based reset dialog. - PROMPT_FOLLOWED_BY_WEBUI_RESET, - PROMPT_FOLLOWED_BY_WEBUI_NO_RESET, - // The reset bubble was suppressed (not shown) because another bubble was - // already being shown at the time. Regardless, however, the user initiated - // or refrained from doing a reset (respectively) from the conventional, - // WebUI-based reset dialog. - PROMPT_NOT_SHOWN_BUBBLE_BUT_HAD_WEBUI_RESET, - PROMPT_NOT_SHOWN_BUBBLE_BUT_HAD_WEBUI_NO_RESET, - PROMPT_RESULT_MAX - }; - - explicit AutomaticProfileResetter(Profile* profile); - ~AutomaticProfileResetter() override; - - // Initializes the service if it is enabled in the field trial. Otherwise, - // skips the initialization steps, and also permanently disables the service. - // Called by AutomaticProfileResetterFactory. - void Initialize(); - - // Fires up the service by unleashing the asynchronous evaluation flow, unless - // the service has been already disabled in Initialize() or there is no - // |program_| to run (in which case the service also gets disabled). - // Called by the AutomaticProfileResetterFactory. - void Activate(); - - // Called in case the user chooses to reset their profile settings from inside - // the reset bubble. Will trigger the reset, optionally |send_feedback|, and - // conclude the reset prompt flow. - void TriggerProfileReset(bool send_feedback); - - // Called in case the user chooses from inside the reset bubble that they do - // not want to reset their profile settings. Will conclude the reset prompt - // flow without setting off a reset. - void SkipProfileReset(); - - // Returns whether or not the profile reset prompt flow is currently active, - // that is, we have triggered the prompt and are waiting for the user to take - // definitive action (and we are not yet performing a reset). - bool IsResetPromptFlowActive() const; - - // Returns whether or not the profile reset banner should be shown on the - // WebUI-based settings page. - bool ShouldShowResetBanner() const; - - // Called to give notice that the reset bubble has actually been shown. - void NotifyDidShowResetBubble(); - - // Called to give notice that the conventional, WebUI-based settings reset - // dialog has been opened. This will dismiss the menu item in the wrench menu. - // This should always be followed by a corresponding call to - // NotifyDidCloseWebUIResetDialog(). - void NotifyDidOpenWebUIResetDialog(); - - // Called to give notice that the conventional, WebUI-based settings reset - // dialog has been closed, with |performed_reset| indicating whether or not a - // reset was requested. This is required so that we can record the appropriate - // PromptResult, dismiss the prompt, and conclude the reset prompt flow early - // without setting off any resets in the future. - void NotifyDidCloseWebUIResetDialog(bool performed_reset); - - // Called to give notice that reset banner has been dismissed as a result of - // user action on the WebUI-based settings page itself. - void NotifyDidCloseWebUIResetBanner(); - - base::WeakPtr<AutomaticProfileResetter> AsWeakPtr() { - return weak_ptr_factory_.GetWeakPtr(); - } - - // Should be called before Activate(). - void SetProgramForTesting(const std::string& program); - - // Should be called before Activate(). - void SetHashSeedForTesting(const std::string& hash_seed); - - // Should be called before Activate(). - void SetDelegateForTesting( - scoped_ptr<AutomaticProfileResetterDelegate> delegate); - - // Should be called before Activate(). Sets the task runner to be used to post - // task |PrepareEvaluationFlow| in a delayed manner. - void SetTaskRunnerForWaitingForTesting( - const scoped_refptr<base::TaskRunner>& task_runner); - - // KeyedService: - void Shutdown() override; - - private: - class InputBuilder; - struct EvaluationResults; - - enum State { - STATE_UNINITIALIZED, - STATE_INITIALIZED, - STATE_DISABLED, - STATE_WAITING_ON_DEPENDENCIES, - STATE_READY, - STATE_EVALUATING_CONDITIONS, - // The reset prompt has been triggered; but the reset bubble has not yet - // been shown. - STATE_HAS_TRIGGERED_PROMPT, - // The reset prompt has been triggered; the reset bubble has been shown, and - // potentially already dismissed by the user. - STATE_HAS_SHOWN_BUBBLE, - STATE_PERFORMING_RESET, - STATE_DONE - }; - - // Prepares the asynchronous evaluation flow by requesting services that it - // depends on to make themselves ready. - void PrepareEvaluationFlow(); - - // Called back by |resetter_delegate_| when the template URL service is ready. - void OnTemplateURLServiceIsLoaded(); - - // Called back by |resetter_delegate_| when the loaded modules have been - // enumerated. - void OnLoadedModulesAreEnumerated(); - - // Invoked by the above two methods. Kicks off the actual evaluation flow. - void OnDependencyIsReady(); - - // Begins the asynchronous evaluation flow, which will assess whether the - // criteria for showing the reset prompt are met, whether we have already - // shown the prompt; and, in the end, will potentially trigger the prompt. - void BeginEvaluationFlow(); - - // Called by InputBuilder once it has finished assembling the |program_input|, - // and will continue with the evaluation flow by triggering the evaluator - // program on the worker thread. - void ContinueWithEvaluationFlow( - scoped_ptr<base::DictionaryValue> program_input); - - // Performs the bulk of the work. Invokes the JTL interpreter to run the - // |program| that will evaluate whether the conditions are met for showing the - // reset prompt. The program will make this decision based on the state - // information contained in |input| in the form of key-value pairs. The - // program will only see hashed keys and values that are produced using - // |hash_seed| as a key. - static scoped_ptr<EvaluationResults> EvaluateConditionsOnWorkerPoolThread( - const std::string& hash_seed, - const std::string& program, - scoped_ptr<base::DictionaryValue> program_input); - - // Reports the given metrics through UMA. Virtual, so it can be mocked out in - // tests to verify that the correct value are being reported. - virtual void ReportStatistics(uint32 satisfied_criteria_mask, - uint32 combined_status_mask); - - // Called back when EvaluateConditionsOnWorkerPoolThread completes executing - // the program with |results|. Finishes the evaluation flow, and, based on the - // result, potentially initiates the reset prompt flow. - void FinishEvaluationFlow(scoped_ptr<EvaluationResults> results); - - // Begins the reset prompt flow by triggering the reset prompt, which consists - // of two parts: (1.) the profile reset (pop-up) bubble, and (2.) a menu item - // in the wrench menu (provided by a GlobalError). - // The flow lasts until we receive a clear indication from the user about - // whether or not they wish to reset their settings. This indication can come - // in a variety of flavors: - // * taking definitive action (i.e. selecting either "Reset" or "No, thanks") - // in the pop-up reset bubble itself, - // * dismissing the bubble, but then selecting the wrench menu item, which - // takes them to the WebUI reset dialog in chrome://settings, and then the - // user can make their choice there, - // * the user going to the WebUI reset dialog by themself. - // For the most part, the conclusion of the reset flow coincides with when the - // reset prompt is dismissed, with the one exception being that the prompt is - // closed as soon as the WebUI reset dialog is opened, we do not wait until - // the user actually makes a choice in that dialog. - void BeginResetPromptFlow(); - - // Called back by the ProfileResetter once resetting the profile settings has - // been completed, when requested by the user from inside the reset bubble. - // Will dismiss the prompt and conclude the reset prompt flow. - void OnProfileSettingsResetCompleted(); - - // Reports the result of triggering the prompt through UMA. Virtual, so it can - // be mocked out in tests to verify that the correct value is being reported. - virtual void ReportPromptResult(PromptResult result); - - // Writes the memento values returned by the evaluation program to disk, and - // then destroys |evaluation_results_|. - void PersistMementos(); - - // Concludes the reset prompt flow. - void FinishResetPromptFlow(); - - Profile* profile_; - - State state_; - bool enumeration_of_loaded_modules_ready_; - bool template_url_service_ready_; - bool has_already_dismissed_prompt_; - - scoped_ptr<InputBuilder> input_builder_; - std::string hash_seed_; - std::string program_; - - scoped_ptr<EvaluationResults> evaluation_results_; - - bool should_show_reset_banner_; - - scoped_ptr<AutomaticProfileResetterDelegate> delegate_; - scoped_refptr<base::TaskRunner> task_runner_for_waiting_; - - base::WeakPtrFactory<AutomaticProfileResetter> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(AutomaticProfileResetter); -}; - -#endif // CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_H_
diff --git a/chrome/browser/profile_resetter/automatic_profile_resetter_delegate.cc b/chrome/browser/profile_resetter/automatic_profile_resetter_delegate.cc deleted file mode 100644 index b74329fd..0000000 --- a/chrome/browser/profile_resetter/automatic_profile_resetter_delegate.cc +++ /dev/null
@@ -1,393 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/profile_resetter/automatic_profile_resetter_delegate.h" - -#include <string> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/callback.h" -#include "base/logging.h" -#include "base/md5.h" -#include "base/memory/scoped_vector.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_util.h" -#include "base/values.h" -#include "chrome/app/chrome_command_ids.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/google/google_brand.h" -#include "chrome/browser/profile_resetter/brandcode_config_fetcher.h" -#include "chrome/browser/profile_resetter/profile_reset_global_error.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/browser/search_engines/template_url_service_factory.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/global_error/global_error_service.h" -#include "chrome/browser/ui/global_error/global_error_service_factory.h" -#include "components/search_engines/template_url_prepopulate_data.h" -#include "components/search_engines/template_url_service.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/notification_service.h" - -#if defined(OS_WIN) -#include "chrome/browser/enumerate_modules_model_win.h" -#endif - -namespace { - -scoped_ptr<base::DictionaryValue> BuildSubTreeFromTemplateURL( - const TemplateURL* template_url) { - // If this value contains a placeholder in the pre-populated data, it will - // have been replaced as it was loaded into a TemplateURL. - // BuildSubTreeFromTemplateURL works with TemplateURL (not TemplateURLData) - // in order to maintain this behaviour. - // TODO(engedy): Confirm the expected behaviour and convert to use - // TemplateURLData if possible." - scoped_ptr<base::DictionaryValue> tree(new base::DictionaryValue); - tree->SetString("name", template_url->short_name()); - tree->SetString("short_name", template_url->short_name()); - tree->SetString("keyword", template_url->keyword()); - tree->SetString("search_url", template_url->url()); - tree->SetString("url", template_url->url()); - tree->SetString("suggestions_url", template_url->suggestions_url()); - tree->SetString("instant_url", template_url->instant_url()); - tree->SetString("image_url", template_url->image_url()); - tree->SetString("new_tab_url", template_url->new_tab_url()); - tree->SetString("search_url_post_params", - template_url->search_url_post_params()); - tree->SetString("suggestions_url_post_params", - template_url->suggestions_url_post_params()); - tree->SetString("instant_url_post_params", - template_url->instant_url_post_params()); - tree->SetString("image_url_post_params", - template_url->image_url_post_params()); - base::ListValue* alternate_urls = new base::ListValue; - alternate_urls->AppendStrings(template_url->alternate_urls()); - tree->Set("alternate_urls", alternate_urls); - tree->SetString("favicon_url", template_url->favicon_url().spec()); - tree->SetString("originating_url", template_url->originating_url().spec()); - tree->SetBoolean("safe_for_autoreplace", - template_url->safe_for_autoreplace()); - base::ListValue* input_encodings = new base::ListValue; - input_encodings->AppendStrings(template_url->input_encodings()); - tree->Set("input_encodings", input_encodings); - tree->SetString("id", base::Int64ToString(template_url->id())); - tree->SetString("date_created", - base::Int64ToString( - template_url->date_created().ToInternalValue())); - tree->SetString("last_modified", - base::Int64ToString( - template_url->last_modified().ToInternalValue())); - tree->SetBoolean("created_by_policy", template_url->created_by_policy()); - tree->SetInteger("usage_count", template_url->usage_count()); - tree->SetInteger("prepopulate_id", template_url->prepopulate_id()); - tree->SetString("search_terms_replacement_key", - template_url->search_terms_replacement_key()); - return tree.Pass(); -} - -#if defined(OS_WIN) -void ExtractLoadedModuleNameDigests( - const base::ListValue& module_list, - base::ListValue* module_name_digests) { - DCHECK(module_name_digests); - - // EnumerateModulesModel produces a list of dictionaries. - // Each dictionary corresponds to a module and exposes a number of properties. - // We care only about 'type' and 'name'. - for (size_t i = 0; i < module_list.GetSize(); ++i) { - const base::DictionaryValue* module_dictionary = NULL; - if (!module_list.GetDictionary(i, &module_dictionary)) - continue; - ModuleEnumerator::ModuleType module_type = - ModuleEnumerator::LOADED_MODULE; - if (!module_dictionary->GetInteger( - "type", reinterpret_cast<int*>(&module_type)) || - module_type != ModuleEnumerator::LOADED_MODULE) { - continue; - } - std::string module_name; - if (!module_dictionary->GetString("name", &module_name)) - continue; - module_name = base::ToLowerASCII(module_name); - module_name_digests->AppendString(base::MD5String(module_name)); - } -} -#endif - -} // namespace - - -// AutomaticProfileResetterDelegateImpl -------------------------------------- - -AutomaticProfileResetterDelegateImpl::AutomaticProfileResetterDelegateImpl( - Profile* profile, - ProfileResetter::ResettableFlags resettable_aspects) - : profile_(profile), - global_error_service_(GlobalErrorServiceFactory::GetForProfile(profile_)), - template_url_service_(TemplateURLServiceFactory::GetForProfile(profile_)), - resettable_aspects_(resettable_aspects) { - DCHECK(profile_); - if (template_url_service_) { - template_url_service_->AddObserver(this); - // Needed so that |template_url_service_ready_event_| will be signaled even - // when TemplateURLService had been already initialized before this point. - OnTemplateURLServiceChanged(); - } - -#if defined(OS_WIN) - module_list_.reset(EnumerateModulesModel::GetInstance()->GetModuleList()); -#endif - if (module_list_) { - // Having a non-empty module list proves that enumeration had been already - // performed before this point. - modules_have_been_enumerated_event_.Signal(); - } - registrar_.Add(this, - chrome::NOTIFICATION_MODULE_LIST_ENUMERATED, - content::NotificationService::AllSources()); -} - -AutomaticProfileResetterDelegateImpl::~AutomaticProfileResetterDelegateImpl() { - if (template_url_service_) - template_url_service_->RemoveObserver(this); -} - -void AutomaticProfileResetterDelegateImpl::EnumerateLoadedModulesIfNeeded() { - if (!modules_have_been_enumerated_event_.is_signaled()) { -#if defined(OS_WIN) - EnumerateModulesModel::GetInstance()->ScanNow(); -#else - modules_have_been_enumerated_event_.Signal(); -#endif - } -} - -void AutomaticProfileResetterDelegateImpl:: - RequestCallbackWhenLoadedModulesAreEnumerated( - const base::Closure& ready_callback) const { - DCHECK(!ready_callback.is_null()); - modules_have_been_enumerated_event_.Post(FROM_HERE, ready_callback); -} - -void AutomaticProfileResetterDelegateImpl::LoadTemplateURLServiceIfNeeded() { - DCHECK(template_url_service_); - template_url_service_->Load(); // Safe to call even if it has loaded already. -} - -void AutomaticProfileResetterDelegateImpl:: - RequestCallbackWhenTemplateURLServiceIsLoaded( - const base::Closure& ready_callback) const { - DCHECK(!ready_callback.is_null()); - template_url_service_ready_event_.Post(FROM_HERE, ready_callback); -} - -void AutomaticProfileResetterDelegateImpl:: - FetchBrandcodedDefaultSettingsIfNeeded() { - if (brandcoded_config_fetcher_ || - brandcoded_defaults_fetched_event_.is_signaled()) - return; - - std::string brandcode; - google_brand::GetBrand(&brandcode); - if (brandcode.empty()) { - brandcoded_defaults_.reset(new BrandcodedDefaultSettings); - brandcoded_defaults_fetched_event_.Signal(); - } else { - brandcoded_config_fetcher_.reset(new BrandcodeConfigFetcher( - base::Bind( - &AutomaticProfileResetterDelegateImpl::OnBrandcodedDefaultsFetched, - base::Unretained(this)), - GURL("https://tools.google.com/service/update2"), - brandcode)); - } -} - -void AutomaticProfileResetterDelegateImpl:: - RequestCallbackWhenBrandcodedDefaultsAreFetched( - const base::Closure& ready_callback) const { - DCHECK(!ready_callback.is_null()); - brandcoded_defaults_fetched_event_.Post(FROM_HERE, ready_callback); -} - -scoped_ptr<base::ListValue> AutomaticProfileResetterDelegateImpl:: - GetLoadedModuleNameDigests() const { - DCHECK(modules_have_been_enumerated_event_.is_signaled()); - scoped_ptr<base::ListValue> result(new base::ListValue); -#if defined(OS_WIN) - if (module_list_) - ExtractLoadedModuleNameDigests(*module_list_, result.get()); -#endif - return result.Pass(); -} - -scoped_ptr<base::DictionaryValue> AutomaticProfileResetterDelegateImpl:: - GetDefaultSearchProviderDetails() const { - DCHECK(template_url_service_); - DCHECK(template_url_service_->loaded()); - - const TemplateURL* default_search_provider = - template_url_service_->GetDefaultSearchProvider(); - - // Having a NULL default search provider is due to either: - // 1.) default search providers being disabled by policy, - // 2.) directly tampering with the Preferences and/or the SQLite DBs. - // In this state, Omnibox non-keyword search functionality is disabled. - return default_search_provider ? - BuildSubTreeFromTemplateURL(default_search_provider) : - scoped_ptr<base::DictionaryValue>(new base::DictionaryValue); -} - -bool AutomaticProfileResetterDelegateImpl:: - IsDefaultSearchProviderManaged() const { - DCHECK(template_url_service_); - DCHECK(template_url_service_->loaded()); - return template_url_service_->is_default_search_managed(); -} - -scoped_ptr<base::ListValue> AutomaticProfileResetterDelegateImpl:: - GetPrepopulatedSearchProvidersDetails() const { - size_t default_search_index = 0; - ScopedVector<TemplateURLData> engines( - TemplateURLPrepopulateData::GetPrepopulatedEngines( - profile_->GetPrefs(), &default_search_index)); - scoped_ptr<base::ListValue> engines_details_list(new base::ListValue); - for (ScopedVector<TemplateURLData>::const_iterator it = engines.begin(); - it != engines.end(); ++it) { - TemplateURL template_url(**it); - engines_details_list->Append( - BuildSubTreeFromTemplateURL(&template_url).release()); - } - return engines_details_list.Pass(); -} - -bool AutomaticProfileResetterDelegateImpl::TriggerPrompt() { - DCHECK(global_error_service_); - - Browser* browser = chrome::FindTabbedBrowser( - profile_, false /*match_original_profiles*/, chrome::GetActiveDesktop()); - if (!browser || !ProfileResetGlobalError::IsSupportedOnPlatform(browser)) - return false; - - ProfileResetGlobalError* global_error = new ProfileResetGlobalError(profile_); - global_error_service_->AddGlobalError(global_error); - - // Do not try to show bubble if another GlobalError is already showing one. - const GlobalErrorService::GlobalErrorList& global_errors( - global_error_service_->errors()); - GlobalErrorService::GlobalErrorList::const_iterator it; - for (it = global_errors.begin(); it != global_errors.end(); ++it) { - if ((*it)->GetBubbleView()) - break; - } - if (it == global_errors.end()) - global_error->ShowBubbleView(browser); - return true; -} - -void AutomaticProfileResetterDelegateImpl::TriggerProfileSettingsReset( - bool send_feedback, - const base::Closure& completion) { - DCHECK(!profile_resetter_); - DCHECK(!completion.is_null()); - - profile_resetter_.reset(new ProfileResetter(profile_)); - FetchBrandcodedDefaultSettingsIfNeeded(); - RequestCallbackWhenBrandcodedDefaultsAreFetched(base::Bind( - &AutomaticProfileResetterDelegateImpl::RunProfileSettingsReset, - AsWeakPtr(), - send_feedback, - completion)); -} - -void AutomaticProfileResetterDelegateImpl::OnTemplateURLServiceChanged() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK(template_url_service_); - if (template_url_service_->loaded() && - !template_url_service_ready_event_.is_signaled()) - template_url_service_ready_event_.Signal(); -} - -void AutomaticProfileResetterDelegateImpl::DismissPrompt() { - DCHECK(global_error_service_); - GlobalError* global_error = - global_error_service_->GetGlobalErrorByMenuItemCommandID( - IDC_SHOW_SETTINGS_RESET_BUBBLE); - if (global_error) { - // This will also close/destroy the Bubble UI if it is currently shown. - global_error_service_->RemoveGlobalError(global_error); - delete global_error; - } -} - -void AutomaticProfileResetterDelegateImpl::Observe( - int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (type == chrome::NOTIFICATION_MODULE_LIST_ENUMERATED && - !modules_have_been_enumerated_event_.is_signaled()) { -#if defined(OS_WIN) - module_list_.reset(EnumerateModulesModel::GetInstance()->GetModuleList()); -#endif - modules_have_been_enumerated_event_.Signal(); - } -} - -void AutomaticProfileResetterDelegateImpl::SendFeedback( - const std::string& report) const { - SendSettingsFeedback(report, profile_, PROFILE_RESET_PROMPT); -} - -void AutomaticProfileResetterDelegateImpl::RunProfileSettingsReset( - bool send_feedback, - const base::Closure& completion) { - DCHECK(brandcoded_defaults_); - scoped_ptr<ResettableSettingsSnapshot> old_settings_snapshot; - if (send_feedback) { - old_settings_snapshot.reset(new ResettableSettingsSnapshot(profile_)); - old_settings_snapshot->RequestShortcuts(base::Closure()); - } - profile_resetter_->Reset(resettable_aspects_, - brandcoded_defaults_.Pass(), - send_feedback, - base::Bind(&AutomaticProfileResetterDelegateImpl:: - OnProfileSettingsResetCompleted, - AsWeakPtr(), - completion, - base::Passed(&old_settings_snapshot))); -} - -void AutomaticProfileResetterDelegateImpl:: - OnBrandcodedDefaultsFetched() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK(brandcoded_config_fetcher_); - DCHECK(!brandcoded_config_fetcher_->IsActive()); - brandcoded_defaults_ = brandcoded_config_fetcher_->GetSettings(); - if (!brandcoded_defaults_) - brandcoded_defaults_.reset(new BrandcodedDefaultSettings); - brandcoded_defaults_fetched_event_.Signal(); -} - -void AutomaticProfileResetterDelegateImpl::OnProfileSettingsResetCompleted( - const base::Closure& user_callback, - scoped_ptr<ResettableSettingsSnapshot> old_settings_snapshot) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (old_settings_snapshot) { - ResettableSettingsSnapshot new_settings_snapshot(profile_); - int difference = - old_settings_snapshot->FindDifferentFields(new_settings_snapshot); - if (difference) { - old_settings_snapshot->Subtract(new_settings_snapshot); - std::string report = - SerializeSettingsReport(*old_settings_snapshot, difference); - SendFeedback(report); - } - } - content::BrowserThread::PostTask( - content::BrowserThread::UI, FROM_HERE, user_callback); -}
diff --git a/chrome/browser/profile_resetter/automatic_profile_resetter_delegate.h b/chrome/browser/profile_resetter/automatic_profile_resetter_delegate.h deleted file mode 100644 index 73a660b6..0000000 --- a/chrome/browser/profile_resetter/automatic_profile_resetter_delegate.h +++ /dev/null
@@ -1,237 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Declares a delegate that interacts with the rest of the browser on behalf of -// the AutomaticProfileResetter. -// -// The reason for this separation is to facilitate unit testing. Factoring out -// the implementation for each interaction step (encapsulated by one method of -// the delegate) allows it to be tested independently in itself. It also becomes -// easier to verify that the state machine inside AutomaticProfileResetter works -// correctly: by mocking out the interaction methods in the delegate, we can, in -// effect, mock out the entire rest of the browser, allowing us to easily -// simulate scenarios that are interesting for testing the state machine. -// -// The delegate is normally instantiated by AutomaticProfileResetter internally, -// while a mock implementation can be injected during unit tests. - -#ifndef CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_DELEGATE_H_ -#define CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_DELEGATE_H_ - -#include "base/basictypes.h" -#include "base/callback_forward.h" -#include "base/memory/scoped_ptr.h" -#include "base/memory/weak_ptr.h" -#include "chrome/browser/profile_resetter/profile_resetter.h" -#include "components/search_engines/template_url_service_observer.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" -#include "extensions/common/one_shot_event.h" - -class BrandcodeConfigFetcher; -class GlobalErrorService; -class Profile; -class ResettableSettingsSnapshot; -class TemplateURLService; - -namespace base { -class DictionaryValue; -class ListValue; -} - -// Defines the interface for the delegate that will interact with the rest of -// the browser on behalf of the AutomaticProfileResetter. -class AutomaticProfileResetterDelegate { - public: - virtual ~AutomaticProfileResetterDelegate() {} - - // Requests the module enumerator to start scanning for loaded modules now, if - // it has not done so already. - virtual void EnumerateLoadedModulesIfNeeded() = 0; - - // Requests |ready_callback| to be posted on the UI thread once the module - // enumerator has finished scanning for loaded modules. - virtual void RequestCallbackWhenLoadedModulesAreEnumerated( - const base::Closure& ready_callback) const = 0; - - // Requests the template URL service to load its database (asynchronously). - virtual void LoadTemplateURLServiceIfNeeded() = 0; - - // Requests |ready_callback| to be posted on the UI thread once the template - // URL service has finished loading its database. - virtual void RequestCallbackWhenTemplateURLServiceIsLoaded( - const base::Closure& ready_callback) const = 0; - - // Starts downloading the configuration file that specifies the default - // settings for the current brandcode; or establishes that we are running a - // vanilla (non-branded) build. - virtual void FetchBrandcodedDefaultSettingsIfNeeded() = 0; - - // Requests |ready_callback| to be posted on the UI thread once the brandcoded - // default settings have been downloaded, or once it has been established that - // we are running a vanilla (non-branded) build. - virtual void RequestCallbackWhenBrandcodedDefaultsAreFetched( - const base::Closure& ready_callback) const = 0; - - // Returns a list of loaded module name digests. - virtual scoped_ptr<base::ListValue> GetLoadedModuleNameDigests() const = 0; - - // Returns attributes of the search engine currently set as the default (or - // an empty dictionary if there is none). - // The dictionary is in the same format as persisted to preferences by - // DefaultSearchManager::SetUserSelectedDefaultSearchEngine. - virtual scoped_ptr<base::DictionaryValue> - GetDefaultSearchProviderDetails() const = 0; - - // Returns whether or not the default search provider is set by policy. - virtual bool IsDefaultSearchProviderManaged() const = 0; - - // Returns a list of dictionaries, each containing attributes for each of the - // pre-populated search engines, in the format described above. - virtual scoped_ptr<base::ListValue> - GetPrepopulatedSearchProvidersDetails() const = 0; - - // Triggers showing the one-time profile settings reset prompt, which consists - // of two parts: (1.) the profile reset (pop-up) bubble, and (2.) a menu item - // in the wrench menu. Showing the bubble might be delayed if there is another - // bubble currently shown, in which case the bubble will be shown the first - // time a new browser window is opened. - // Returns true unless the reset prompt is not supported on the current - // platform, in which case it returns false and does nothing. - virtual bool TriggerPrompt() = 0; - - // Triggers the ProfileResetter to reset all supported settings and optionally - // |send_feedback|. Will post |completion| on the UI thread once completed. - // Brandcoded default settings will be fetched if they are not yet available, - // the reset will be performed once the download is complete. - // NOTE: Should only be called at most once during the lifetime of the object. - virtual void TriggerProfileSettingsReset(bool send_feedback, - const base::Closure& completion) = 0; - - // Dismisses the one-time profile settings reset prompt, if it is currently - // triggered. Will synchronously destroy the corresponding GlobalError. - virtual void DismissPrompt() = 0; -}; - -// Implementation for AutomaticProfileResetterDelegate. -class AutomaticProfileResetterDelegateImpl - : public AutomaticProfileResetterDelegate, - public base::SupportsWeakPtr<AutomaticProfileResetterDelegateImpl>, - public TemplateURLServiceObserver, - public content::NotificationObserver { - public: - explicit AutomaticProfileResetterDelegateImpl( - Profile* profile, - ProfileResetter::ResettableFlags resettable_aspects); - ~AutomaticProfileResetterDelegateImpl() override; - - // Returns the brandcoded default settings; empty defaults if this is not a - // branded build; or NULL if FetchBrandcodedDefaultSettingsIfNeeded() has not - // yet been called or not yet finished. Exposed only for unit tests. - const BrandcodedDefaultSettings* brandcoded_defaults() const { - return brandcoded_defaults_.get(); - } - - // AutomaticProfileResetterDelegate: - void EnumerateLoadedModulesIfNeeded() override; - void RequestCallbackWhenLoadedModulesAreEnumerated( - const base::Closure& ready_callback) const override; - void LoadTemplateURLServiceIfNeeded() override; - void RequestCallbackWhenTemplateURLServiceIsLoaded( - const base::Closure& ready_callback) const override; - void FetchBrandcodedDefaultSettingsIfNeeded() override; - void RequestCallbackWhenBrandcodedDefaultsAreFetched( - const base::Closure& ready_callback) const override; - scoped_ptr<base::ListValue> GetLoadedModuleNameDigests() const override; - scoped_ptr<base::DictionaryValue> GetDefaultSearchProviderDetails() - const override; - bool IsDefaultSearchProviderManaged() const override; - scoped_ptr<base::ListValue> GetPrepopulatedSearchProvidersDetails() - const override; - bool TriggerPrompt() override; - void TriggerProfileSettingsReset(bool send_feedback, - const base::Closure& completion) override; - void DismissPrompt() override; - - // TemplateURLServiceObserver: - void OnTemplateURLServiceChanged() override; - - // content::NotificationObserver: - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; - - private: - // Sends a feedback |report|, where |report| is supposed to be result of - // ::SerializeSettingsReport(). Virtual, so it can be mocked out for tests. - virtual void SendFeedback(const std::string& report) const; - - // Triggers the ProfileResetter to reset |resettable_aspects_| and optionally - // |send_feedback|. Will invoke |completion| on the UI thread once completed - // The |brandcoded_defaults_| must already be initialized when this is called. - void RunProfileSettingsReset(bool send_feedback, - const base::Closure& completion); - - // Called by |brandcoded_config_fetcher_| when it finishes downloading the - // brandcoded default settings (or the download times out). - void OnBrandcodedDefaultsFetched(); - - // Called back by the ProfileResetter once resetting the profile settings has - // been completed. If |old_settings_snapshot| is non-NULL, will compare it to - // the new settings and send the differences to Google for analysis. Finally, - // will post |user_callback|. - void OnProfileSettingsResetCompleted( - const base::Closure& user_callback, - scoped_ptr<ResettableSettingsSnapshot> old_settings_snapshot); - - // The profile that this delegate operates on. - Profile* profile_; - - // Shortcuts to |profile_| keyed services, to reduce boilerplate. These may be - // NULL in unit tests that do not initialize the respective service(s). - GlobalErrorService* global_error_service_; - TemplateURLService* template_url_service_; - - // Helper to asynchronously download the default settings for the current - // distribution channel (identified by brand code). Instantiated on-demand. - scoped_ptr<BrandcodeConfigFetcher> brandcoded_config_fetcher_; - - // Once |brandcoded_defaults_fetched_event_| has fired, this will contain the - // brandcoded default settings, or empty settings for a non-branded build. - scoped_ptr<BrandcodedDefaultSettings> brandcoded_defaults_; - - // Overwritten to avoid resetting aspects that will not work in unit tests. - const ProfileResetter::ResettableFlags resettable_aspects_; - - // The profile resetter to perform the actual reset. Instantiated on-demand. - scoped_ptr<ProfileResetter> profile_resetter_; - - // Manages registrations/unregistrations for notifications. - content::NotificationRegistrar registrar_; - - // The list of modules found. Even when |modules_have_been_enumerated_event_| - // is signaled, this may still be NULL. - scoped_ptr<base::ListValue> module_list_; - - // This event is signaled once module enumeration has been attempted. If - // during construction, EnumerateModulesModel can supply a non-empty list of - // modules, module enumeration has clearly already happened, so the event will - // be signaled immediately; otherwise, when EnumerateLoadedModulesIfNeeded() - // is called, it will ask the model to scan the modules, and then signal the - // event once this process is completed. - extensions::OneShotEvent modules_have_been_enumerated_event_; - - // This event is signaled once the TemplateURLService has loaded. If the - // TemplateURLService was already loaded prior to the creation of this class, - // the event will be signaled during construction. - extensions::OneShotEvent template_url_service_ready_event_; - - // This event is signaled once brandcoded default settings have been fetched, - // or once it has been established that this is not a branded build. - extensions::OneShotEvent brandcoded_defaults_fetched_event_; - - DISALLOW_COPY_AND_ASSIGN(AutomaticProfileResetterDelegateImpl); -}; - -#endif // CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_DELEGATE_H_
diff --git a/chrome/browser/profile_resetter/automatic_profile_resetter_delegate_unittest.cc b/chrome/browser/profile_resetter/automatic_profile_resetter_delegate_unittest.cc deleted file mode 100644 index 9214100..0000000 --- a/chrome/browser/profile_resetter/automatic_profile_resetter_delegate_unittest.cc +++ /dev/null
@@ -1,608 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/profile_resetter/automatic_profile_resetter_delegate.h" - -#include <algorithm> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/prefs/pref_service.h" -#include "base/run_loop.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_split.h" -#include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" -#include "base/test/values_test_util.h" -#include "base/values.h" -#include "chrome/app/chrome_command_ids.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/extensions/extension_service.h" -#include "chrome/browser/extensions/extension_service_test_base.h" -#include "chrome/browser/google/google_brand.h" -#include "chrome/browser/profile_resetter/brandcoded_default_settings.h" -#include "chrome/browser/profile_resetter/profile_reset_global_error.h" -#include "chrome/browser/search_engines/template_url_service_factory.h" -#include "chrome/browser/search_engines/template_url_service_factory_test_util.h" -#include "chrome/browser/ui/global_error/global_error.h" -#include "chrome/browser/ui/global_error/global_error_service.h" -#include "chrome/browser/ui/global_error/global_error_service_factory.h" -#include "chrome/common/pref_names.h" -#include "chrome/test/base/testing_profile.h" -#include "components/search_engines/default_search_manager.h" -#include "components/search_engines/template_url_prepopulate_data.h" -#include "components/search_engines/template_url_service.h" -#include "components/syncable_prefs/testing_pref_service_syncable.h" -#include "content/public/browser/notification_service.h" -#include "net/http/http_response_headers.h" -#include "net/url_request/test_url_fetcher_factory.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -#if defined(OS_WIN) -#include "chrome/browser/enumerate_modules_model_win.h" -#endif - -namespace { - -const char kTestBrandcode[] = "FOOBAR"; - -const char kTestHomepage[] = "http://google.com"; -const char kTestBrandedHomepage[] = "http://example.com"; - -const ProfileResetter::ResettableFlags kResettableAspectsForTest = - ProfileResetter::ALL & ~ProfileResetter::COOKIES_AND_SITE_DATA; - -// Helpers ------------------------------------------------------------------- - -// A testing version of the AutomaticProfileResetterDelegate that differs from -// the real one only in that it has its feedback reporting mocked out, and it -// will not reset COOKIES_AND_SITE_DATA, due to difficulties to set up some -// required URLRequestContexts in unit tests. -class AutomaticProfileResetterDelegateUnderTest - : public AutomaticProfileResetterDelegateImpl { - public: - explicit AutomaticProfileResetterDelegateUnderTest(Profile* profile) - : AutomaticProfileResetterDelegateImpl( - profile, kResettableAspectsForTest) {} - virtual ~AutomaticProfileResetterDelegateUnderTest() {} - - MOCK_CONST_METHOD1(SendFeedback, void(const std::string&)); - - private: - DISALLOW_COPY_AND_ASSIGN(AutomaticProfileResetterDelegateUnderTest); -}; - -class MockCallbackTarget { - public: - MockCallbackTarget() {} - ~MockCallbackTarget() {} - - MOCK_CONST_METHOD0(Run, void(void)); - - base::Closure CreateClosure() { - return base::Bind(&MockCallbackTarget::Run, base::Unretained(this)); - } - - private: - DISALLOW_COPY_AND_ASSIGN(MockCallbackTarget); -}; - -// Returns the details of the default search provider from |prefs| in a format -// suitable for usage as |expected_details| in ExpectDetailsMatch(). -const base::DictionaryValue* GetDefaultSearchProviderDetailsFromPrefs( - const PrefService* prefs) { - return prefs->GetDictionary( - DefaultSearchManager::kDefaultSearchProviderDataPrefName); -} - -// Verifies that the |details| of a search engine as provided by the delegate -// are correct in comparison to the |expected_details| coming from the Prefs. -void ExpectDetailsMatch(const base::DictionaryValue& expected_details, - const base::DictionaryValue& details) { - for (base::DictionaryValue::Iterator it(expected_details); !it.IsAtEnd(); - it.Advance()) { - SCOPED_TRACE(testing::Message("Key: ") << it.key()); - if (it.key() == "enabled" || it.key() == "synced_guid") { - // These attributes should not be present. - EXPECT_FALSE(details.HasKey(it.key())); - continue; - } - const base::Value* expected_value = &it.value(); - const base::Value* actual_value = NULL; - ASSERT_TRUE(details.Get(it.key(), &actual_value)); - - // Ignore ID as it is dynamically assigned by the TemplateURLService. - // last_modified may get updated during a run, so ignore value differences. - if (it.key() != "id" && it.key() != "last_modified") { - // Everything else is the same format. - EXPECT_TRUE(actual_value->Equals(expected_value)) - << "Expected: " << *expected_value << ". Actual: " << *actual_value; - } - } -} - -// If |simulate_failure| is false, then replies to the pending request on -// |fetcher| with a brandcoded config that only specifies a home page URL. -// If |simulate_failure| is true, replies with 404. -void ServicePendingBrancodedConfigFetch(net::TestURLFetcher* fetcher, - bool simulate_failure) { - const char kBrandcodedXmlSettings[] = - "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" - "<response protocol=\"3.0\" server=\"prod\">" - "<app appid=\"{8A69D345-D564-463C-AFF1-A69D9E530F96}\" status=\"ok\">" - "<data index=\"skipfirstrunui-importsearch-defaultbrowser\" " - "name=\"install\" status=\"ok\">" - "{\"homepage\" : \"$1\"}" - "</data>" - "</app>" - "</response>"; - - fetcher->set_response_code(simulate_failure ? 404 : 200); - scoped_refptr<net::HttpResponseHeaders> response_headers( - new net::HttpResponseHeaders("")); - response_headers->AddHeader("Content-Type: text/xml"); - fetcher->set_response_headers(response_headers); - if (!simulate_failure) { - std::string response(kBrandcodedXmlSettings); - size_t placeholder_index = response.find("$1"); - ASSERT_NE(std::string::npos, placeholder_index); - response.replace(placeholder_index, 2, kTestBrandedHomepage); - fetcher->SetResponseString(response); - } - fetcher->delegate()->OnURLFetchComplete(fetcher); -} - - -// Test fixture -------------------------------------------------------------- - -// ExtensionServiceTestBase sets up a TestingProfile with the ExtensionService, -// we then add the TemplateURLService, so the ProfileResetter can be exercised. -class AutomaticProfileResetterDelegateTest - : public extensions::ExtensionServiceTestBase { - protected: - AutomaticProfileResetterDelegateTest() {} - ~AutomaticProfileResetterDelegateTest() override {} - - void SetUp() override { - extensions::ExtensionServiceTestBase::SetUp(); - ExtensionServiceInitParams params = CreateDefaultInitParams(); - params.pref_file.clear(); // Prescribes a TestingPrefService to be created. - InitializeExtensionService(params); - template_url_service_test_util_.reset( - new TemplateURLServiceFactoryTestUtil(profile_.get())); - resetter_delegate_.reset( - new AutomaticProfileResetterDelegateUnderTest(profile())); - } - - void TearDown() override { - resetter_delegate_.reset(); - template_url_service_test_util_.reset(); - extensions::ExtensionServiceTestBase::TearDown(); - } - - scoped_ptr<TemplateURL> CreateTestTemplateURL() { - TemplateURLData data; - - data.SetURL("http://example.com/search?q={searchTerms}"); - data.suggestions_url = "http://example.com/suggest?q={searchTerms}"; - data.instant_url = "http://example.com/instant?q={searchTerms}"; - data.image_url = "http://example.com/image?q={searchTerms}"; - data.search_url_post_params = "search-post-params"; - data.suggestions_url_post_params = "suggest-post-params"; - data.instant_url_post_params = "instant-post-params"; - data.image_url_post_params = "image-post-params"; - - data.favicon_url = GURL("http://example.com/favicon.ico"); - data.new_tab_url = "http://example.com/newtab.html"; - data.alternate_urls.push_back("http://example.com/s?q={searchTerms}"); - - data.short_name = base::ASCIIToUTF16("name"); - data.SetKeyword(base::ASCIIToUTF16("keyword")); - data.search_terms_replacement_key = "search-terms-replacment-key"; - data.prepopulate_id = 42; - data.input_encodings.push_back("UTF-8"); - data.safe_for_autoreplace = true; - - return scoped_ptr<TemplateURL>(new TemplateURL(data)); - } - - void ExpectNoPendingBrandcodedConfigFetch() { - EXPECT_FALSE(test_url_fetcher_factory_.GetFetcherByID(0)); - } - - void ExpectAndServicePendingBrandcodedConfigFetch(bool simulate_failure) { - net::TestURLFetcher* fetcher = test_url_fetcher_factory_.GetFetcherByID(0); - ASSERT_TRUE(fetcher); - EXPECT_THAT(fetcher->upload_data(), - testing::HasSubstr(kTestBrandcode)); - ServicePendingBrancodedConfigFetch(fetcher, simulate_failure); - } - - void ExpectResetPromptState(bool active) { - GlobalErrorService* global_error_service = - GlobalErrorServiceFactory::GetForProfile(profile()); - GlobalError* global_error = global_error_service-> - GetGlobalErrorByMenuItemCommandID(IDC_SHOW_SETTINGS_RESET_BUBBLE); - EXPECT_EQ(active, !!global_error); - } - - AutomaticProfileResetterDelegateUnderTest* resetter_delegate() { - return resetter_delegate_.get(); - } - - TemplateURLServiceFactoryTestUtil* template_url_service_test_util() { - return template_url_service_test_util_.get(); - } - - private: - scoped_ptr<TemplateURLServiceFactoryTestUtil> template_url_service_test_util_; - net::TestURLFetcherFactory test_url_fetcher_factory_; - scoped_ptr<AutomaticProfileResetterDelegateUnderTest> resetter_delegate_; - - DISALLOW_COPY_AND_ASSIGN(AutomaticProfileResetterDelegateTest); -}; - - -// Tests --------------------------------------------------------------------- - -TEST_F(AutomaticProfileResetterDelegateTest, - TriggerAndWaitOnModuleEnumeration) { - // Expect ready_callback to be called just after the modules have been - // enumerated. Fail if it is not called. Note: as the EnumerateModulesModel is - // a global singleton, the callback might be invoked immediately if another - // test-case (e.g. the one below) has already performed module enumeration. - testing::StrictMock<MockCallbackTarget> mock_target; - EXPECT_CALL(mock_target, Run()); - resetter_delegate()->RequestCallbackWhenLoadedModulesAreEnumerated( - mock_target.CreateClosure()); - resetter_delegate()->EnumerateLoadedModulesIfNeeded(); - base::RunLoop().RunUntilIdle(); - - testing::Mock::VerifyAndClearExpectations(&mock_target); - - // Expect ready_callback to be posted immediately when the modules have - // already been enumerated. - EXPECT_CALL(mock_target, Run()); - resetter_delegate()->RequestCallbackWhenLoadedModulesAreEnumerated( - mock_target.CreateClosure()); - base::RunLoop().RunUntilIdle(); - -#if defined(OS_WIN) - testing::Mock::VerifyAndClearExpectations(&mock_target); - - // Expect ready_callback to be posted immediately even when the modules had - // already been enumerated when the delegate was constructed. - scoped_ptr<AutomaticProfileResetterDelegate> late_resetter_delegate( - new AutomaticProfileResetterDelegateImpl(profile(), - ProfileResetter::ALL)); - - EXPECT_CALL(mock_target, Run()); - late_resetter_delegate->RequestCallbackWhenLoadedModulesAreEnumerated( - mock_target.CreateClosure()); - base::RunLoop().RunUntilIdle(); -#endif -} - -TEST_F(AutomaticProfileResetterDelegateTest, GetLoadedModuleNameDigests) { - resetter_delegate()->EnumerateLoadedModulesIfNeeded(); - base::RunLoop().RunUntilIdle(); - scoped_ptr<base::ListValue> module_name_digests( - resetter_delegate()->GetLoadedModuleNameDigests()); - - // Just verify that each element looks like an MD5 hash in hexadecimal, and - // also that we have at least one element on Win. - ASSERT_TRUE(module_name_digests); - for (base::ListValue::const_iterator it = module_name_digests->begin(); - it != module_name_digests->end(); ++it) { - std::string digest_hex; - std::vector<uint8> digest_raw; - - ASSERT_TRUE((*it)->GetAsString(&digest_hex)); - ASSERT_TRUE(base::HexStringToBytes(digest_hex, &digest_raw)); - EXPECT_EQ(16u, digest_raw.size()); - } -#if defined(OS_WIN) - EXPECT_LE(1u, module_name_digests->GetSize()); -#endif -} - -TEST_F(AutomaticProfileResetterDelegateTest, LoadAndWaitOnTemplateURLService) { - // Expect ready_callback to be called just after the template URL service gets - // initialized. Fail if it is not called, or called too early. - testing::StrictMock<MockCallbackTarget> mock_target; - resetter_delegate()->RequestCallbackWhenTemplateURLServiceIsLoaded( - mock_target.CreateClosure()); - base::RunLoop().RunUntilIdle(); - - EXPECT_CALL(mock_target, Run()); - resetter_delegate()->LoadTemplateURLServiceIfNeeded(); - base::RunLoop().RunUntilIdle(); - - testing::Mock::VerifyAndClearExpectations(&mock_target); - - // Expect ready_callback to be posted immediately when the template URL - // service is already initialized. - EXPECT_CALL(mock_target, Run()); - resetter_delegate()->RequestCallbackWhenTemplateURLServiceIsLoaded( - mock_target.CreateClosure()); - base::RunLoop().RunUntilIdle(); - - testing::Mock::VerifyAndClearExpectations(&mock_target); - - // Expect ready_callback to be posted immediately even when the template URL - // service had already been initialized when the delegate was constructed. - scoped_ptr<AutomaticProfileResetterDelegate> late_resetter_delegate( - new AutomaticProfileResetterDelegateImpl(profile(), - ProfileResetter::ALL)); - - EXPECT_CALL(mock_target, Run()); - late_resetter_delegate->RequestCallbackWhenTemplateURLServiceIsLoaded( - mock_target.CreateClosure()); - base::RunLoop().RunUntilIdle(); -} - -TEST_F(AutomaticProfileResetterDelegateTest, - DefaultSearchProviderDataWhenNotManaged) { - TemplateURLService* template_url_service = - TemplateURLServiceFactory::GetForProfile(profile()); - template_url_service_test_util()->VerifyLoad(); - - // Check that the "managed state" and the details returned by the delegate are - // correct. We verify the details against the data stored by - // TemplateURLService into Prefs. - scoped_ptr<TemplateURL> owned_custom_dsp(CreateTestTemplateURL()); - TemplateURL* custom_dsp = owned_custom_dsp.get(); - template_url_service->Add(owned_custom_dsp.release()); - template_url_service->SetUserSelectedDefaultSearchProvider(custom_dsp); - - PrefService* prefs = profile()->GetPrefs(); - ASSERT_TRUE(prefs); - scoped_ptr<base::DictionaryValue> dsp_details( - resetter_delegate()->GetDefaultSearchProviderDetails()); - const base::DictionaryValue* expected_dsp_details = - GetDefaultSearchProviderDetailsFromPrefs(prefs); - - ExpectDetailsMatch(*expected_dsp_details, *dsp_details); - EXPECT_FALSE(resetter_delegate()->IsDefaultSearchProviderManaged()); -} - -TEST_F(AutomaticProfileResetterDelegateTest, - DefaultSearchProviderDataWhenManaged) { - const char kTestSearchURL[] = "http://example.com/search?q={searchTerms}"; - const char kTestName[] = "name"; - const char kTestKeyword[] = "keyword"; - - template_url_service_test_util()->VerifyLoad(); - - EXPECT_FALSE(resetter_delegate()->IsDefaultSearchProviderManaged()); - - // Set managed preferences to emulate a default search provider set by policy. - template_url_service_test_util()->SetManagedDefaultSearchPreferences( - true, kTestName, kTestKeyword, kTestSearchURL, std::string(), - std::string(), std::string(), std::string(), std::string()); - - EXPECT_TRUE(resetter_delegate()->IsDefaultSearchProviderManaged()); - scoped_ptr<base::DictionaryValue> dsp_details( - resetter_delegate()->GetDefaultSearchProviderDetails()); - // Checking that all details are correct is already done by the above test. - // Just make sure details are reported about the correct engine. - base::ExpectDictStringValue(kTestSearchURL, *dsp_details, "search_url"); - - // Set managed preferences to emulate that having a default search provider is - // disabled by policy. - template_url_service_test_util()->RemoveManagedDefaultSearchPreferences(); - template_url_service_test_util()->SetManagedDefaultSearchPreferences( - false, std::string(), std::string(), std::string(), std::string(), - std::string(), std::string(), std::string(), std::string()); - - dsp_details = resetter_delegate()->GetDefaultSearchProviderDetails(); - EXPECT_TRUE(resetter_delegate()->IsDefaultSearchProviderManaged()); - EXPECT_TRUE(dsp_details->empty()); -} - -TEST_F(AutomaticProfileResetterDelegateTest, - GetPrepopulatedSearchProvidersDetails) { - TemplateURLService* template_url_service = - TemplateURLServiceFactory::GetForProfile(profile()); - template_url_service_test_util()->VerifyLoad(); - - scoped_ptr<base::ListValue> search_engines_details( - resetter_delegate()->GetPrepopulatedSearchProvidersDetails()); - - // Do the same kind of verification as for GetDefaultSearchEngineDetails: - // subsequently set each pre-populated engine as the default, so we can verify - // that the details returned by the delegate about one particular engine are - // correct in comparison to what has been stored to the Prefs. - std::vector<TemplateURL*> prepopulated_engines = - template_url_service->GetTemplateURLs(); - - ASSERT_EQ(prepopulated_engines.size(), search_engines_details->GetSize()); - - for (size_t i = 0; i < search_engines_details->GetSize(); ++i) { - const base::DictionaryValue* details = NULL; - ASSERT_TRUE(search_engines_details->GetDictionary(i, &details)); - - std::string keyword; - ASSERT_TRUE(details->GetString("keyword", &keyword)); - TemplateURL* search_engine = - template_url_service->GetTemplateURLForKeyword( - base::ASCIIToUTF16(keyword)); - ASSERT_TRUE(search_engine); - template_url_service->SetUserSelectedDefaultSearchProvider( - prepopulated_engines[i]); - - PrefService* prefs = profile()->GetPrefs(); - ASSERT_TRUE(prefs); - const base::DictionaryValue* expected_dsp_details = - GetDefaultSearchProviderDetailsFromPrefs(prefs); - ExpectDetailsMatch(*expected_dsp_details, *details); - } -} - -TEST_F(AutomaticProfileResetterDelegateTest, - FetchAndWaitOnDefaultSettingsVanilla) { - google_brand::BrandForTesting scoped_brand_for_testing((std::string())); - - // Expect ready_callback to be called just after empty brandcoded settings - // are loaded, given this is a vanilla build. Fail if it is not called, or - // called too early. - testing::StrictMock<MockCallbackTarget> mock_target; - resetter_delegate()->RequestCallbackWhenBrandcodedDefaultsAreFetched( - mock_target.CreateClosure()); - base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(resetter_delegate()->brandcoded_defaults()); - - EXPECT_CALL(mock_target, Run()); - resetter_delegate()->FetchBrandcodedDefaultSettingsIfNeeded(); - base::RunLoop().RunUntilIdle(); - ExpectNoPendingBrandcodedConfigFetch(); - - testing::Mock::VerifyAndClearExpectations(&mock_target); - EXPECT_TRUE(resetter_delegate()->brandcoded_defaults()); - - // Expect ready_callback to be posted immediately when the brandcoded settings - // have already been loaded. - EXPECT_CALL(mock_target, Run()); - resetter_delegate()->RequestCallbackWhenBrandcodedDefaultsAreFetched( - mock_target.CreateClosure()); - base::RunLoop().RunUntilIdle(); - - // No test for a new instance of AutomaticProfileResetterDelegate. That will - // need to fetch the brandcoded settings again. -} - -TEST_F(AutomaticProfileResetterDelegateTest, - FetchAndWaitOnDefaultSettingsBranded) { - google_brand::BrandForTesting scoped_brand_for_testing(kTestBrandcode); - - // Expect ready_callback to be called just after the brandcoded settings are - // downloaded. Fail if it is not called, or called too early. - testing::StrictMock<MockCallbackTarget> mock_target; - resetter_delegate()->RequestCallbackWhenBrandcodedDefaultsAreFetched( - mock_target.CreateClosure()); - base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(resetter_delegate()->brandcoded_defaults()); - - EXPECT_CALL(mock_target, Run()); - resetter_delegate()->FetchBrandcodedDefaultSettingsIfNeeded(); - ExpectAndServicePendingBrandcodedConfigFetch(false /*simulate_failure*/); - base::RunLoop().RunUntilIdle(); - - testing::Mock::VerifyAndClearExpectations(&mock_target); - const BrandcodedDefaultSettings* brandcoded_defaults = - resetter_delegate()->brandcoded_defaults(); - ASSERT_TRUE(brandcoded_defaults); - std::string homepage_url; - EXPECT_TRUE(brandcoded_defaults->GetHomepage(&homepage_url)); - EXPECT_EQ(kTestBrandedHomepage, homepage_url); - - // Expect ready_callback to be posted immediately when the brandcoded settings - // have already been downloaded. - EXPECT_CALL(mock_target, Run()); - resetter_delegate()->RequestCallbackWhenBrandcodedDefaultsAreFetched( - mock_target.CreateClosure()); - base::RunLoop().RunUntilIdle(); -} - -TEST_F(AutomaticProfileResetterDelegateTest, - FetchAndWaitOnDefaultSettingsBrandedFailure) { - google_brand::BrandForTesting scoped_brand_for_testing(kTestBrandcode); - - // Expect ready_callback to be called just after the brandcoded settings have - // failed to download. Fail if it is not called, or called too early. - testing::StrictMock<MockCallbackTarget> mock_target; - resetter_delegate()->RequestCallbackWhenBrandcodedDefaultsAreFetched( - mock_target.CreateClosure()); - base::RunLoop().RunUntilIdle(); - - EXPECT_CALL(mock_target, Run()); - resetter_delegate()->FetchBrandcodedDefaultSettingsIfNeeded(); - ExpectAndServicePendingBrandcodedConfigFetch(true /*simulate_failure*/); - base::RunLoop().RunUntilIdle(); - - testing::Mock::VerifyAndClearExpectations(&mock_target); - EXPECT_TRUE(resetter_delegate()->brandcoded_defaults()); - - // Expect ready_callback to be posted immediately when the brandcoded settings - // have already been attempted to be downloaded, but failed. - EXPECT_CALL(mock_target, Run()); - resetter_delegate()->RequestCallbackWhenBrandcodedDefaultsAreFetched( - mock_target.CreateClosure()); - base::RunLoop().RunUntilIdle(); -} - -TEST_F(AutomaticProfileResetterDelegateTest, TriggerReset) { - google_brand::BrandForTesting scoped_brand_for_testing(kTestBrandcode); - - PrefService* prefs = profile()->GetPrefs(); - DCHECK(prefs); - prefs->SetString(prefs::kHomePage, kTestHomepage); - - testing::StrictMock<MockCallbackTarget> mock_target; - EXPECT_CALL(mock_target, Run()); - EXPECT_CALL(*resetter_delegate(), SendFeedback(testing::_)).Times(0); - resetter_delegate()->TriggerProfileSettingsReset( - false /*send_feedback*/, mock_target.CreateClosure()); - ExpectAndServicePendingBrandcodedConfigFetch(false /*simulate_failure*/); - base::RunLoop().RunUntilIdle(); - - EXPECT_EQ(kTestBrandedHomepage, prefs->GetString(prefs::kHomePage)); -} - -TEST_F(AutomaticProfileResetterDelegateTest, - TriggerResetWithDefaultSettingsAlreadyLoaded) { - google_brand::BrandForTesting scoped_brand_for_testing(kTestBrandcode); - - PrefService* prefs = profile()->GetPrefs(); - DCHECK(prefs); - prefs->SetString(prefs::kHomePage, kTestHomepage); - - resetter_delegate()->FetchBrandcodedDefaultSettingsIfNeeded(); - ExpectAndServicePendingBrandcodedConfigFetch(false /*simulate_failure*/); - base::RunLoop().RunUntilIdle(); - - testing::StrictMock<MockCallbackTarget> mock_target; - EXPECT_CALL(mock_target, Run()); - EXPECT_CALL(*resetter_delegate(), SendFeedback(testing::_)).Times(0); - resetter_delegate()->TriggerProfileSettingsReset( - false /*send_feedback*/, mock_target.CreateClosure()); - base::RunLoop().RunUntilIdle(); - - EXPECT_EQ(kTestBrandedHomepage, prefs->GetString(prefs::kHomePage)); -} - -TEST_F(AutomaticProfileResetterDelegateTest, - TriggerResetAndSendFeedback) { - google_brand::BrandForTesting scoped_brand_for_testing(kTestBrandcode); - - PrefService* prefs = profile()->GetPrefs(); - DCHECK(prefs); - prefs->SetString(prefs::kHomePage, kTestHomepage); - - testing::StrictMock<MockCallbackTarget> mock_target; - EXPECT_CALL(mock_target, Run()); - EXPECT_CALL(*resetter_delegate(), - SendFeedback(testing::HasSubstr(kTestHomepage))); - - resetter_delegate()->TriggerProfileSettingsReset( - true /*send_feedback*/, mock_target.CreateClosure()); - ExpectAndServicePendingBrandcodedConfigFetch(false /*simulate_failure*/); - base::RunLoop().RunUntilIdle(); -} - -TEST_F(AutomaticProfileResetterDelegateTest, ShowAndDismissPrompt) { - resetter_delegate()->TriggerPrompt(); - if (ProfileResetGlobalError::IsSupportedOnPlatform()) - ExpectResetPromptState(true /*active*/); - else - ExpectResetPromptState(false /*active*/); - resetter_delegate()->DismissPrompt(); - ExpectResetPromptState(false /*active*/); - resetter_delegate()->DismissPrompt(); -} - -} // namespace
diff --git a/chrome/browser/profile_resetter/automatic_profile_resetter_factory.cc b/chrome/browser/profile_resetter/automatic_profile_resetter_factory.cc deleted file mode 100644 index f025ce46..0000000 --- a/chrome/browser/profile_resetter/automatic_profile_resetter_factory.cc +++ /dev/null
@@ -1,70 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/profile_resetter/automatic_profile_resetter_factory.h" - -#include "base/memory/singleton.h" -#include "base/prefs/pref_registry_simple.h" -#include "chrome/browser/profile_resetter/automatic_profile_resetter.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/search_engines/template_url_service_factory.h" -#include "chrome/browser/ui/global_error/global_error_service_factory.h" -#include "chrome/common/pref_names.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/pref_registry/pref_registry_syncable.h" -#include "content/public/browser/browser_context.h" - -// static -AutomaticProfileResetter* AutomaticProfileResetterFactory::GetForBrowserContext( - content::BrowserContext* context) { - return static_cast<AutomaticProfileResetter*>( - GetInstance()->GetServiceForBrowserContext(context, true)); -} - -// static -AutomaticProfileResetterFactory* -AutomaticProfileResetterFactory::GetInstance() { - return base::Singleton<AutomaticProfileResetterFactory>::get(); -} - -// static -void AutomaticProfileResetterFactory::RegisterPrefs( - PrefRegistrySimple* registry) { - registry->RegisterDictionaryPref( - prefs::kProfileResetPromptMementosInLocalState); -} - -AutomaticProfileResetterFactory::AutomaticProfileResetterFactory() - : BrowserContextKeyedServiceFactory( - "AutomaticProfileResetter", - BrowserContextDependencyManager::GetInstance()) { - DependsOn(TemplateURLServiceFactory::GetInstance()); - DependsOn(GlobalErrorServiceFactory::GetInstance()); -} - -AutomaticProfileResetterFactory::~AutomaticProfileResetterFactory() {} - -KeyedService* AutomaticProfileResetterFactory::BuildServiceInstanceFor( - content::BrowserContext* context) const { - Profile* profile = Profile::FromBrowserContext(context); - AutomaticProfileResetter* service = new AutomaticProfileResetter(profile); - service->Initialize(); - service->Activate(); - return service; -} - -void AutomaticProfileResetterFactory::RegisterProfilePrefs( - user_prefs::PrefRegistrySyncable* registry) { - registry->RegisterStringPref(prefs::kProfileResetPromptMementoInProfilePrefs, - ""); -} - -bool AutomaticProfileResetterFactory:: - ServiceIsCreatedWithBrowserContext() const { - return true; -} - -bool AutomaticProfileResetterFactory::ServiceIsNULLWhileTesting() const { - return true; -}
diff --git a/chrome/browser/profile_resetter/automatic_profile_resetter_factory.h b/chrome/browser/profile_resetter/automatic_profile_resetter_factory.h deleted file mode 100644 index bbf8012d..0000000 --- a/chrome/browser/profile_resetter/automatic_profile_resetter_factory.h +++ /dev/null
@@ -1,57 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_FACTORY_H_ -#define CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_FACTORY_H_ - -#include "base/basictypes.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -namespace base { -template <typename T> -struct DefaultSingletonTraits; -} // namespace base - -class PrefRegistrySimple; - -namespace content { -class BrowserContext; -} - -namespace user_prefs { -class PrefRegistrySyncable; -} - -class AutomaticProfileResetter; - -class AutomaticProfileResetterFactory - : public BrowserContextKeyedServiceFactory { - public: - static AutomaticProfileResetter* GetForBrowserContext( - content::BrowserContext* context); - static AutomaticProfileResetterFactory* GetInstance(); - - // Registers Local State preferences. - static void RegisterPrefs(PrefRegistrySimple* registry); - - private: - friend struct base::DefaultSingletonTraits<AutomaticProfileResetterFactory>; - - AutomaticProfileResetterFactory(); - ~AutomaticProfileResetterFactory() override; - - // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( - content::BrowserContext* context) const override; - - // BrowserContextKeyedBaseFactory: - void RegisterProfilePrefs( - user_prefs::PrefRegistrySyncable* registry) override; - bool ServiceIsCreatedWithBrowserContext() const override; - bool ServiceIsNULLWhileTesting() const override; - - DISALLOW_COPY_AND_ASSIGN(AutomaticProfileResetterFactory); -}; - -#endif // CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_FACTORY_H_
diff --git a/chrome/browser/profile_resetter/automatic_profile_resetter_mementos.cc b/chrome/browser/profile_resetter/automatic_profile_resetter_mementos.cc deleted file mode 100644 index b4e9446..0000000 --- a/chrome/browser/profile_resetter/automatic_profile_resetter_mementos.cc +++ /dev/null
@@ -1,129 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/profile_resetter/automatic_profile_resetter_mementos.h" - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/logging.h" -#include "base/prefs/pref_service.h" -#include "base/prefs/scoped_user_pref_update.h" -#include "base/values.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/common/chrome_constants.h" -#include "chrome/common/pref_names.h" -#include "content/public/browser/browser_thread.h" - -using base::DictionaryValue; - - -// AutomaticProfileResetter::PreferenceHostedPromptMemento ------------------- - -PreferenceHostedPromptMemento::PreferenceHostedPromptMemento(Profile* profile) - : profile_(profile) {} - -PreferenceHostedPromptMemento::~PreferenceHostedPromptMemento() {} - -std::string PreferenceHostedPromptMemento::ReadValue() const { - PrefService* prefs = profile_->GetPrefs(); - DCHECK(prefs); - return prefs->GetString(prefs::kProfileResetPromptMementoInProfilePrefs); -} - -void PreferenceHostedPromptMemento::StoreValue(const std::string& value) { - PrefService* prefs = profile_->GetPrefs(); - DCHECK(prefs); - prefs->SetString(prefs::kProfileResetPromptMementoInProfilePrefs, value); -} - - -// AutomaticProfileResetter::LocalStateHostedPromptMemento ------------------- - -LocalStateHostedPromptMemento::LocalStateHostedPromptMemento(Profile* profile) - : profile_(profile) {} - -LocalStateHostedPromptMemento::~LocalStateHostedPromptMemento() {} - -std::string LocalStateHostedPromptMemento::ReadValue() const { - PrefService* local_state = g_browser_process->local_state(); - DCHECK(local_state); - - const base::DictionaryValue* prompt_shown_dict = local_state->GetDictionary( - prefs::kProfileResetPromptMementosInLocalState); - std::string profile_key = GetProfileKey(); - if (!prompt_shown_dict || profile_key.empty()) { - NOTREACHED(); - return std::string(); - } - std::string value; - return prompt_shown_dict->GetStringWithoutPathExpansion(profile_key, &value) ? - value : std::string(); -} - -void LocalStateHostedPromptMemento::StoreValue(const std::string& value) { - PrefService* local_state = g_browser_process->local_state(); - DCHECK(local_state); - - DictionaryPrefUpdate prompt_shown_dict_update( - local_state, prefs::kProfileResetPromptMementosInLocalState); - std::string profile_key = GetProfileKey(); - if (profile_key.empty()) { - NOTREACHED(); - return; - } - prompt_shown_dict_update.Get()->SetStringWithoutPathExpansion(profile_key, - value); -} - -std::string LocalStateHostedPromptMemento::GetProfileKey() const { - return profile_->GetPath().BaseName().MaybeAsASCII(); -} - - -// AutomaticProfileResetter::FileHostedPromptMemento ------------------------- - -FileHostedPromptMemento::FileHostedPromptMemento(Profile* profile) - : profile_(profile) {} - -FileHostedPromptMemento::~FileHostedPromptMemento() {} - -void FileHostedPromptMemento::ReadValue( - const ReadValueCallback& callback) const { - base::FilePath path = GetMementoFilePath(); - content::BrowserThread::PostTaskAndReplyWithResult( - content::BrowserThread::FILE, - FROM_HERE, - base::Bind(&ReadValueOnFileThread, path), - callback); -} - -void FileHostedPromptMemento::StoreValue(const std::string& value) { - base::FilePath path = GetMementoFilePath(); - content::BrowserThread::PostTask( - content::BrowserThread::FILE, - FROM_HERE, - base::Bind(&StoreValueOnFileThread, path, value)); -} - -std::string FileHostedPromptMemento::ReadValueOnFileThread( - const base::FilePath& memento_file_path) { - std::string value; - base::ReadFileToString(memento_file_path, &value); - return value; -} - -void FileHostedPromptMemento::StoreValueOnFileThread( - const base::FilePath& memento_file_path, - const std::string& value) { - int retval = - base::WriteFile(memento_file_path, value.c_str(), value.size()); - DCHECK_EQ(retval, (int)value.size()); -} - -base::FilePath FileHostedPromptMemento::GetMementoFilePath() const { - return profile_->GetPath().Append(chrome::kResetPromptMementoFilename); -}
diff --git a/chrome/browser/profile_resetter/automatic_profile_resetter_mementos.h b/chrome/browser/profile_resetter/automatic_profile_resetter_mementos.h deleted file mode 100644 index 025ffb22..0000000 --- a/chrome/browser/profile_resetter/automatic_profile_resetter_mementos.h +++ /dev/null
@@ -1,101 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// The classes in this file are alternative implementations of the concept of a -// "prompt memento", a token of some kind that gets stored when we show the -// one-time profile reset prompt, and which then serves as a reminder that we -// should not show the prompt again. -// -// In an ideal world, a single implementation would suffice, however, we expect -// that third party software might accidentally interfere with some of these -// methods. We need this redundancy because we want to make absolutely sure that -// we do not annoy the user with the prompt multiple times. - -#ifndef CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_MEMENTOS_H_ -#define CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_MEMENTOS_H_ - -#include <string> - -#include "base/basictypes.h" -#include "base/callback.h" - -namespace base { -class FilePath; -} - -class Profile; - -// This class is a wrapper around the user preference that gets stored when we -// show the one-time profile reset prompt, and which is kept as a reminder that -// we should not show the prompt again. -class PreferenceHostedPromptMemento { - public: - explicit PreferenceHostedPromptMemento(Profile* profile); - ~PreferenceHostedPromptMemento(); - - std::string ReadValue() const; - void StoreValue(const std::string& value); - - private: - Profile* profile_; - - DISALLOW_COPY_AND_ASSIGN(PreferenceHostedPromptMemento); -}; - -// This class is a wrapper around the Local State preference that gets stored -// when we show the one-time profile reset prompt, and which is kept as a -// reminder that we should not show the prompt again. -class LocalStateHostedPromptMemento { - public: - explicit LocalStateHostedPromptMemento(Profile* profile); - ~LocalStateHostedPromptMemento(); - - std::string ReadValue() const; - void StoreValue(const std::string& value); - - private: - // Returns the key that shall be used in the dictionary preference in Local - // State to uniquely identify this profile. - std::string GetProfileKey() const; - - Profile* profile_; - - DISALLOW_COPY_AND_ASSIGN(LocalStateHostedPromptMemento); -}; - -// This class manages a marker file that gets stored when we show the one-time -// profile reset prompt, and which is kept as a reminder that we should not show -// the prompt again. -class FileHostedPromptMemento { - public: - typedef base::Callback<void(const std::string&)> ReadValueCallback; - - explicit FileHostedPromptMemento(Profile* profile); - ~FileHostedPromptMemento(); - - // Posts to the FILE thread to read the value, then returns the value to the - // calling thread. It is safe to destroy this object as soon as this method - // (synchronously) returns. - void ReadValue(const ReadValueCallback& callback) const; - - // Asynchronously stores the value on the FILE thread. However, it is safe to - // destroy this object as soon as this method (synchronously) returns. - void StoreValue(const std::string& value); - - private: - static std::string ReadValueOnFileThread( - const base::FilePath& memento_file_path); - static void StoreValueOnFileThread(const base::FilePath& memento_file_path, - const std::string& value); - - // Returns the path to the file that shall be used to store this kind of - // memento for this profile. - base::FilePath GetMementoFilePath() const; - - Profile* profile_; - - DISALLOW_COPY_AND_ASSIGN(FileHostedPromptMemento); -}; - -#endif // CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_MEMENTOS_H_
diff --git a/chrome/browser/profile_resetter/automatic_profile_resetter_unittest.cc b/chrome/browser/profile_resetter/automatic_profile_resetter_unittest.cc deleted file mode 100644 index 046d7de7..0000000 --- a/chrome/browser/profile_resetter/automatic_profile_resetter_unittest.cc +++ /dev/null
@@ -1,1377 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/profile_resetter/automatic_profile_resetter.h" - -#include <string> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/metrics/field_trial.h" -#include "base/prefs/pref_registry_simple.h" -#include "base/prefs/testing_pref_service.h" -#include "base/run_loop.h" -#include "base/test/test_simple_task_runner.h" -#include "base/threading/sequenced_worker_pool.h" -#include "base/values.h" -#include "chrome/browser/profile_resetter/automatic_profile_resetter_delegate.h" -#include "chrome/browser/profile_resetter/automatic_profile_resetter_factory.h" -#include "chrome/browser/profile_resetter/automatic_profile_resetter_mementos.h" -#include "chrome/browser/profile_resetter/jtl_foundation.h" -#include "chrome/browser/profile_resetter/jtl_instructions.h" -#include "chrome/test/base/scoped_testing_local_state.h" -#include "chrome/test/base/testing_browser_process.h" -#include "chrome/test/base/testing_profile.h" -#include "components/pref_registry/pref_registry_syncable.h" -#include "components/syncable_prefs/testing_pref_service_syncable.h" -#include "components/variations/variations_associated_data.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/test/test_browser_thread_bundle.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using testing::_; - -namespace { - -const char kAutomaticProfileResetStudyName[] = "AutomaticProfileReset"; -const char kStudyDisabledGroupName[] = "Disabled"; -const char kStudyDryRunGroupName[] = "DryRun"; -const char kStudyEnabledGroupName[] = "Enabled"; - -const char kTestHashSeed[] = "testing-hash-seed"; -const char kTestMementoValue[] = "01234567890123456789012345678901"; -const char kTestInvalidMementoValue[] = "12345678901234567890123456789012"; - -const char kTestPreferencePath[] = "testing.preference"; -const char kTestPreferenceValue[] = "testing-preference-value"; - -const char kSearchURLAttributeKey[] = "search_url"; -const char kTestSearchURL[] = "http://example.com/search?q={searchTerms}"; -const char kTestSearchURL2[] = "http://google.com/?q={searchTerms}"; - -const char kTestModuleDigest[] = "01234567890123456789012345678901"; -const char kTestModuleDigest2[] = "12345678901234567890123456789012"; - -// Helpers ------------------------------------------------------------------ - -// A testing version of the AutomaticProfileResetter that differs from the real -// one only in that it has its statistics reporting mocked out for verification. -class AutomaticProfileResetterUnderTest : public AutomaticProfileResetter { - public: - explicit AutomaticProfileResetterUnderTest(Profile* profile) - : AutomaticProfileResetter(profile) {} - ~AutomaticProfileResetterUnderTest() override {} - - MOCK_METHOD2(ReportStatistics, void(uint32, uint32)); - MOCK_METHOD1(ReportPromptResult, - void(AutomaticProfileResetter::PromptResult)); - - private: - DISALLOW_COPY_AND_ASSIGN(AutomaticProfileResetterUnderTest); -}; - -class MockProfileResetterDelegate : public AutomaticProfileResetterDelegate { - public: - MockProfileResetterDelegate() - : emulated_is_default_search_provider_managed_(false) {} - ~MockProfileResetterDelegate() override {} - - MOCK_METHOD0(EnumerateLoadedModulesIfNeeded, void()); - MOCK_CONST_METHOD1(RequestCallbackWhenLoadedModulesAreEnumerated, - void(const base::Closure&)); - - MOCK_METHOD0(LoadTemplateURLServiceIfNeeded, void()); - MOCK_CONST_METHOD1(RequestCallbackWhenTemplateURLServiceIsLoaded, - void(const base::Closure&)); - - MOCK_METHOD0(FetchBrandcodedDefaultSettingsIfNeeded, void()); - MOCK_CONST_METHOD1(RequestCallbackWhenBrandcodedDefaultsAreFetched, - void(const base::Closure&)); - - MOCK_CONST_METHOD0(OnGetLoadedModuleNameDigestsCalled, void()); - MOCK_CONST_METHOD0(OnGetDefaultSearchProviderDetailsCalled, void()); - MOCK_CONST_METHOD0(OnIsDefaultSearchProviderManagedCalled, void()); - MOCK_CONST_METHOD0(OnGetPrepopulatedSearchProvidersDetailsCalled, void()); - - MOCK_METHOD0(TriggerPrompt, bool()); - MOCK_METHOD2(TriggerProfileSettingsReset, void(bool, const base::Closure&)); - MOCK_METHOD0(DismissPrompt, void()); - - scoped_ptr<base::ListValue> GetLoadedModuleNameDigests() const override { - OnGetLoadedModuleNameDigestsCalled(); - return scoped_ptr<base::ListValue>( - emulated_loaded_module_digests_.DeepCopy()); - } - - scoped_ptr<base::DictionaryValue> - GetDefaultSearchProviderDetails() const override { - OnGetDefaultSearchProviderDetailsCalled(); - return scoped_ptr<base::DictionaryValue>( - emulated_default_search_provider_details_.DeepCopy()); - } - - bool IsDefaultSearchProviderManaged() const override { - OnIsDefaultSearchProviderManagedCalled(); - return emulated_is_default_search_provider_managed_; - } - - scoped_ptr<base::ListValue> - GetPrepopulatedSearchProvidersDetails() const override { - OnGetPrepopulatedSearchProvidersDetailsCalled(); - return scoped_ptr<base::ListValue>( - emulated_search_providers_details_.DeepCopy()); - } - - static void ClosureInvoker(const base::Closure& closure) { closure.Run(); } - - void ExpectCallsToDependenciesSetUpMethods() { - EXPECT_CALL(*this, EnumerateLoadedModulesIfNeeded()); - EXPECT_CALL(*this, LoadTemplateURLServiceIfNeeded()); - EXPECT_CALL(*this, RequestCallbackWhenLoadedModulesAreEnumerated(_)) - .WillOnce(testing::Invoke(ClosureInvoker)); - EXPECT_CALL(*this, RequestCallbackWhenTemplateURLServiceIsLoaded(_)) - .WillOnce(testing::Invoke(ClosureInvoker)); - } - - void ExpectCallsToGetterMethods() { - EXPECT_CALL(*this, OnGetLoadedModuleNameDigestsCalled()); - EXPECT_CALL(*this, OnGetDefaultSearchProviderDetailsCalled()); - EXPECT_CALL(*this, OnIsDefaultSearchProviderManagedCalled()); - EXPECT_CALL(*this, OnGetPrepopulatedSearchProvidersDetailsCalled()); - } - - void ExpectCallToShowPrompt() { - EXPECT_CALL(*this, TriggerPrompt()).WillOnce(testing::Return(true)); - EXPECT_CALL(*this, FetchBrandcodedDefaultSettingsIfNeeded()); - } - - void ExpectCallToTriggerReset(bool send_feedback) { - EXPECT_CALL(*this, TriggerProfileSettingsReset(send_feedback, _)) - .WillOnce(testing::SaveArg<1>(&reset_completion_)); - } - - base::DictionaryValue& emulated_default_search_provider_details() { - return emulated_default_search_provider_details_; - } - - base::ListValue& emulated_search_providers_details() { - return emulated_search_providers_details_; - } - - base::ListValue& emulated_loaded_module_digests() { - return emulated_loaded_module_digests_; - } - - void set_emulated_is_default_search_provider_managed(bool value) { - emulated_is_default_search_provider_managed_ = value; - } - - void EmulateProfileResetCompleted() { - reset_completion_.Run(); - } - - private: - base::DictionaryValue emulated_default_search_provider_details_; - base::ListValue emulated_search_providers_details_; - base::ListValue emulated_loaded_module_digests_; - bool emulated_is_default_search_provider_managed_; - base::Closure reset_completion_; - - DISALLOW_COPY_AND_ASSIGN(MockProfileResetterDelegate); -}; - -class FileHostedPromptMementoSynchronous : protected FileHostedPromptMemento { - public: - explicit FileHostedPromptMementoSynchronous(Profile* profile) - : FileHostedPromptMemento(profile) {} - - std::string ReadValue() const { - std::string result; - FileHostedPromptMemento::ReadValue(base::Bind(&AssignArgumentTo, &result)); - base::RunLoop().RunUntilIdle(); - return result; - } - - void StoreValue(const std::string& value) { - FileHostedPromptMemento::StoreValue(value); - base::RunLoop().RunUntilIdle(); - } - - private: - static void AssignArgumentTo(std::string* target, const std::string& value) { - *target = value; - } - - DISALLOW_COPY_AND_ASSIGN(FileHostedPromptMementoSynchronous); -}; - -std::string GetHash(const std::string& input) { - return jtl_foundation::Hasher(kTestHashSeed).GetHash(input); -} - -// Encodes a Boolean argument value into JTL bytecode. -std::string EncodeBool(bool value) { return value ? VALUE_TRUE : VALUE_FALSE; } - -// Constructs a simple evaluation program to test that basic input/output works -// well. It will emulate a scenario in which the reset criteria are satisfied as -// prescribed by |emulate_satisfied_criterion_{1|2}|, and the reset is triggered -// when either of them is true. The bits in the combined status mask will be set -// according to whether or not the memento values received in the input were as -// expected. -// -// More specifically, the output of the program will be as follows: -// { -// "satisfied_criteria_mask_bit1": emulate_satisfied_criterion_1, -// "satisfied_criteria_mask_bit2": emulate_satisfied_criterion_2, -// "combined_status_mask_bit1": -// (emulate_satisfied_criterion_1 || emulate_satisfied_criterion_2), -// "combined_status_mask_bit2": -// (input["memento_value_in_prefs"] == kTestMementoValue), -// "combined_status_mask_bit3": -// (input["memento_value_in_local_state"] == kTestMementoValue), -// "combined_status_mask_bit4": -// (input["memento_value_in_file"] == kTestMementoValue), -// "should_prompt": -// (emulate_satisfied_criterion_1 || emulate_satisfied_criterion_2), -// "had_prompted_already": <OR-combination of above three>, -// "memento_value_in_prefs": kTestMementoValue, -// "memento_value_in_local_state": kTestMementoValue, -// "memento_value_in_file": kTestMementoValue -// } -std::string ConstructProgram(bool emulate_satisfied_criterion_1, - bool emulate_satisfied_criterion_2) { - std::string bytecode; - bytecode += OP_STORE_BOOL(GetHash("satisfied_criteria_mask_bit1"), - EncodeBool(emulate_satisfied_criterion_1)); - bytecode += OP_END_OF_SENTENCE; - bytecode += OP_STORE_BOOL(GetHash("satisfied_criteria_mask_bit2"), - EncodeBool(emulate_satisfied_criterion_2)); - bytecode += OP_END_OF_SENTENCE; - bytecode += OP_STORE_BOOL(GetHash("should_prompt"), - EncodeBool(emulate_satisfied_criterion_1 || - emulate_satisfied_criterion_2)); - bytecode += OP_END_OF_SENTENCE; - bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit1"), - EncodeBool(emulate_satisfied_criterion_1 || - emulate_satisfied_criterion_2)); - bytecode += OP_END_OF_SENTENCE; - bytecode += OP_NAVIGATE(GetHash("memento_value_in_prefs")); - bytecode += OP_COMPARE_NODE_HASH(GetHash(kTestMementoValue)); - bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit2"), VALUE_TRUE); - bytecode += OP_STORE_BOOL(GetHash("had_prompted_already"), VALUE_TRUE); - bytecode += OP_END_OF_SENTENCE; - bytecode += OP_NAVIGATE(GetHash("memento_value_in_local_state")); - bytecode += OP_COMPARE_NODE_HASH(GetHash(kTestMementoValue)); - bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit3"), VALUE_TRUE); - bytecode += OP_STORE_BOOL(GetHash("had_prompted_already"), VALUE_TRUE); - bytecode += OP_END_OF_SENTENCE; - bytecode += OP_NAVIGATE(GetHash("memento_value_in_file")); - bytecode += OP_COMPARE_NODE_HASH(GetHash(kTestMementoValue)); - bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit4"), VALUE_TRUE); - bytecode += OP_STORE_BOOL(GetHash("had_prompted_already"), VALUE_TRUE); - bytecode += OP_END_OF_SENTENCE; - bytecode += OP_STORE_HASH(GetHash("memento_value_in_prefs"), - kTestMementoValue); - bytecode += OP_END_OF_SENTENCE; - bytecode += OP_STORE_HASH(GetHash("memento_value_in_local_state"), - kTestMementoValue); - bytecode += OP_END_OF_SENTENCE; - bytecode += OP_STORE_HASH(GetHash("memento_value_in_file"), - kTestMementoValue); - bytecode += OP_END_OF_SENTENCE; - return bytecode; -} - -// Constructs another evaluation program to specifically test that bits of the -// "satisfied_criteria_mask" are correctly assigned, and so is "should_prompt"; -// and that reset is triggered iff the latter is true, regardless of the bits -// in the mask (so as to allow for a non-disjunctive compound criterion). -// -// More specifically, the output of the program will be as follows: -// { -// "satisfied_criteria_mask_bitN": emulate_satisfied_odd_criteria, -// "satisfied_criteria_mask_bitM": emulate_satisfied_even_criteria, -// "combined_status_mask_bit1": emulate_should_prompt, -// "should_prompt": emulate_should_prompt, -// "memento_value_in_prefs": kTestMementoValue, -// "memento_value_in_local_state": kTestMementoValue, -// "memento_value_in_file": kTestMementoValue -// } -// ... such that N is {1,3,5} and M is {2,4}. -std::string ConstructProgramToExerciseCriteria( - bool emulate_should_prompt, - bool emulate_satisfied_odd_criteria, - bool emulate_satisfied_even_criteria) { - std::string bytecode; - bytecode += OP_STORE_BOOL(GetHash("satisfied_criteria_mask_bit1"), - EncodeBool(emulate_satisfied_odd_criteria)); - bytecode += OP_END_OF_SENTENCE; - bytecode += OP_STORE_BOOL(GetHash("satisfied_criteria_mask_bit3"), - EncodeBool(emulate_satisfied_odd_criteria)); - bytecode += OP_END_OF_SENTENCE; - bytecode += OP_STORE_BOOL(GetHash("satisfied_criteria_mask_bit5"), - EncodeBool(emulate_satisfied_odd_criteria)); - bytecode += OP_END_OF_SENTENCE; - bytecode += OP_STORE_BOOL(GetHash("satisfied_criteria_mask_bit2"), - EncodeBool(emulate_satisfied_even_criteria)); - bytecode += OP_END_OF_SENTENCE; - bytecode += OP_STORE_BOOL(GetHash("satisfied_criteria_mask_bit4"), - EncodeBool(emulate_satisfied_even_criteria)); - bytecode += OP_END_OF_SENTENCE; - bytecode += OP_STORE_BOOL(GetHash("should_prompt"), - EncodeBool(emulate_should_prompt)); - bytecode += OP_END_OF_SENTENCE; - bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit1"), - EncodeBool(emulate_should_prompt)); - bytecode += OP_END_OF_SENTENCE; - bytecode += OP_STORE_HASH(GetHash("memento_value_in_prefs"), - kTestMementoValue); - bytecode += OP_END_OF_SENTENCE; - bytecode += OP_STORE_HASH(GetHash("memento_value_in_local_state"), - kTestMementoValue); - bytecode += OP_END_OF_SENTENCE; - bytecode += OP_STORE_HASH(GetHash("memento_value_in_file"), - kTestMementoValue); - bytecode += OP_END_OF_SENTENCE; - return bytecode; -} - -// Constructs another evaluation program to specifically test that local state -// and user preference values are included in the input as expected. We will -// re-purpose the output bitmasks to channel out information about the outcome -// of the checks. -// -// More specifically, the output of the program will be as follows: -// { -// "combined_status_mask_bit1": -// (input["preferences.testing.preference"] == kTestPreferenceValue) -// "combined_status_mask_bit2": -// (input["local_state.testing.preference"] == kTestPreferenceValue) -// "combined_status_mask_bit3": input["preferences_iuc.testing.preference"] -// "combined_status_mask_bit4": input["local_state_iuc.testing.preference"] -// } -std::string ConstructProgramToCheckPreferences() { - std::string bytecode; - bytecode += OP_NAVIGATE(GetHash("preferences")); - bytecode += OP_NAVIGATE(GetHash("testing")); - bytecode += OP_NAVIGATE(GetHash("preference")); - bytecode += OP_COMPARE_NODE_HASH(GetHash(kTestPreferenceValue)); - bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit1"), - EncodeBool(true)); - bytecode += OP_END_OF_SENTENCE; - bytecode += OP_NAVIGATE(GetHash("local_state")); - bytecode += OP_NAVIGATE(GetHash("testing")); - bytecode += OP_NAVIGATE(GetHash("preference")); - bytecode += OP_COMPARE_NODE_HASH(GetHash(kTestPreferenceValue)); - bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit2"), - EncodeBool(true)); - bytecode += OP_END_OF_SENTENCE; - bytecode += OP_NAVIGATE(GetHash("preferences_iuc")); - bytecode += OP_NAVIGATE(GetHash("testing")); - bytecode += OP_NAVIGATE(GetHash("preference")); - bytecode += OP_COMPARE_NODE_BOOL(EncodeBool(true)); - bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit3"), - EncodeBool(true)); - bytecode += OP_END_OF_SENTENCE; - bytecode += OP_NAVIGATE(GetHash("local_state_iuc")); - bytecode += OP_NAVIGATE(GetHash("testing")); - bytecode += OP_NAVIGATE(GetHash("preference")); - bytecode += OP_COMPARE_NODE_BOOL(EncodeBool(true)); - bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit4"), - EncodeBool(true)); - bytecode += OP_END_OF_SENTENCE; - return bytecode; -} - -// Legend for the bitmask returned by the above program. -enum CombinedStatusMaskLegendForCheckingPreferences { - HAS_EXPECTED_USER_PREFERENCE = 1 << 0, - HAS_EXPECTED_LOCAL_STATE_PREFERENCE = 1 << 1, - USER_PREFERENCE_IS_USER_CONTROLLED = 1 << 2, - LOCAL_STATE_IS_USER_CONTROLLED = 1 << 3, -}; - -// Constructs yet another evaluation program to specifically test that default -// and pre-populated search engines are included in the input as expected. We -// will re-purpose the output bitmasks to channel out information about the -// outcome of the checks. -// -// More specifically, the output of the program will be as follows: -// { -// "combined_status_mask_bit1": -// (input["default_search_provider.search_url"] == kTestSearchURL) -// "combined_status_mask_bit2": input["default_search_provider_iuc"] -// "combined_status_mask_bit3": -// (input["search_providers.*.search_url"] == kTestSearchURL) -// "combined_status_mask_bit4": -// (input["search_providers.*.search_url"] == kTestSearchURL2) -// } -std::string ConstructProgramToCheckSearchEngines() { - std::string bytecode; - bytecode += OP_NAVIGATE(GetHash("default_search_provider")); - bytecode += OP_NAVIGATE(GetHash("search_url")); - bytecode += OP_COMPARE_NODE_HASH(GetHash(kTestSearchURL)); - bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit1"), - EncodeBool(true)); - bytecode += OP_END_OF_SENTENCE; - bytecode += OP_NAVIGATE(GetHash("default_search_provider_iuc")); - bytecode += OP_COMPARE_NODE_BOOL(EncodeBool(true)); - bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit2"), - EncodeBool(true)); - bytecode += OP_END_OF_SENTENCE; - bytecode += OP_NAVIGATE(GetHash("search_providers")); - bytecode += OP_NAVIGATE_ANY; - bytecode += OP_NAVIGATE(GetHash("search_url")); - bytecode += OP_COMPARE_NODE_HASH(GetHash(kTestSearchURL)); - bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit3"), - EncodeBool(true)); - bytecode += OP_END_OF_SENTENCE; - bytecode += OP_NAVIGATE(GetHash("search_providers")); - bytecode += OP_NAVIGATE_ANY; - bytecode += OP_NAVIGATE(GetHash("search_url")); - bytecode += OP_COMPARE_NODE_HASH(GetHash(kTestSearchURL2)); - bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit4"), - EncodeBool(true)); - bytecode += OP_END_OF_SENTENCE; - return bytecode; -} - -// Legend for the bitmask returned by the above program. -enum CombinedStatusMaskLegendForCheckingSearchEngines { - HAS_EXPECTED_DEFAULT_SEARCH_PROVIDER = 1 << 0, - DEFAULT_SEARCH_PROVIDER_IS_USER_CONTROLLED = 1 << 1, - HAS_EXPECTED_PREPOPULATED_SEARCH_PROVIDER_1 = 1 << 2, - HAS_EXPECTED_PREPOPULATED_SEARCH_PROVIDER_2 = 1 << 3, -}; - -// Constructs yet another evaluation program to specifically test that loaded -// module digests are included in the input as expected. We will re-purpose the -// output bitmasks to channel out information about the outcome of the checks. -// -// More specifically, the output of the program will be as follows: -// { -// "combined_status_mask_bit1": -// (input["loaded_modules.*"] == kTestModuleDigest) -// "combined_status_mask_bit2": -// (input["loaded_modules.*"] == kTestModuleDigest2) -// } -std::string ConstructProgramToCheckLoadedModuleDigests() { - std::string bytecode; - bytecode += OP_NAVIGATE(GetHash("loaded_modules")); - bytecode += OP_NAVIGATE_ANY; - bytecode += OP_COMPARE_NODE_HASH(GetHash(kTestModuleDigest)); - bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit1"), - EncodeBool(true)); - bytecode += OP_END_OF_SENTENCE; - bytecode += OP_NAVIGATE(GetHash("loaded_modules")); - bytecode += OP_NAVIGATE_ANY; - bytecode += OP_COMPARE_NODE_HASH(GetHash(kTestModuleDigest2)); - bytecode += OP_STORE_BOOL(GetHash("combined_status_mask_bit2"), - EncodeBool(true)); - bytecode += OP_END_OF_SENTENCE; - return bytecode; -} - -// Legend for the bitmask returned by the above program. -enum CombinedStatusMaskLegendForCheckingLoadedModules { - HAS_EXPECTED_MODULE_DIGEST_1 = 1 << 0, - HAS_EXPECTED_MODULE_DIGEST_2 = 1 << 1, -}; - -// Test fixtures ------------------------------------------------------------- - -class AutomaticProfileResetterTestBase : public testing::Test { - protected: - explicit AutomaticProfileResetterTestBase( - const std::string& experiment_group_name) - : waiting_task_runner_(new base::TestSimpleTaskRunner), - local_state_(TestingBrowserProcess::GetGlobal()), - profile_(new TestingProfile()), - field_trials_(new base::FieldTrialList(NULL)), - memento_in_prefs_(new PreferenceHostedPromptMemento(profile())), - memento_in_local_state_(new LocalStateHostedPromptMemento(profile())), - memento_in_file_(new FileHostedPromptMementoSynchronous(profile())), - experiment_group_name_(experiment_group_name), - inject_data_through_variation_params_(false), - mock_delegate_(NULL) { - // Make sure the factory is not optimized away, so whatever preferences it - // wants to register will actually get registered. - AutomaticProfileResetterFactory::GetInstance(); - - // Register some additional local state preferences for testing purposes. - PrefRegistrySimple* local_state_registry = local_state_.Get()->registry(); - DCHECK(local_state_registry); - local_state_registry->RegisterStringPref(kTestPreferencePath, ""); - - // Register some additional user preferences for testing purposes. - user_prefs::PrefRegistrySyncable* user_prefs_registry = - profile_->GetTestingPrefService()->registry(); - DCHECK(user_prefs_registry); - user_prefs_registry->RegisterStringPref(kTestPreferencePath, std::string()); - } - - void SetUp() override { - variations::testing::ClearAllVariationParams(); - base::FieldTrialList::CreateFieldTrial(kAutomaticProfileResetStudyName, - experiment_group_name_); - resetter_.reset( - new testing::StrictMock<AutomaticProfileResetterUnderTest>(profile())); - mock_delegate_owned_.reset( - new testing::StrictMock<MockProfileResetterDelegate>()); - mock_delegate_ = mock_delegate_owned_.get(); - - ExpectAllMementoValuesEqualTo(std::string()); - } - - void SetTestingHashSeed(const std::string& hash_seed) { - testing_hash_seed_ = hash_seed; - } - - void SetTestingProgram(const std::string& source_code) { - testing_program_ = source_code; - } - - void AllowInjectingTestDataThroughVariationParams(bool value) { - inject_data_through_variation_params_ = value; - } - - void ExpectAllMementoValuesEqualTo(const std::string& value) { - EXPECT_EQ(value, memento_in_prefs_->ReadValue()); - EXPECT_EQ(value, memento_in_local_state_->ReadValue()); - EXPECT_EQ(value, memento_in_file_->ReadValue()); - } - - void UnleashResetterAndWait() { - if (inject_data_through_variation_params_) { - std::map<std::string, std::string> variation_params; - variation_params["program"] = testing_program_; - variation_params["hash_seed"] = testing_hash_seed_; - ASSERT_TRUE(variations::AssociateVariationParams( - kAutomaticProfileResetStudyName, - experiment_group_name_, - variation_params)); - } - resetter_->Initialize(); - resetter_->SetDelegateForTesting(mock_delegate_owned_.Pass()); - resetter_->SetTaskRunnerForWaitingForTesting(waiting_task_runner_); - if (!inject_data_through_variation_params_) { - resetter_->SetProgramForTesting(testing_program_); - resetter_->SetHashSeedForTesting(testing_hash_seed_); - } - resetter_->Activate(); - - if (waiting_task_runner_->HasPendingTask()) { - ASSERT_EQ(base::TimeDelta::FromSeconds(55), - waiting_task_runner_->NextPendingTaskDelay()); - waiting_task_runner_->RunPendingTasks(); - } - base::RunLoop().RunUntilIdle(); - content::BrowserThread::GetBlockingPool()->FlushForTesting(); - base::RunLoop().RunUntilIdle(); - } - - // Goes through an evaluation flow such that the reset criteria are satisfied. - // Used to reduce boilerplate for tests that need to verify behavior during - // the reset prompt flow. - void OrchestrateThroughEvaluationFlow() { - SetTestingProgram(ConstructProgram(true, true)); - SetTestingHashSeed(kTestHashSeed); - - mock_delegate().ExpectCallsToDependenciesSetUpMethods(); - mock_delegate().ExpectCallsToGetterMethods(); - mock_delegate().ExpectCallToShowPrompt(); - EXPECT_CALL(resetter(), ReportStatistics(0x03u, 0x01u)); - - UnleashResetterAndWait(); - - EXPECT_TRUE(resetter().ShouldShowResetBanner()); - testing::Mock::VerifyAndClearExpectations(&resetter()); - testing::Mock::VerifyAndClearExpectations(&mock_delegate()); - } - - // Explicitly shut down the service to double-check that nothing explodes, but - // first, verify expectations to make sure the service makes no more calls to - // any mocked functions during or after shutdown. - void VerifyExpectationsThenShutdownResetter() { - testing::Mock::VerifyAndClearExpectations(&resetter()); - testing::Mock::VerifyAndClearExpectations(&mock_delegate()); - - resetter_->Shutdown(); - resetter_.reset(); - } - - TestingProfile* profile() { return profile_.get(); } - TestingPrefServiceSimple* local_state() { return local_state_.Get(); } - - PreferenceHostedPromptMemento& memento_in_prefs() { - return *memento_in_prefs_; - } - - LocalStateHostedPromptMemento& memento_in_local_state() { - return *memento_in_local_state_; - } - - FileHostedPromptMementoSynchronous& memento_in_file() { - return *memento_in_file_; - } - - MockProfileResetterDelegate& mock_delegate() { return *mock_delegate_; } - AutomaticProfileResetterUnderTest& resetter() { return *resetter_; } - - private: - content::TestBrowserThreadBundle thread_bundle_; - scoped_refptr<base::TestSimpleTaskRunner> waiting_task_runner_; - ScopedTestingLocalState local_state_; - scoped_ptr<TestingProfile> profile_; - scoped_ptr<base::FieldTrialList> field_trials_; - scoped_ptr<PreferenceHostedPromptMemento> memento_in_prefs_; - scoped_ptr<LocalStateHostedPromptMemento> memento_in_local_state_; - scoped_ptr<FileHostedPromptMementoSynchronous> memento_in_file_; - - std::string experiment_group_name_; - std::string testing_program_; - std::string testing_hash_seed_; - bool inject_data_through_variation_params_; - - scoped_ptr<AutomaticProfileResetterUnderTest> resetter_; - scoped_ptr<MockProfileResetterDelegate> mock_delegate_owned_; - MockProfileResetterDelegate* mock_delegate_; - - DISALLOW_COPY_AND_ASSIGN(AutomaticProfileResetterTestBase); -}; - -class AutomaticProfileResetterTest : public AutomaticProfileResetterTestBase { - protected: - AutomaticProfileResetterTest() - : AutomaticProfileResetterTestBase(kStudyEnabledGroupName) {} -}; - -class AutomaticProfileResetterTestDryRun - : public AutomaticProfileResetterTestBase { - protected: - AutomaticProfileResetterTestDryRun() - : AutomaticProfileResetterTestBase(kStudyDryRunGroupName) {} -}; - -class AutomaticProfileResetterTestDisabled - : public AutomaticProfileResetterTestBase { - protected: - AutomaticProfileResetterTestDisabled() - : AutomaticProfileResetterTestBase(kStudyDisabledGroupName) {} -}; - -// Tests --------------------------------------------------------------------- - -TEST_F(AutomaticProfileResetterTestDisabled, NothingIsDoneWhenDisabled) { - SetTestingProgram(ConstructProgram(true, true)); - SetTestingHashSeed(kTestHashSeed); - - // No calls are expected to the delegate. - - UnleashResetterAndWait(); - - EXPECT_FALSE(resetter().ShouldShowResetBanner()); - VerifyExpectationsThenShutdownResetter(); - - ExpectAllMementoValuesEqualTo(std::string()); -} - -TEST_F(AutomaticProfileResetterTestDryRun, CriteriaNotSatisfied) { - SetTestingProgram(ConstructProgramToExerciseCriteria(false, true, true)); - SetTestingHashSeed(kTestHashSeed); - - mock_delegate().ExpectCallsToDependenciesSetUpMethods(); - mock_delegate().ExpectCallsToGetterMethods(); - EXPECT_CALL(resetter(), ReportStatistics(0x1fu, 0x00u)); - - UnleashResetterAndWait(); - - EXPECT_FALSE(resetter().ShouldShowResetBanner()); - VerifyExpectationsThenShutdownResetter(); - - ExpectAllMementoValuesEqualTo(std::string()); -} - -TEST_F(AutomaticProfileResetterTestDryRun, OddCriteriaSatisfied) { - SetTestingProgram(ConstructProgramToExerciseCriteria(true, true, false)); - SetTestingHashSeed(kTestHashSeed); - - mock_delegate().ExpectCallsToDependenciesSetUpMethods(); - mock_delegate().ExpectCallsToGetterMethods(); - EXPECT_CALL(resetter(), ReportStatistics(0x15u, 0x01u)); - EXPECT_CALL(resetter(), ReportPromptResult( - AutomaticProfileResetter::PROMPT_NOT_TRIGGERED)); - - UnleashResetterAndWait(); - - ExpectAllMementoValuesEqualTo(kTestMementoValue); - EXPECT_FALSE(resetter().ShouldShowResetBanner()); - VerifyExpectationsThenShutdownResetter(); -} - -TEST_F(AutomaticProfileResetterTestDryRun, EvenCriteriaSatisfied) { - SetTestingProgram(ConstructProgramToExerciseCriteria(true, false, true)); - SetTestingHashSeed(kTestHashSeed); - - mock_delegate().ExpectCallsToDependenciesSetUpMethods(); - mock_delegate().ExpectCallsToGetterMethods(); - EXPECT_CALL(resetter(), ReportStatistics(0x0au, 0x01u)); - EXPECT_CALL(resetter(), ReportPromptResult( - AutomaticProfileResetter::PROMPT_NOT_TRIGGERED)); - - UnleashResetterAndWait(); - - ExpectAllMementoValuesEqualTo(kTestMementoValue); - EXPECT_FALSE(resetter().ShouldShowResetBanner()); - VerifyExpectationsThenShutdownResetter(); -} - -#if defined(GOOGLE_CHROME_BUILD) -TEST_F(AutomaticProfileResetterTestDryRun, ProgramSetThroughVariationParams) { - SetTestingProgram(ConstructProgram(true, true)); - SetTestingHashSeed(kTestHashSeed); - AllowInjectingTestDataThroughVariationParams(true); - - mock_delegate().ExpectCallsToDependenciesSetUpMethods(); - mock_delegate().ExpectCallsToGetterMethods(); - EXPECT_CALL(resetter(), ReportStatistics(0x03u, 0x01u)); - EXPECT_CALL(resetter(), ReportPromptResult( - AutomaticProfileResetter::PROMPT_NOT_TRIGGERED)); - - UnleashResetterAndWait(); - - ExpectAllMementoValuesEqualTo(kTestMementoValue); - EXPECT_FALSE(resetter().ShouldShowResetBanner()); - VerifyExpectationsThenShutdownResetter(); -} -#endif - -TEST_F(AutomaticProfileResetterTestDryRun, - ConditionsSatisfiedAndInvalidMementos) { - memento_in_prefs().StoreValue(kTestInvalidMementoValue); - memento_in_local_state().StoreValue(kTestInvalidMementoValue); - memento_in_file().StoreValue(kTestInvalidMementoValue); - - SetTestingProgram(ConstructProgram(true, true)); - SetTestingHashSeed(kTestHashSeed); - - mock_delegate().ExpectCallsToDependenciesSetUpMethods(); - mock_delegate().ExpectCallsToGetterMethods(); - EXPECT_CALL(resetter(), ReportStatistics(0x03u, 0x01u)); - EXPECT_CALL(resetter(), ReportPromptResult( - AutomaticProfileResetter::PROMPT_NOT_TRIGGERED)); - - UnleashResetterAndWait(); - - ExpectAllMementoValuesEqualTo(kTestMementoValue); - EXPECT_FALSE(resetter().ShouldShowResetBanner()); - VerifyExpectationsThenShutdownResetter(); -} - -TEST_F(AutomaticProfileResetterTestDryRun, AlreadyHadPrefHostedMemento) { - memento_in_prefs().StoreValue(kTestMementoValue); - - SetTestingProgram(ConstructProgram(true, true)); - SetTestingHashSeed(kTestHashSeed); - - mock_delegate().ExpectCallsToDependenciesSetUpMethods(); - mock_delegate().ExpectCallsToGetterMethods(); - EXPECT_CALL(resetter(), ReportStatistics(0x03u, 0x03u)); - - UnleashResetterAndWait(); - - EXPECT_FALSE(resetter().ShouldShowResetBanner()); - VerifyExpectationsThenShutdownResetter(); - - EXPECT_EQ(kTestMementoValue, memento_in_prefs().ReadValue()); - EXPECT_EQ(std::string(), memento_in_local_state().ReadValue()); - EXPECT_EQ(std::string(), memento_in_file().ReadValue()); -} - -TEST_F(AutomaticProfileResetterTestDryRun, AlreadyHadLocalStateHostedMemento) { - memento_in_local_state().StoreValue(kTestMementoValue); - - SetTestingProgram(ConstructProgram(true, true)); - SetTestingHashSeed(kTestHashSeed); - - mock_delegate().ExpectCallsToDependenciesSetUpMethods(); - mock_delegate().ExpectCallsToGetterMethods(); - EXPECT_CALL(resetter(), ReportStatistics(0x03u, 0x05u)); - - UnleashResetterAndWait(); - - EXPECT_FALSE(resetter().ShouldShowResetBanner()); - VerifyExpectationsThenShutdownResetter(); - - EXPECT_EQ(std::string(), memento_in_prefs().ReadValue()); - EXPECT_EQ(kTestMementoValue, memento_in_local_state().ReadValue()); - EXPECT_EQ(std::string(), memento_in_file().ReadValue()); -} - -TEST_F(AutomaticProfileResetterTestDryRun, AlreadyHadFileHostedMemento) { - memento_in_file().StoreValue(kTestMementoValue); - - SetTestingProgram(ConstructProgram(true, true)); - SetTestingHashSeed(kTestHashSeed); - - mock_delegate().ExpectCallsToDependenciesSetUpMethods(); - mock_delegate().ExpectCallsToGetterMethods(); - EXPECT_CALL(resetter(), ReportStatistics(0x03u, 0x09u)); - - UnleashResetterAndWait(); - - EXPECT_FALSE(resetter().ShouldShowResetBanner()); - VerifyExpectationsThenShutdownResetter(); - - EXPECT_EQ(std::string(), memento_in_prefs().ReadValue()); - EXPECT_EQ(std::string(), memento_in_local_state().ReadValue()); - EXPECT_EQ(kTestMementoValue, memento_in_file().ReadValue()); -} - -TEST_F(AutomaticProfileResetterTestDryRun, DoNothingWhenResourcesAreMissing) { - SetTestingProgram(std::string()); - SetTestingHashSeed(std::string()); - - // No calls are expected to the delegate. - - UnleashResetterAndWait(); - - EXPECT_FALSE(resetter().ShouldShowResetBanner()); - VerifyExpectationsThenShutdownResetter(); - - ExpectAllMementoValuesEqualTo(std::string()); -} - -TEST_F(AutomaticProfileResetterTest, CriteriaNotSatisfied) { - SetTestingProgram(ConstructProgramToExerciseCriteria(false, true, true)); - SetTestingHashSeed(kTestHashSeed); - - mock_delegate().ExpectCallsToDependenciesSetUpMethods(); - mock_delegate().ExpectCallsToGetterMethods(); - EXPECT_CALL(resetter(), ReportStatistics(0x1fu, 0x00u)); - - UnleashResetterAndWait(); - - EXPECT_FALSE(resetter().ShouldShowResetBanner()); - VerifyExpectationsThenShutdownResetter(); - - ExpectAllMementoValuesEqualTo(std::string()); -} - -TEST_F(AutomaticProfileResetterTest, OddCriteriaSatisfied) { - SetTestingProgram(ConstructProgramToExerciseCriteria(true, true, false)); - SetTestingHashSeed(kTestHashSeed); - - mock_delegate().ExpectCallsToDependenciesSetUpMethods(); - mock_delegate().ExpectCallsToGetterMethods(); - mock_delegate().ExpectCallToShowPrompt(); - EXPECT_CALL(resetter(), ReportStatistics(0x15u, 0x01u)); - - UnleashResetterAndWait(); - - EXPECT_TRUE(resetter().ShouldShowResetBanner()); - VerifyExpectationsThenShutdownResetter(); -} - -TEST_F(AutomaticProfileResetterTest, EvenCriteriaSatisfied) { - SetTestingProgram(ConstructProgramToExerciseCriteria(true, false, true)); - SetTestingHashSeed(kTestHashSeed); - - mock_delegate().ExpectCallsToDependenciesSetUpMethods(); - mock_delegate().ExpectCallsToGetterMethods(); - mock_delegate().ExpectCallToShowPrompt(); - EXPECT_CALL(resetter(), ReportStatistics(0x0au, 0x01u)); - - UnleashResetterAndWait(); - - EXPECT_TRUE(resetter().ShouldShowResetBanner()); - VerifyExpectationsThenShutdownResetter(); -} - -#if defined(GOOGLE_CHROME_BUILD) -TEST_F(AutomaticProfileResetterTest, ProgramSetThroughVariationParams) { - SetTestingProgram(ConstructProgram(true, true)); - SetTestingHashSeed(kTestHashSeed); - AllowInjectingTestDataThroughVariationParams(true); - - mock_delegate().ExpectCallsToDependenciesSetUpMethods(); - mock_delegate().ExpectCallsToGetterMethods(); - mock_delegate().ExpectCallToShowPrompt(); - EXPECT_CALL(resetter(), ReportStatistics(0x03u, 0x01u)); - EXPECT_CALL(resetter(), ReportPromptResult( - AutomaticProfileResetter::PROMPT_SHOWN_BUBBLE)); - - UnleashResetterAndWait(); - resetter().NotifyDidShowResetBubble(); - - ExpectAllMementoValuesEqualTo(kTestMementoValue); - EXPECT_TRUE(resetter().ShouldShowResetBanner()); - VerifyExpectationsThenShutdownResetter(); -} -#endif - -TEST_F(AutomaticProfileResetterTest, ConditionsSatisfiedAndInvalidMementos) { - memento_in_prefs().StoreValue(kTestInvalidMementoValue); - memento_in_local_state().StoreValue(kTestInvalidMementoValue); - memento_in_file().StoreValue(kTestInvalidMementoValue); - - SetTestingProgram(ConstructProgram(true, true)); - SetTestingHashSeed(kTestHashSeed); - - mock_delegate().ExpectCallsToDependenciesSetUpMethods(); - mock_delegate().ExpectCallsToGetterMethods(); - mock_delegate().ExpectCallToShowPrompt(); - EXPECT_CALL(resetter(), ReportStatistics(0x03u, 0x01u)); - EXPECT_CALL(resetter(), ReportPromptResult( - AutomaticProfileResetter::PROMPT_SHOWN_BUBBLE)); - - UnleashResetterAndWait(); - resetter().NotifyDidShowResetBubble(); - - ExpectAllMementoValuesEqualTo(kTestMementoValue); - EXPECT_TRUE(resetter().ShouldShowResetBanner()); - VerifyExpectationsThenShutdownResetter(); -} - -TEST_F(AutomaticProfileResetterTest, PrefHostedMementoPreventsPrompt) { - memento_in_prefs().StoreValue(kTestMementoValue); - - SetTestingProgram(ConstructProgram(true, true)); - SetTestingHashSeed(kTestHashSeed); - - mock_delegate().ExpectCallsToDependenciesSetUpMethods(); - mock_delegate().ExpectCallsToGetterMethods(); - EXPECT_CALL(resetter(), ReportStatistics(0x03u, 0x03u)); - - UnleashResetterAndWait(); - - EXPECT_TRUE(resetter().ShouldShowResetBanner()); - VerifyExpectationsThenShutdownResetter(); - - EXPECT_EQ(kTestMementoValue, memento_in_prefs().ReadValue()); - EXPECT_EQ(std::string(), memento_in_local_state().ReadValue()); - EXPECT_EQ(std::string(), memento_in_file().ReadValue()); -} - -TEST_F(AutomaticProfileResetterTest, LocalStateHostedMementoPreventsPrompt) { - memento_in_local_state().StoreValue(kTestMementoValue); - - SetTestingProgram(ConstructProgram(true, true)); - SetTestingHashSeed(kTestHashSeed); - - mock_delegate().ExpectCallsToDependenciesSetUpMethods(); - mock_delegate().ExpectCallsToGetterMethods(); - EXPECT_CALL(resetter(), ReportStatistics(0x03u, 0x05u)); - - UnleashResetterAndWait(); - - EXPECT_TRUE(resetter().ShouldShowResetBanner()); - VerifyExpectationsThenShutdownResetter(); - - EXPECT_EQ(std::string(), memento_in_prefs().ReadValue()); - EXPECT_EQ(kTestMementoValue, memento_in_local_state().ReadValue()); - EXPECT_EQ(std::string(), memento_in_file().ReadValue()); -} - -TEST_F(AutomaticProfileResetterTest, FileHostedMementoPreventsPrompt) { - memento_in_file().StoreValue(kTestMementoValue); - - SetTestingProgram(ConstructProgram(true, true)); - SetTestingHashSeed(kTestHashSeed); - - mock_delegate().ExpectCallsToDependenciesSetUpMethods(); - mock_delegate().ExpectCallsToGetterMethods(); - EXPECT_CALL(resetter(), ReportStatistics(0x03u, 0x09u)); - - UnleashResetterAndWait(); - - EXPECT_TRUE(resetter().ShouldShowResetBanner()); - VerifyExpectationsThenShutdownResetter(); - - EXPECT_EQ(std::string(), memento_in_prefs().ReadValue()); - EXPECT_EQ(std::string(), memento_in_local_state().ReadValue()); - EXPECT_EQ(kTestMementoValue, memento_in_file().ReadValue()); -} - -TEST_F(AutomaticProfileResetterTest, DoNothingWhenResourcesAreMissing) { - SetTestingProgram(std::string()); - SetTestingHashSeed(std::string()); - - // No calls are expected to the delegate. - - UnleashResetterAndWait(); - - EXPECT_FALSE(resetter().ShouldShowResetBanner()); - VerifyExpectationsThenShutdownResetter(); - - ExpectAllMementoValuesEqualTo(std::string()); -} - -TEST_F(AutomaticProfileResetterTest, PromptSuppressed) { - OrchestrateThroughEvaluationFlow(); - - VerifyExpectationsThenShutdownResetter(); - - ExpectAllMementoValuesEqualTo(std::string()); -} - -TEST_F(AutomaticProfileResetterTest, PromptNotSupported) { - SetTestingProgram(ConstructProgram(true, true)); - SetTestingHashSeed(kTestHashSeed); - - mock_delegate().ExpectCallsToDependenciesSetUpMethods(); - mock_delegate().ExpectCallsToGetterMethods(); - EXPECT_CALL(mock_delegate(), TriggerPrompt()) - .WillOnce(testing::Return(false)); - EXPECT_CALL(resetter(), ReportStatistics(0x03u, 0x01u)); - EXPECT_CALL(resetter(), ReportPromptResult( - AutomaticProfileResetter::PROMPT_NOT_TRIGGERED)); - - UnleashResetterAndWait(); - - ExpectAllMementoValuesEqualTo(kTestMementoValue); - EXPECT_TRUE(resetter().ShouldShowResetBanner()); - VerifyExpectationsThenShutdownResetter(); -} - -TEST_F(AutomaticProfileResetterTest, PromptIgnored) { - OrchestrateThroughEvaluationFlow(); - - EXPECT_CALL(resetter(), ReportPromptResult( - AutomaticProfileResetter::PROMPT_SHOWN_BUBBLE)); - resetter().NotifyDidShowResetBubble(); - ExpectAllMementoValuesEqualTo(kTestMementoValue); - VerifyExpectationsThenShutdownResetter(); -} - -TEST_F(AutomaticProfileResetterTest, PromptActionReset) { - OrchestrateThroughEvaluationFlow(); - - EXPECT_CALL(resetter(), ReportPromptResult( - AutomaticProfileResetter::PROMPT_SHOWN_BUBBLE)); - resetter().NotifyDidShowResetBubble(); - ExpectAllMementoValuesEqualTo(kTestMementoValue); - testing::Mock::VerifyAndClearExpectations(&resetter()); - - mock_delegate().ExpectCallToTriggerReset(false); - EXPECT_CALL(resetter(), ReportPromptResult( - AutomaticProfileResetter::PROMPT_ACTION_RESET)); - resetter().TriggerProfileReset(false /*send_feedback*/); - testing::Mock::VerifyAndClearExpectations(&resetter()); - testing::Mock::VerifyAndClearExpectations(&mock_delegate()); - - EXPECT_CALL(mock_delegate(), DismissPrompt()); - mock_delegate().EmulateProfileResetCompleted(); - EXPECT_FALSE(resetter().ShouldShowResetBanner()); - VerifyExpectationsThenShutdownResetter(); -} - -TEST_F(AutomaticProfileResetterTest, PromptActionResetWithFeedback) { - OrchestrateThroughEvaluationFlow(); - - EXPECT_CALL(resetter(), ReportPromptResult( - AutomaticProfileResetter::PROMPT_SHOWN_BUBBLE)); - resetter().NotifyDidShowResetBubble(); - ExpectAllMementoValuesEqualTo(kTestMementoValue); - testing::Mock::VerifyAndClearExpectations(&resetter()); - - mock_delegate().ExpectCallToTriggerReset(true); - EXPECT_CALL(resetter(), ReportPromptResult( - AutomaticProfileResetter::PROMPT_ACTION_RESET)); - resetter().TriggerProfileReset(true /*send_feedback*/); - testing::Mock::VerifyAndClearExpectations(&resetter()); - testing::Mock::VerifyAndClearExpectations(&mock_delegate()); - - EXPECT_CALL(mock_delegate(), DismissPrompt()); - mock_delegate().EmulateProfileResetCompleted(); - EXPECT_FALSE(resetter().ShouldShowResetBanner()); - VerifyExpectationsThenShutdownResetter(); -} - -TEST_F(AutomaticProfileResetterTest, PromptActionNoReset) { - OrchestrateThroughEvaluationFlow(); - - EXPECT_CALL(resetter(), ReportPromptResult( - AutomaticProfileResetter::PROMPT_SHOWN_BUBBLE)); - resetter().NotifyDidShowResetBubble(); - ExpectAllMementoValuesEqualTo(kTestMementoValue); - testing::Mock::VerifyAndClearExpectations(&resetter()); - - EXPECT_CALL(mock_delegate(), DismissPrompt()); - EXPECT_CALL(resetter(), ReportPromptResult( - AutomaticProfileResetter::PROMPT_ACTION_NO_RESET)); - resetter().SkipProfileReset(); - EXPECT_FALSE(resetter().ShouldShowResetBanner()); - VerifyExpectationsThenShutdownResetter(); -} - -TEST_F(AutomaticProfileResetterTest, PromptFollowedByWebUIReset) { - OrchestrateThroughEvaluationFlow(); - - EXPECT_CALL(resetter(), ReportPromptResult( - AutomaticProfileResetter::PROMPT_SHOWN_BUBBLE)); - resetter().NotifyDidShowResetBubble(); - ExpectAllMementoValuesEqualTo(kTestMementoValue); - testing::Mock::VerifyAndClearExpectations(&resetter()); - - EXPECT_CALL(mock_delegate(), DismissPrompt()); - resetter().NotifyDidOpenWebUIResetDialog(); - testing::Mock::VerifyAndClearExpectations(&mock_delegate()); - - EXPECT_CALL(resetter(), ReportPromptResult( - AutomaticProfileResetter::PROMPT_FOLLOWED_BY_WEBUI_RESET)); - resetter().NotifyDidCloseWebUIResetDialog(true); - EXPECT_TRUE(resetter().ShouldShowResetBanner()); - VerifyExpectationsThenShutdownResetter(); -} - -TEST_F(AutomaticProfileResetterTest, PromptFollowedByWebUINoReset) { - OrchestrateThroughEvaluationFlow(); - - EXPECT_CALL(resetter(), ReportPromptResult( - AutomaticProfileResetter::PROMPT_SHOWN_BUBBLE)); - resetter().NotifyDidShowResetBubble(); - ExpectAllMementoValuesEqualTo(kTestMementoValue); - testing::Mock::VerifyAndClearExpectations(&resetter()); - - EXPECT_CALL(mock_delegate(), DismissPrompt()); - resetter().NotifyDidOpenWebUIResetDialog(); - testing::Mock::VerifyAndClearExpectations(&mock_delegate()); - - EXPECT_CALL(resetter(), ReportPromptResult( - AutomaticProfileResetter::PROMPT_FOLLOWED_BY_WEBUI_NO_RESET)); - resetter().NotifyDidCloseWebUIResetDialog(false); - EXPECT_TRUE(resetter().ShouldShowResetBanner()); - VerifyExpectationsThenShutdownResetter(); -} - -TEST_F(AutomaticProfileResetterTest, PromptFollowedByIncidentalWebUIReset) { - OrchestrateThroughEvaluationFlow(); - - EXPECT_CALL(resetter(), ReportPromptResult( - AutomaticProfileResetter::PROMPT_SHOWN_BUBBLE)); - resetter().NotifyDidShowResetBubble(); - ExpectAllMementoValuesEqualTo(kTestMementoValue); - testing::Mock::VerifyAndClearExpectations(&resetter()); - - // Missing NotifyDidOpenWebUIResetDialog(). - // This can arise if a settings page was already opened at the time the prompt - // was triggered, and this already opened dialog was used to initiate a reset - // after having dismissed the prompt. - - EXPECT_CALL(mock_delegate(), DismissPrompt()); - EXPECT_CALL(resetter(), ReportPromptResult( - AutomaticProfileResetter::PROMPT_FOLLOWED_BY_WEBUI_RESET)); - resetter().NotifyDidCloseWebUIResetDialog(true); - EXPECT_TRUE(resetter().ShouldShowResetBanner()); - VerifyExpectationsThenShutdownResetter(); -} - -TEST_F(AutomaticProfileResetterTest, PromptSuppressedButHadWebUIReset) { - OrchestrateThroughEvaluationFlow(); - - EXPECT_CALL(mock_delegate(), DismissPrompt()); - resetter().NotifyDidOpenWebUIResetDialog(); - testing::Mock::VerifyAndClearExpectations(&mock_delegate()); - - EXPECT_CALL(resetter(), ReportPromptResult( - AutomaticProfileResetter::PROMPT_NOT_SHOWN_BUBBLE_BUT_HAD_WEBUI_RESET)); - resetter().NotifyDidCloseWebUIResetDialog(true); - ExpectAllMementoValuesEqualTo(kTestMementoValue); - EXPECT_TRUE(resetter().ShouldShowResetBanner()); - VerifyExpectationsThenShutdownResetter(); -} - -TEST_F(AutomaticProfileResetterTest, PromptSuppressedButHadWebUINoReset) { - OrchestrateThroughEvaluationFlow(); - - EXPECT_CALL(mock_delegate(), DismissPrompt()); - resetter().NotifyDidOpenWebUIResetDialog(); - testing::Mock::VerifyAndClearExpectations(&mock_delegate()); - - EXPECT_CALL(resetter(), ReportPromptResult(AutomaticProfileResetter:: - PROMPT_NOT_SHOWN_BUBBLE_BUT_HAD_WEBUI_NO_RESET)); - resetter().NotifyDidCloseWebUIResetDialog(false); - ExpectAllMementoValuesEqualTo(kTestMementoValue); - EXPECT_TRUE(resetter().ShouldShowResetBanner()); - VerifyExpectationsThenShutdownResetter(); -} - -TEST_F(AutomaticProfileResetterTest, BannerDismissed) { - OrchestrateThroughEvaluationFlow(); - - EXPECT_CALL(resetter(), ReportPromptResult( - AutomaticProfileResetter::PROMPT_SHOWN_BUBBLE)); - resetter().NotifyDidShowResetBubble(); - ExpectAllMementoValuesEqualTo(kTestMementoValue); - testing::Mock::VerifyAndClearExpectations(&resetter()); - - resetter().NotifyDidCloseWebUIResetBanner(); - - EXPECT_TRUE(resetter().IsResetPromptFlowActive()); - EXPECT_FALSE(resetter().ShouldShowResetBanner()); - - // Note: we use strict mocks, so this also checks the bubble is not closed. - VerifyExpectationsThenShutdownResetter(); -} - -TEST_F(AutomaticProfileResetterTest, BannerDismissedWhilePromptSuppressed) { - OrchestrateThroughEvaluationFlow(); - - resetter().NotifyDidCloseWebUIResetBanner(); - - EXPECT_TRUE(resetter().IsResetPromptFlowActive()); - EXPECT_FALSE(resetter().ShouldShowResetBanner()); - VerifyExpectationsThenShutdownResetter(); - - ExpectAllMementoValuesEqualTo(std::string()); -} - -// Please see comments above ConstructProgramToCheckPreferences() to understand -// how the following tests work. - -TEST_F(AutomaticProfileResetterTest, InputUserPreferencesCorrect) { - SetTestingProgram(ConstructProgramToCheckPreferences()); - SetTestingHashSeed(kTestHashSeed); - - PrefService* prefs = profile()->GetPrefs(); - prefs->SetString(kTestPreferencePath, kTestPreferenceValue); - - mock_delegate().ExpectCallsToDependenciesSetUpMethods(); - mock_delegate().ExpectCallsToGetterMethods(); - uint32 expected_mask = HAS_EXPECTED_USER_PREFERENCE | - USER_PREFERENCE_IS_USER_CONTROLLED; - EXPECT_CALL(resetter(), ReportStatistics(0x00u, expected_mask)); - - UnleashResetterAndWait(); -} - -TEST_F(AutomaticProfileResetterTest, InputLocalStateCorrect) { - SetTestingProgram(ConstructProgramToCheckPreferences()); - SetTestingHashSeed(kTestHashSeed); - - PrefService* prefs = local_state(); - prefs->SetString(kTestPreferencePath, kTestPreferenceValue); - - mock_delegate().ExpectCallsToDependenciesSetUpMethods(); - mock_delegate().ExpectCallsToGetterMethods(); - uint32 expected_mask = HAS_EXPECTED_LOCAL_STATE_PREFERENCE | - LOCAL_STATE_IS_USER_CONTROLLED; - EXPECT_CALL(resetter(), ReportStatistics(0x00u, expected_mask)); - - UnleashResetterAndWait(); -} - -TEST_F(AutomaticProfileResetterTest, InputManagedUserPreferencesCorrect) { - SetTestingProgram(ConstructProgramToCheckPreferences()); - SetTestingHashSeed(kTestHashSeed); - - syncable_prefs::TestingPrefServiceSyncable* prefs = - profile()->GetTestingPrefService(); - prefs->SetManagedPref(kTestPreferencePath, - new base::StringValue(kTestPreferenceValue)); - - mock_delegate().ExpectCallsToDependenciesSetUpMethods(); - mock_delegate().ExpectCallsToGetterMethods(); - uint32 expected_mask = HAS_EXPECTED_USER_PREFERENCE; - EXPECT_CALL(resetter(), ReportStatistics(0x00u, expected_mask)); - - UnleashResetterAndWait(); -} - -TEST_F(AutomaticProfileResetterTest, InputManagedLocalStateCorrect) { - SetTestingProgram(ConstructProgramToCheckPreferences()); - SetTestingHashSeed(kTestHashSeed); - - TestingPrefServiceSimple* prefs = local_state(); - prefs->SetManagedPref(kTestPreferencePath, - new base::StringValue(kTestPreferenceValue)); - - mock_delegate().ExpectCallsToDependenciesSetUpMethods(); - mock_delegate().ExpectCallsToGetterMethods(); - uint32 expected_mask = HAS_EXPECTED_LOCAL_STATE_PREFERENCE; - EXPECT_CALL(resetter(), ReportStatistics(0x00u, expected_mask)); - - UnleashResetterAndWait(); -} - -// Please see comments above ConstructProgramToCheckSearchEngines() to -// understand how the following tests work. - -TEST_F(AutomaticProfileResetterTest, InputDefaultSearchProviderCorrect) { - SetTestingProgram(ConstructProgramToCheckSearchEngines()); - SetTestingHashSeed(kTestHashSeed); - - mock_delegate().emulated_default_search_provider_details().SetString( - kSearchURLAttributeKey, kTestSearchURL); - - mock_delegate().ExpectCallsToDependenciesSetUpMethods(); - mock_delegate().ExpectCallsToGetterMethods(); - uint32 expected_mask = HAS_EXPECTED_DEFAULT_SEARCH_PROVIDER | - DEFAULT_SEARCH_PROVIDER_IS_USER_CONTROLLED; - EXPECT_CALL(resetter(), ReportStatistics(0x00u, expected_mask)); - - UnleashResetterAndWait(); -} - -TEST_F(AutomaticProfileResetterTest, InputSearchProviderManagedCorrect) { - SetTestingProgram(ConstructProgramToCheckSearchEngines()); - SetTestingHashSeed(kTestHashSeed); - - mock_delegate().emulated_default_search_provider_details().SetString( - kSearchURLAttributeKey, kTestSearchURL); - mock_delegate().set_emulated_is_default_search_provider_managed(true); - - mock_delegate().ExpectCallsToDependenciesSetUpMethods(); - mock_delegate().ExpectCallsToGetterMethods(); - uint32 expected_mask = HAS_EXPECTED_DEFAULT_SEARCH_PROVIDER; - EXPECT_CALL(resetter(), ReportStatistics(0x00u, expected_mask)); - - UnleashResetterAndWait(); -} - -TEST_F(AutomaticProfileResetterTest, InputSearchProvidersCorrect) { - SetTestingProgram(ConstructProgramToCheckSearchEngines()); - SetTestingHashSeed(kTestHashSeed); - - base::DictionaryValue* search_provider_1 = new base::DictionaryValue; - base::DictionaryValue* search_provider_2 = new base::DictionaryValue; - search_provider_1->SetString(kSearchURLAttributeKey, kTestSearchURL); - search_provider_2->SetString(kSearchURLAttributeKey, kTestSearchURL2); - mock_delegate().emulated_search_providers_details().Append(search_provider_1); - mock_delegate().emulated_search_providers_details().Append(search_provider_2); - - mock_delegate().ExpectCallsToDependenciesSetUpMethods(); - mock_delegate().ExpectCallsToGetterMethods(); - uint32 expected_mask = DEFAULT_SEARCH_PROVIDER_IS_USER_CONTROLLED | - HAS_EXPECTED_PREPOPULATED_SEARCH_PROVIDER_1 | - HAS_EXPECTED_PREPOPULATED_SEARCH_PROVIDER_2; - EXPECT_CALL(resetter(), ReportStatistics(0x00u, expected_mask)); - - UnleashResetterAndWait(); -} - -// Please see comments above ConstructProgramToCheckLoadedModuleDigests() to -// understand how the following tests work. - -TEST_F(AutomaticProfileResetterTest, InputModuleDigestsCorrect) { - SetTestingProgram(ConstructProgramToCheckLoadedModuleDigests()); - SetTestingHashSeed(kTestHashSeed); - - mock_delegate().emulated_loaded_module_digests().AppendString( - kTestModuleDigest); - mock_delegate().emulated_loaded_module_digests().AppendString( - kTestModuleDigest2); - - mock_delegate().ExpectCallsToDependenciesSetUpMethods(); - mock_delegate().ExpectCallsToGetterMethods(); - uint32 expected_mask = - HAS_EXPECTED_MODULE_DIGEST_1 | HAS_EXPECTED_MODULE_DIGEST_2; - EXPECT_CALL(resetter(), ReportStatistics(0x00u, expected_mask)); - - UnleashResetterAndWait(); -} - -} // namespace
diff --git a/chrome/browser/profile_resetter/jtl_foundation.cc b/chrome/browser/profile_resetter/jtl_foundation.cc deleted file mode 100644 index a2a2007..0000000 --- a/chrome/browser/profile_resetter/jtl_foundation.cc +++ /dev/null
@@ -1,48 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/profile_resetter/jtl_foundation.h" - -#include "base/logging.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_util.h" - -namespace jtl_foundation { - -Hasher::Hasher(const std::string& seed) : hmac_(crypto::HMAC::SHA256) { - if (!hmac_.Init(seed)) - NOTREACHED(); -} - -Hasher::~Hasher() {} - -std::string Hasher::GetHash(const std::string& input) const { - if (cached_hashes_.find(input) == cached_hashes_.end()) { - // Calculate value. - unsigned char digest[kHashSizeInBytes]; - if (!hmac_.Sign(input, digest, arraysize(digest))) { - NOTREACHED(); - return std::string(); - } - // Instead of using the full SHA256, we only use the hex encoding of the - // first 16 bytes. - cached_hashes_[input] = base::HexEncode(digest, kHashSizeInBytes / 2); - DCHECK_EQ(kHashSizeInBytes, cached_hashes_[input].size()); - } - return cached_hashes_[input]; -} - -// static -bool Hasher::IsHash(const std::string& maybe_hash) { - if (maybe_hash.size() != kHashSizeInBytes) - return false; - for (std::string::const_iterator it = maybe_hash.begin(); - it != maybe_hash.end(); ++it) { - if (!base::IsHexDigit(*it)) - return false; - } - return true; -} - -} // namespace jtl_foundation
diff --git a/chrome/browser/profile_resetter/jtl_foundation.h b/chrome/browser/profile_resetter/jtl_foundation.h deleted file mode 100644 index cc4a5f4..0000000 --- a/chrome/browser/profile_resetter/jtl_foundation.h +++ /dev/null
@@ -1,193 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_PROFILE_RESETTER_JTL_FOUNDATION_H_ -#define CHROME_BROWSER_PROFILE_RESETTER_JTL_FOUNDATION_H_ - -#include <map> -#include <string> - -#include "base/basictypes.h" -#include "crypto/hmac.h" - -namespace jtl_foundation { - -// A JTL (JSON Traversal Language) program is composed of one or more -// sentences. Each sentence consists of a sequence of operations. The input of -// the program is a hierarchical JSON data structure. -// -// The execution of each sentence starts at the root of an input dictionary. The -// operations include navigation in the JSON data structure, as well as -// comparing the current (leaf) node to fixed values. The program also has a -// separate dictionary as working memory, into which it can memorize data, then -// later recall it for comparisons. -// -// Example program: -// NAVIGATE_ANY -// NAVIGATE(hash("bar")) -// COMPARE_NODE_BOOL(1) -// STORE_BOOL(hash("found_foo"), 1) -// STOP_EXECUTING_SENTENCE -// -// Example input: -// { -// 'key1': 1, -// 'key2': {'foo': 0, 'bar': false, 'baz': 2} -// 'key3': {'foo': 0, 'bar': true, 'baz': 2} -// 'key4': {'foo': 0, 'bar': true, 'baz': 2} -// } -// -// This program navigates from the root of the dictionary to all children -// ("key1", "key2", "key3", "key4") and executes the remaining program on each -// of the children. The navigation happens in depth-first pre-order. On each of -// the children it tries to navigate into the child "bar", which fails for -// "key1", so execution stops for this sub-branch. On key2 the program navigates -// to "bar" and moves the execution context to this node which has the value -// "false". Therefore, the following COMPARE_NODE_BOOL is not fulfilled and the -// execution does not continue on this branch, so we back track and proceed with -// "key3" and its "bar" child. For this node, COMPARE_NODE_BOOL is fulfilled and -// the execution continues to store "found_foo = true" into the working memory -// of the interpreter. Next the interpreter executes STOP_EXECUTING_SENTENCE -// which prevents the traversal from descending into the "key4" branch from the -// NAVIGATE_ANY operation and can therefore speedup the processing. -// -// All node names, and node values of type string, integer and double are hashed -// before being compared to hash values listed in |program|. - -// JTL byte code consists of uint8 opcodes followed by parameters. Parameters -// are either boolean (uint8 with value \x00 or \x01), uint32 (in little-endian -// notation), or hash string of 32 bytes. -// The following opcodes are defined: -enum OpCodes { - // Continues execution with the next operation on the element of a - // dictionary that matches the passed key parameter. If no such element - // exists, the command execution returns from the current instruction. - // Parameters: - // - a 32 byte hash of the target dictionary key. - NAVIGATE = 0x00, - // Continues execution with the next operation on each element of a - // dictionary or list. If no such element exists or the current element is - // neither a dictionary or list, the command execution returns from the - // current instruction. - NAVIGATE_ANY = 0x01, - // Continues execution with the next operation on the parent node of the - // current node. If the current node is the root of the input dictionary, the - // program execution fails with a runtime error. - NAVIGATE_BACK = 0x02, - // Stores a boolean value in the working memory. - // Parameters: - // - a 32 byte hash of the parameter name, - // - the value to store (\x00 or \x01) - STORE_BOOL = 0x10, - // Checks whether a boolean stored in working memory matches the expected - // value and continues execution with the next operation in case of a match. - // Parameters: - // - a 32 byte hash of the parameter name, - // - the expected value (\x00 or \x01), - // - the default value in case the working memory contains no corresponding - // entry (\x00 or\x01). - COMPARE_STORED_BOOL = 0x11, - // Same as STORE_BOOL but takes a hash instead of a boolean value as - // parameter. - STORE_HASH = 0x12, - // Same as COMPARE_STORED_BOOL but takes a hash instead of two boolean values - // as parameters. - COMPARE_STORED_HASH = 0x13, - // Stores the current node into the working memory. If the current node is not - // a boolean value, the program execution returns from the current - // instruction. - // Parameters: - // - a 32 byte hash of the parameter name. - STORE_NODE_BOOL = 0x14, - // Stores the hashed value of the current node into the working memory. If - // the current node is not a string, integer or double, the program execution - // returns from the current instruction. - // Parameters: - // - a 32 byte hash of the parameter name. - STORE_NODE_HASH = 0x15, - // Parses the value of the current node as a URL, extracts the subcomponent of - // the domain name that is immediately below the registrar-controlled portion, - // and stores the hash of this subcomponent into working memory. In case the - // domain name ends in a suffix not on the Public Suffix List (i.e. is neither - // an ICANN, nor a private domain suffix), the last subcomponent is assumed to - // be the registry, and the second-to-last subcomponent is extracted. - // If the current node is not a string that represents a URL, or if this URL - // does not have a domain component as described above, the program execution - // returns from the current instruction. - // For example, "foo.com", "www.foo.co.uk", "foo.appspot.com", and "foo.bar" - // will all yield (the hash of) "foo" as a result. - // See the unit test for more details. - // Parameters: - // - a 32 byte hash of the parameter name. - STORE_NODE_REGISTERABLE_DOMAIN_HASH = 0x16, - // Compares the current node against a boolean value and continues execution - // with the next operation in case of a match. If the current node does not - // match or is not a boolean value, the program execution returns from the - // current instruction. - // Parameters: - // - a boolean value (\x00 or \x01). - COMPARE_NODE_BOOL = 0x20, - // Compares the hashed value of the current node against the given hash, and - // continues execution with the next operation in case of a match. If the - // current node is not a string, integer or double, or if it is either, but - // its hash does not match, the program execution returns from the current - // instruction. - // Parameters: - // - a 32 byte hash of the expected value. - COMPARE_NODE_HASH = 0x21, - // The negation of the above. - COMPARE_NODE_HASH_NOT = 0x22, - // Compares the current node against a boolean value stored in working memory, - // and continues with the next operation in case of a match. If the current - // node is not a boolean value, the working memory contains no corresponding - // boolean value, or if they do not match, the program execution returns from - // the current instruction. - // Parameters: - // - a 32 byte hash of the parameter name. - COMPARE_NODE_TO_STORED_BOOL = 0x23, - // Compares the hashed value of the current node against a hash value stored - // in working memory, and continues with the next operation in case of a - // match. If the current node is not a string, integer or double, or if the - // working memory contains no corresponding hash string, or if the hashes do - // not match, the program execution returns from the current instruction. - // Parameters: - // - a 32 byte hash of the parameter name. - COMPARE_NODE_TO_STORED_HASH = 0x24, - // Checks whether the current node is a string value that contains the given - // pattern as a substring, and continues execution with the next operation in - // case it does. If the current node is not a string, or if does not match the - // pattern, the program execution returns from the current instruction. - // Parameters: - // - a 32 byte hash of the pattern, - // - a 4 byte unsigned integer: the length (>0) of the pattern in bytes, - // - a 4 byte unsigned integer: the sum of all bytes in the pattern, serving - // as a heuristic to reduce the number of actual SHA-256 calculations. - COMPARE_NODE_SUBSTRING = 0x25, - // Stop execution in this specific sentence. - STOP_EXECUTING_SENTENCE = 0x30, - // Separator between sentences, starts a new sentence. - END_OF_SENTENCE = 0x31 -}; - -const size_t kHashSizeInBytes = 32u; - -// A class that provides SHA256 hash values for strings using a fixed hash seed. -class Hasher { - public: - explicit Hasher(const std::string& seed); - ~Hasher(); - - std::string GetHash(const std::string& input) const; - - static bool IsHash(const std::string& maybe_hash); - - private: - crypto::HMAC hmac_; - mutable std::map<std::string, std::string> cached_hashes_; - DISALLOW_COPY_AND_ASSIGN(Hasher); -}; - -} // namespace jtl_foundation - -#endif // CHROME_BROWSER_PROFILE_RESETTER_JTL_FOUNDATION_H_
diff --git a/chrome/browser/profile_resetter/jtl_instructions.h b/chrome/browser/profile_resetter/jtl_instructions.h deleted file mode 100644 index 76b57a67..0000000 --- a/chrome/browser/profile_resetter/jtl_instructions.h +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_PROFILE_RESETTER_JTL_INSTRUCTIONS_H_ -#define CHROME_BROWSER_PROFILE_RESETTER_JTL_INSTRUCTIONS_H_ - -#include <string> - -// These are instructions to generate binary code for JTL programs. - -#define VALUE_FALSE std::string(1, '\x00') -#define VALUE_TRUE std::string(1, '\x01') - -#define OP_NAVIGATE(key) std::string(1, '\x00') + key -#define OP_NAVIGATE_ANY std::string(1, '\x01') -#define OP_NAVIGATE_BACK std::string(1, '\x02') -#define OP_STORE_BOOL(name, value) std::string(1, '\x10') + name + value -#define OP_COMPARE_STORED_BOOL(name, value, default_value) \ - std::string(1, '\x11') + name + value + default_value -#define OP_STORE_HASH(name, value) std::string(1, '\x12') + name + value -#define OP_COMPARE_STORED_HASH(name, value, default_value) \ - std::string(1, '\x13') + name + value + default_value -#define OP_STORE_NODE_BOOL(name) std::string(1, '\x14') + name -#define OP_STORE_NODE_HASH(name) std::string(1, '\x15') + name -#define OP_STORE_NODE_REGISTERABLE_DOMAIN_HASH(name) \ - std::string(1, '\x16') + name -#define OP_COMPARE_NODE_BOOL(value) std::string(1, '\x20') + value -#define OP_COMPARE_NODE_HASH(value) std::string(1, '\x21') + value -#define OP_COMPARE_NODE_HASH_NOT(value) std::string(1, '\x22') + value -#define OP_COMPARE_NODE_TO_STORED_BOOL(name) std::string(1, '\x23') + name -#define OP_COMPARE_NODE_TO_STORED_HASH(name) std::string(1, '\x24') + name -#define OP_COMPARE_NODE_SUBSTRING(pattern, pattern_length, pattern_sum) \ - std::string(1, '\x25') + pattern + pattern_length + pattern_sum -#define OP_STOP_EXECUTING_SENTENCE std::string(1, '\x30') -#define OP_END_OF_SENTENCE std::string(1, '\x31') - -#endif // CHROME_BROWSER_PROFILE_RESETTER_JTL_INSTRUCTIONS_H_
diff --git a/chrome/browser/profile_resetter/jtl_interpreter.cc b/chrome/browser/profile_resetter/jtl_interpreter.cc deleted file mode 100644 index be0b368c..0000000 --- a/chrome/browser/profile_resetter/jtl_interpreter.cc +++ /dev/null
@@ -1,746 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/profile_resetter/jtl_interpreter.h" - -#include <numeric> - -#include "base/memory/scoped_vector.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_util.h" -#include "chrome/browser/profile_resetter/jtl_foundation.h" -#include "crypto/hmac.h" -#include "crypto/sha2.h" -#include "net/base/registry_controlled_domains/registry_controlled_domain.h" -#include "url/gurl.h" - -namespace { - -class ExecutionContext; - -// An operation in an interpreted program. -class Operation { - public: - virtual ~Operation() {} - // Executes the operation on the specified context and instructs the context - // to continue execution with the next instruction if appropriate. - // Returns true if we should continue with any potential backtracking that - // needs to be done. - virtual bool Execute(ExecutionContext* context) = 0; -}; - -// An execution context of operations. -class ExecutionContext { - public: - // |input| is the root of a dictionary that stores the information the - // sentence is evaluated on. - ExecutionContext(const jtl_foundation::Hasher* hasher, - const std::vector<Operation*>& sentence, - const base::DictionaryValue* input, - base::DictionaryValue* working_memory) - : hasher_(hasher), - sentence_(sentence), - next_instruction_index_(0u), - working_memory_(working_memory), - error_(false) { - stack_.push_back(input); - } - ~ExecutionContext() {} - - // Returns true in case of success. - bool ContinueExecution() { - if (error_ || stack_.empty()) { - error_ = true; - return false; - } - if (next_instruction_index_ >= sentence_.size()) - return true; - - Operation* op = sentence_[next_instruction_index_]; - next_instruction_index_++; - bool continue_traversal = op->Execute(this); - next_instruction_index_--; - return continue_traversal; - } - - std::string GetHash(const std::string& input) { - return hasher_->GetHash(input); - } - - // Calculates the |hash| of a string, integer or double |value|, and returns - // true. Returns false otherwise. - bool GetValueHash(const base::Value& value, std::string* hash) { - DCHECK(hash); - std::string value_as_string; - int tmp_int = 0; - double tmp_double = 0.0; - if (value.GetAsInteger(&tmp_int)) - value_as_string = base::IntToString(tmp_int); - else if (value.GetAsDouble(&tmp_double)) - value_as_string = base::DoubleToString(tmp_double); - else if (!value.GetAsString(&value_as_string)) - return false; - *hash = GetHash(value_as_string); - return true; - } - - const base::Value* current_node() const { return stack_.back(); } - std::vector<const base::Value*>* stack() { return &stack_; } - base::DictionaryValue* working_memory() { return working_memory_; } - bool error() const { return error_; } - - private: - // A hasher used to hash node names in a dictionary. - const jtl_foundation::Hasher* hasher_; - // The sentence to be executed. - const std::vector<Operation*> sentence_; - // Position in |sentence_|. - size_t next_instruction_index_; - // A stack of Values, indicating a navigation path from the root node of - // |input| (see constructor) to the current node on which the - // sentence_[next_instruction_index_] is evaluated. - std::vector<const base::Value*> stack_; - // Memory into which values can be stored by the program. - base::DictionaryValue* working_memory_; - // Whether a runtime error occurred. - bool error_; - DISALLOW_COPY_AND_ASSIGN(ExecutionContext); -}; - -class NavigateOperation : public Operation { - public: - explicit NavigateOperation(const std::string& hashed_key) - : hashed_key_(hashed_key) {} - ~NavigateOperation() override {} - bool Execute(ExecutionContext* context) override { - const base::DictionaryValue* dict = NULL; - if (!context->current_node()->GetAsDictionary(&dict)) { - // Just ignore this node gracefully as this navigation is a dead end. - // If this NavigateOperation occurred after a NavigateAny operation, those - // may still be fulfillable, so we allow continuing the execution of the - // sentence on other nodes. - return true; - } - for (base::DictionaryValue::Iterator i(*dict); !i.IsAtEnd(); i.Advance()) { - if (context->GetHash(i.key()) != hashed_key_) - continue; - context->stack()->push_back(&i.value()); - bool continue_traversal = context->ContinueExecution(); - context->stack()->pop_back(); - if (!continue_traversal) - return false; - } - return true; - } - - private: - std::string hashed_key_; - DISALLOW_COPY_AND_ASSIGN(NavigateOperation); -}; - -class NavigateAnyOperation : public Operation { - public: - NavigateAnyOperation() {} - ~NavigateAnyOperation() override {} - bool Execute(ExecutionContext* context) override { - const base::DictionaryValue* dict = NULL; - const base::ListValue* list = NULL; - if (context->current_node()->GetAsDictionary(&dict)) { - for (base::DictionaryValue::Iterator i(*dict); - !i.IsAtEnd(); i.Advance()) { - context->stack()->push_back(&i.value()); - bool continue_traversal = context->ContinueExecution(); - context->stack()->pop_back(); - if (!continue_traversal) - return false; - } - } else if (context->current_node()->GetAsList(&list)) { - for (base::ListValue::const_iterator i = list->begin(); - i != list->end(); ++i) { - context->stack()->push_back(*i); - bool continue_traversal = context->ContinueExecution(); - context->stack()->pop_back(); - if (!continue_traversal) - return false; - } - } else { - // Do nothing, just ignore this node. - } - return true; - } - - private: - DISALLOW_COPY_AND_ASSIGN(NavigateAnyOperation); -}; - -class NavigateBackOperation : public Operation { - public: - NavigateBackOperation() {} - ~NavigateBackOperation() override {} - bool Execute(ExecutionContext* context) override { - const base::Value* current_node = context->current_node(); - context->stack()->pop_back(); - bool continue_traversal = context->ContinueExecution(); - context->stack()->push_back(current_node); - return continue_traversal; - } - - private: - DISALLOW_COPY_AND_ASSIGN(NavigateBackOperation); -}; - -class StoreValue : public Operation { - public: - StoreValue(const std::string& hashed_name, scoped_ptr<base::Value> value) - : hashed_name_(hashed_name), - value_(value.Pass()) { - DCHECK(base::IsStringUTF8(hashed_name)); - DCHECK(value_); - } - ~StoreValue() override {} - bool Execute(ExecutionContext* context) override { - context->working_memory()->Set(hashed_name_, value_->DeepCopy()); - return context->ContinueExecution(); - } - - private: - std::string hashed_name_; - scoped_ptr<base::Value> value_; - DISALLOW_COPY_AND_ASSIGN(StoreValue); -}; - -class CompareStoredValue : public Operation { - public: - CompareStoredValue(const std::string& hashed_name, - scoped_ptr<base::Value> value, - scoped_ptr<base::Value> default_value) - : hashed_name_(hashed_name), - value_(value.Pass()), - default_value_(default_value.Pass()) { - DCHECK(base::IsStringUTF8(hashed_name)); - DCHECK(value_); - DCHECK(default_value_); - } - ~CompareStoredValue() override {} - bool Execute(ExecutionContext* context) override { - const base::Value* actual_value = NULL; - if (!context->working_memory()->Get(hashed_name_, &actual_value)) - actual_value = default_value_.get(); - if (!value_->Equals(actual_value)) - return true; - return context->ContinueExecution(); - } - - private: - std::string hashed_name_; - scoped_ptr<base::Value> value_; - scoped_ptr<base::Value> default_value_; - DISALLOW_COPY_AND_ASSIGN(CompareStoredValue); -}; - -template<bool ExpectedTypeIsBooleanNotHashable> -class StoreNodeValue : public Operation { - public: - explicit StoreNodeValue(const std::string& hashed_name) - : hashed_name_(hashed_name) { - DCHECK(base::IsStringUTF8(hashed_name)); - } - ~StoreNodeValue() override {} - bool Execute(ExecutionContext* context) override { - scoped_ptr<base::Value> value; - if (ExpectedTypeIsBooleanNotHashable) { - if (!context->current_node()->IsType(base::Value::TYPE_BOOLEAN)) - return true; - value.reset(context->current_node()->DeepCopy()); - } else { - std::string hash; - if (!context->GetValueHash(*context->current_node(), &hash)) - return true; - value.reset(new base::StringValue(hash)); - } - context->working_memory()->Set(hashed_name_, value.release()); - return context->ContinueExecution(); - } - - private: - std::string hashed_name_; - DISALLOW_COPY_AND_ASSIGN(StoreNodeValue); -}; - -// Stores the hash of the registerable domain name -- as in, the portion of the -// domain that is registerable, as opposed to controlled by a registrar; without -// subdomains -- of the URL represented by the current node into working memory. -class StoreNodeRegisterableDomain : public Operation { - public: - explicit StoreNodeRegisterableDomain(const std::string& hashed_name) - : hashed_name_(hashed_name) { - DCHECK(base::IsStringUTF8(hashed_name)); - } - ~StoreNodeRegisterableDomain() override {} - bool Execute(ExecutionContext* context) override { - std::string possibly_invalid_url; - std::string domain; - if (!context->current_node()->GetAsString(&possibly_invalid_url) || - !GetRegisterableDomain(possibly_invalid_url, &domain)) - return true; - context->working_memory()->Set( - hashed_name_, new base::StringValue(context->GetHash(domain))); - return context->ContinueExecution(); - } - - private: - // If |possibly_invalid_url| is a valid URL having a registerable domain name - // part, outputs that in |registerable_domain| and returns true. Otherwise, - // returns false. - static bool GetRegisterableDomain(const std::string& possibly_invalid_url, - std::string* registerable_domain) { - namespace domains = net::registry_controlled_domains; - DCHECK(registerable_domain); - GURL url(possibly_invalid_url); - if (!url.is_valid()) - return false; - std::string registry_plus_one = domains::GetDomainAndRegistry( - url.host(), domains::INCLUDE_PRIVATE_REGISTRIES); - size_t registry_length = domains::GetRegistryLength( - url.host(), - domains::INCLUDE_UNKNOWN_REGISTRIES, - domains::INCLUDE_PRIVATE_REGISTRIES); - // Fail unless (1.) the URL has a host part; and (2.) that host part is a - // well-formed domain name consisting of at least one subcomponent; followed - // by either a recognized registry identifier, or exactly one subcomponent, - // which is then assumed to be the unknown registry identifier. - if (registry_length == std::string::npos || registry_length == 0) - return false; - DCHECK_LT(registry_length, registry_plus_one.size()); - // Subtract one to cut off the dot separating the SLD and the registry. - registerable_domain->assign( - registry_plus_one, 0, registry_plus_one.size() - registry_length - 1); - return true; - } - - std::string hashed_name_; - DISALLOW_COPY_AND_ASSIGN(StoreNodeRegisterableDomain); -}; - -class CompareNodeBool : public Operation { - public: - explicit CompareNodeBool(bool value) : value_(value) {} - ~CompareNodeBool() override {} - bool Execute(ExecutionContext* context) override { - bool actual_value = false; - if (!context->current_node()->GetAsBoolean(&actual_value)) - return true; - if (actual_value != value_) - return true; - return context->ContinueExecution(); - } - - private: - bool value_; - DISALLOW_COPY_AND_ASSIGN(CompareNodeBool); -}; - -class CompareNodeHash : public Operation { - public: - explicit CompareNodeHash(const std::string& hashed_value) - : hashed_value_(hashed_value) {} - ~CompareNodeHash() override {} - bool Execute(ExecutionContext* context) override { - std::string actual_hash; - if (!context->GetValueHash(*context->current_node(), &actual_hash) || - actual_hash != hashed_value_) - return true; - return context->ContinueExecution(); - } - - private: - std::string hashed_value_; - DISALLOW_COPY_AND_ASSIGN(CompareNodeHash); -}; - -class CompareNodeHashNot : public Operation { - public: - explicit CompareNodeHashNot(const std::string& hashed_value) - : hashed_value_(hashed_value) {} - ~CompareNodeHashNot() override {} - bool Execute(ExecutionContext* context) override { - std::string actual_hash; - if (context->GetValueHash(*context->current_node(), &actual_hash) && - actual_hash == hashed_value_) - return true; - return context->ContinueExecution(); - } - - private: - std::string hashed_value_; - DISALLOW_COPY_AND_ASSIGN(CompareNodeHashNot); -}; - -template<bool ExpectedTypeIsBooleanNotHashable> -class CompareNodeToStored : public Operation { - public: - explicit CompareNodeToStored(const std::string& hashed_name) - : hashed_name_(hashed_name) {} - ~CompareNodeToStored() override {} - bool Execute(ExecutionContext* context) override { - const base::Value* stored_value = NULL; - if (!context->working_memory()->Get(hashed_name_, &stored_value)) - return true; - if (ExpectedTypeIsBooleanNotHashable) { - if (!context->current_node()->IsType(base::Value::TYPE_BOOLEAN) || - !context->current_node()->Equals(stored_value)) - return true; - } else { - std::string actual_hash; - std::string stored_hash; - if (!context->GetValueHash(*context->current_node(), &actual_hash) || - !stored_value->GetAsString(&stored_hash) || - actual_hash != stored_hash) - return true; - } - return context->ContinueExecution(); - } - - private: - std::string hashed_name_; - DISALLOW_COPY_AND_ASSIGN(CompareNodeToStored); -}; - -class CompareNodeSubstring : public Operation { - public: - explicit CompareNodeSubstring(const std::string& hashed_pattern, - size_t pattern_length, - uint32 pattern_sum) - : hashed_pattern_(hashed_pattern), - pattern_length_(pattern_length), - pattern_sum_(pattern_sum) { - DCHECK(pattern_length_); - } - ~CompareNodeSubstring() override {} - bool Execute(ExecutionContext* context) override { - std::string value_as_string; - if (!context->current_node()->GetAsString(&value_as_string) || - !pattern_length_ || value_as_string.size() < pattern_length_) - return true; - // Go over the string with a sliding window. Meanwhile, maintain the sum in - // an incremental fashion, and only calculate the SHA-256 hash when the sum - // checks out so as to improve performance. - std::string::const_iterator window_begin = value_as_string.begin(); - std::string::const_iterator window_end = window_begin + pattern_length_ - 1; - uint32 window_sum = - std::accumulate(window_begin, window_end, static_cast<uint32>(0u)); - while (window_end != value_as_string.end()) { - window_sum += *window_end++; - if (window_sum == pattern_sum_ && context->GetHash(std::string( - window_begin, window_end)) == hashed_pattern_) - return context->ContinueExecution(); - window_sum -= *window_begin++; - } - return true; - } - - private: - std::string hashed_pattern_; - size_t pattern_length_; - uint32 pattern_sum_; - DISALLOW_COPY_AND_ASSIGN(CompareNodeSubstring); -}; - -class StopExecutingSentenceOperation : public Operation { - public: - StopExecutingSentenceOperation() {} - ~StopExecutingSentenceOperation() override {} - bool Execute(ExecutionContext* context) override { return false; } - - private: - DISALLOW_COPY_AND_ASSIGN(StopExecutingSentenceOperation); -}; - -class Parser { - public: - explicit Parser(const std::string& program) - : program_(program), - next_instruction_index_(0u) {} - ~Parser() {} - bool ParseNextSentence(ScopedVector<Operation>* output) { - ScopedVector<Operation> operators; - bool sentence_ended = false; - while (next_instruction_index_ < program_.size() && !sentence_ended) { - uint8 op_code = 0; - if (!ReadOpCode(&op_code)) - return false; - switch (static_cast<jtl_foundation::OpCodes>(op_code)) { - case jtl_foundation::NAVIGATE: { - std::string hashed_key; - if (!ReadHash(&hashed_key)) - return false; - operators.push_back(new NavigateOperation(hashed_key)); - break; - } - case jtl_foundation::NAVIGATE_ANY: - operators.push_back(new NavigateAnyOperation); - break; - case jtl_foundation::NAVIGATE_BACK: - operators.push_back(new NavigateBackOperation); - break; - case jtl_foundation::STORE_BOOL: { - std::string hashed_name; - if (!ReadHash(&hashed_name) || !base::IsStringUTF8(hashed_name)) - return false; - bool value = false; - if (!ReadBool(&value)) - return false; - operators.push_back(new StoreValue( - hashed_name, - scoped_ptr<base::Value>(new base::FundamentalValue(value)))); - break; - } - case jtl_foundation::COMPARE_STORED_BOOL: { - std::string hashed_name; - if (!ReadHash(&hashed_name) || !base::IsStringUTF8(hashed_name)) - return false; - bool value = false; - if (!ReadBool(&value)) - return false; - bool default_value = false; - if (!ReadBool(&default_value)) - return false; - operators.push_back(new CompareStoredValue( - hashed_name, - scoped_ptr<base::Value>(new base::FundamentalValue(value)), - scoped_ptr<base::Value>( - new base::FundamentalValue(default_value)))); - break; - } - case jtl_foundation::STORE_HASH: { - std::string hashed_name; - if (!ReadHash(&hashed_name) || !base::IsStringUTF8(hashed_name)) - return false; - std::string hashed_value; - if (!ReadHash(&hashed_value)) - return false; - operators.push_back(new StoreValue( - hashed_name, - scoped_ptr<base::Value>(new base::StringValue(hashed_value)))); - break; - } - case jtl_foundation::COMPARE_STORED_HASH: { - std::string hashed_name; - if (!ReadHash(&hashed_name) || !base::IsStringUTF8(hashed_name)) - return false; - std::string hashed_value; - if (!ReadHash(&hashed_value)) - return false; - std::string hashed_default_value; - if (!ReadHash(&hashed_default_value)) - return false; - operators.push_back(new CompareStoredValue( - hashed_name, - scoped_ptr<base::Value>(new base::StringValue(hashed_value)), - scoped_ptr<base::Value>( - new base::StringValue(hashed_default_value)))); - break; - } - case jtl_foundation::STORE_NODE_BOOL: { - std::string hashed_name; - if (!ReadHash(&hashed_name) || !base::IsStringUTF8(hashed_name)) - return false; - operators.push_back(new StoreNodeValue<true>(hashed_name)); - break; - } - case jtl_foundation::STORE_NODE_HASH: { - std::string hashed_name; - if (!ReadHash(&hashed_name) || !base::IsStringUTF8(hashed_name)) - return false; - operators.push_back(new StoreNodeValue<false>(hashed_name)); - break; - } - case jtl_foundation::STORE_NODE_REGISTERABLE_DOMAIN_HASH: { - std::string hashed_name; - if (!ReadHash(&hashed_name) || !base::IsStringUTF8(hashed_name)) - return false; - operators.push_back(new StoreNodeRegisterableDomain(hashed_name)); - break; - } - case jtl_foundation::COMPARE_NODE_BOOL: { - bool value = false; - if (!ReadBool(&value)) - return false; - operators.push_back(new CompareNodeBool(value)); - break; - } - case jtl_foundation::COMPARE_NODE_HASH: { - std::string hashed_value; - if (!ReadHash(&hashed_value)) - return false; - operators.push_back(new CompareNodeHash(hashed_value)); - break; - } - case jtl_foundation::COMPARE_NODE_HASH_NOT: { - std::string hashed_value; - if (!ReadHash(&hashed_value)) - return false; - operators.push_back(new CompareNodeHashNot(hashed_value)); - break; - } - case jtl_foundation::COMPARE_NODE_TO_STORED_BOOL: { - std::string hashed_name; - if (!ReadHash(&hashed_name) || !base::IsStringUTF8(hashed_name)) - return false; - operators.push_back(new CompareNodeToStored<true>(hashed_name)); - break; - } - case jtl_foundation::COMPARE_NODE_TO_STORED_HASH: { - std::string hashed_name; - if (!ReadHash(&hashed_name) || !base::IsStringUTF8(hashed_name)) - return false; - operators.push_back(new CompareNodeToStored<false>(hashed_name)); - break; - } - case jtl_foundation::COMPARE_NODE_SUBSTRING: { - std::string hashed_pattern; - uint32 pattern_length = 0, pattern_sum = 0; - if (!ReadHash(&hashed_pattern)) - return false; - if (!ReadUint32(&pattern_length) || pattern_length == 0) - return false; - if (!ReadUint32(&pattern_sum)) - return false; - operators.push_back(new CompareNodeSubstring( - hashed_pattern, pattern_length, pattern_sum)); - break; - } - case jtl_foundation::STOP_EXECUTING_SENTENCE: - operators.push_back(new StopExecutingSentenceOperation); - break; - case jtl_foundation::END_OF_SENTENCE: - sentence_ended = true; - break; - default: - return false; - } - } - output->swap(operators); - return true; - } - - bool HasNextSentence() const { - return next_instruction_index_ < program_.size(); - } - - private: - // Reads an uint8 and returns whether this operation was successful. - bool ReadUint8(uint8* out) { - DCHECK(out); - if (next_instruction_index_ + 1u > program_.size()) - return false; - *out = static_cast<uint8>(program_[next_instruction_index_]); - ++next_instruction_index_; - return true; - } - - // Reads an uint32 and returns whether this operation was successful. - bool ReadUint32(uint32* out) { - DCHECK(out); - if (next_instruction_index_ + 4u > program_.size()) - return false; - *out = 0u; - for (int i = 0; i < 4; ++i) { - *out >>= 8; - *out |= static_cast<uint8>(program_[next_instruction_index_]) << 24; - ++next_instruction_index_; - } - return true; - } - - // Reads an operator code and returns whether this operation was successful. - bool ReadOpCode(uint8* out) { return ReadUint8(out); } - - bool ReadHash(std::string* out) { - DCHECK(out); - if (next_instruction_index_ + jtl_foundation::kHashSizeInBytes > - program_.size()) - return false; - *out = program_.substr(next_instruction_index_, - jtl_foundation::kHashSizeInBytes); - next_instruction_index_ += jtl_foundation::kHashSizeInBytes; - DCHECK(jtl_foundation::Hasher::IsHash(*out)); - return true; - } - - bool ReadBool(bool* out) { - DCHECK(out); - uint8 value = 0; - if (!ReadUint8(&value)) - return false; - if (value == 0) - *out = false; - else if (value == 1) - *out = true; - else - return false; - return true; - } - - std::string program_; - size_t next_instruction_index_; - DISALLOW_COPY_AND_ASSIGN(Parser); -}; - -} // namespace - -JtlInterpreter::JtlInterpreter( - const std::string& hasher_seed, - const std::string& program, - const base::DictionaryValue* input) - : hasher_seed_(hasher_seed), - program_(program), - input_(input), - working_memory_(new base::DictionaryValue), - result_(OK) { - DCHECK(input->IsType(base::Value::TYPE_DICTIONARY)); -} - -JtlInterpreter::~JtlInterpreter() {} - -void JtlInterpreter::Execute() { - jtl_foundation::Hasher hasher(hasher_seed_); - Parser parser(program_); - while (parser.HasNextSentence()) { - ScopedVector<Operation> sentence; - if (!parser.ParseNextSentence(&sentence)) { - result_ = PARSE_ERROR; - return; - } - ExecutionContext context( - &hasher, sentence.get(), input_, working_memory_.get()); - context.ContinueExecution(); - if (context.error()) { - result_ = RUNTIME_ERROR; - return; - } - } -} - -bool JtlInterpreter::GetOutputBoolean(const std::string& unhashed_key, - bool* output) const { - std::string hashed_key = - jtl_foundation::Hasher(hasher_seed_).GetHash(unhashed_key); - return working_memory_->GetBoolean(hashed_key, output); -} - -bool JtlInterpreter::GetOutputString(const std::string& unhashed_key, - std::string* output) const { - std::string hashed_key = - jtl_foundation::Hasher(hasher_seed_).GetHash(unhashed_key); - return working_memory_->GetString(hashed_key, output); -} - -int JtlInterpreter::CalculateProgramChecksum() const { - uint8 digest[3] = {}; - crypto::SHA256HashString(program_, digest, arraysize(digest)); - return static_cast<uint32>(digest[0]) << 16 | - static_cast<uint32>(digest[1]) << 8 | - static_cast<uint32>(digest[2]); -}
diff --git a/chrome/browser/profile_resetter/jtl_interpreter.h b/chrome/browser/profile_resetter/jtl_interpreter.h deleted file mode 100644 index cafb7fd..0000000 --- a/chrome/browser/profile_resetter/jtl_interpreter.h +++ /dev/null
@@ -1,61 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_PROFILE_RESETTER_JTL_INTERPRETER_H_ -#define CHROME_BROWSER_PROFILE_RESETTER_JTL_INTERPRETER_H_ - -#include <string> - -#include "base/basictypes.h" -#include "base/values.h" - -// Executes a JTL program on a given dictionary. -// -// JTL (Json Traversal Language) programs are defined in jtl_foundation.h -class JtlInterpreter { - public: - enum Result { - OK, - PARSE_ERROR, - RUNTIME_ERROR, - RESULT_MAX, - }; - - // |hasher_seed| is a value used in jtl_foundation::Hasher. All node names, - // strings, integers and doubles are hashed before being compared to hash - // values listed in |program|. - // |program| is a byte array containing a JTL program. - // |input| is a dictionary on which the program is evaluated. - JtlInterpreter(const std::string& hasher_seed, - const std::string& program, - const base::DictionaryValue* input); - ~JtlInterpreter(); - - void Execute(); - - Result result() const { return result_; } - const base::DictionaryValue* working_memory() const { - return working_memory_.get(); - } - bool GetOutputBoolean(const std::string& unhashed_key, bool* output) const; - bool GetOutputString(const std::string& unhashed_key, - std::string* output) const; - - // Generates a checksum of the loaded program, defined as the first 3 bytes of - // the program's SHA-256 hash interpreted as a big-endian integer. - int CalculateProgramChecksum() const; - - private: - // Input. - std::string hasher_seed_; - std::string program_; - const base::DictionaryValue* input_; - // Output. - scoped_ptr<base::DictionaryValue> working_memory_; - Result result_; - - DISALLOW_COPY_AND_ASSIGN(JtlInterpreter); -}; - -#endif // CHROME_BROWSER_PROFILE_RESETTER_JTL_INTERPRETER_H_
diff --git a/chrome/browser/profile_resetter/jtl_interpreter_unittest.cc b/chrome/browser/profile_resetter/jtl_interpreter_unittest.cc deleted file mode 100644 index 8457264f..0000000 --- a/chrome/browser/profile_resetter/jtl_interpreter_unittest.cc +++ /dev/null
@@ -1,689 +0,0 @@ -// Copyright 2011 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/jtl_interpreter.h" - -#include <numeric> - -#include "base/strings/string_util.h" -#include "base/test/values_test_util.h" -#include "chrome/browser/profile_resetter/jtl_foundation.h" -#include "chrome/browser/profile_resetter/jtl_instructions.h" -#include "crypto/hmac.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace { - -const char seed[] = "foobar"; - -#define KEY_HASH_1 GetHash("KEY_HASH_1") -#define KEY_HASH_2 GetHash("KEY_HASH_2") -#define KEY_HASH_3 GetHash("KEY_HASH_3") -#define KEY_HASH_4 GetHash("KEY_HASH_4") - -#define VALUE_HASH_1 GetHash("VALUE_HASH_1") -#define VALUE_HASH_2 GetHash("VALUE_HASH_2") - -#define VAR_HASH_1 "01234567890123456789012345678901" -#define VAR_HASH_2 "12345678901234567890123456789012" - -std::string GetHash(const std::string& input) { - return jtl_foundation::Hasher(seed).GetHash(input); -} - -std::string EncodeUint32(uint32 value) { - std::string bytecode; - for (int i = 0; i < 4; ++i) { - bytecode.push_back(static_cast<char>(value & 0xFFu)); - value >>= 8; - } - return bytecode; -} - -// escaped_json_param may contain ' characters that are replaced with ". This -// makes the code more readable because we need less escaping. -#define INIT_INTERPRETER(program_param, escaped_json_param) \ - const char* escaped_json = escaped_json_param; \ - std::string json; \ - base::ReplaceChars(escaped_json, "'", "\"", &json); \ - scoped_ptr<base::Value> json_value(ParseJson(json)); \ - JtlInterpreter interpreter( \ - seed, \ - program_param, \ - static_cast<const base::DictionaryValue*>(json_value.get())); \ - interpreter.Execute() - -using base::test::ParseJson; - -TEST(JtlInterpreter, Store) { - INIT_INTERPRETER( - OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE), - "{ 'KEY_HASH_1': 'VALUE_HASH_1' }"); - EXPECT_EQ(JtlInterpreter::OK, interpreter.result()); - base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1); -} - -TEST(JtlInterpreter, NavigateAndStore) { - INIT_INTERPRETER( - OP_NAVIGATE(KEY_HASH_1) + - OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE), - "{ 'KEY_HASH_1': 'VALUE_HASH_1' }"); - EXPECT_EQ(JtlInterpreter::OK, interpreter.result()); - base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1); -} - -TEST(JtlInterpreter, FailNavigate) { - INIT_INTERPRETER( - OP_NAVIGATE(KEY_HASH_2) + - OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE), - "{ 'KEY_HASH_1': 'VALUE_HASH_1' }"); - EXPECT_EQ(JtlInterpreter::OK, interpreter.result()); - EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1)); -} - -TEST(JtlInterpreter, ConsecutiveNavigate) { - INIT_INTERPRETER( - OP_NAVIGATE(KEY_HASH_1) + - OP_NAVIGATE(KEY_HASH_2) + - OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE), - "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }"); - EXPECT_EQ(JtlInterpreter::OK, interpreter.result()); - base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1); -} - -TEST(JtlInterpreter, FailConsecutiveNavigate) { - INIT_INTERPRETER( - OP_NAVIGATE(KEY_HASH_1) + - OP_NAVIGATE(KEY_HASH_2) + - OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE), - "{ 'KEY_HASH_1': 'foo' }"); - EXPECT_EQ(JtlInterpreter::OK, interpreter.result()); - EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1)); -} - -TEST(JtlInterpreter, NavigateAnyInDictionary) { - INIT_INTERPRETER( - OP_NAVIGATE(KEY_HASH_1) + - OP_NAVIGATE_ANY + - OP_NAVIGATE(KEY_HASH_4) + - OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE), - "{ 'KEY_HASH_1':" - " { 'KEY_HASH_2': {'KEY_HASH_3': 'VALUE_HASH_1' }," - " 'KEY_HASH_3': {'KEY_HASH_4': 'VALUE_HASH_1' }" - " } }"); - EXPECT_EQ(JtlInterpreter::OK, interpreter.result()); - base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1); -} - -TEST(JtlInterpreter, NavigateAnyInList) { - INIT_INTERPRETER( - OP_NAVIGATE(KEY_HASH_1) + - OP_NAVIGATE_ANY + - OP_NAVIGATE(KEY_HASH_4) + - OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE), - "{ 'KEY_HASH_1':" - " [ {'KEY_HASH_3': 'VALUE_HASH_1' }," - " {'KEY_HASH_4': 'VALUE_HASH_1' }" - " ] }"); - EXPECT_EQ(JtlInterpreter::OK, interpreter.result()); - base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1); -} - -TEST(JtlInterpreter, NavigateBack) { - INIT_INTERPRETER( - OP_NAVIGATE(KEY_HASH_1) + - OP_NAVIGATE(KEY_HASH_2) + - OP_NAVIGATE_BACK + - OP_NAVIGATE(KEY_HASH_3) + - OP_NAVIGATE(KEY_HASH_4) + - OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE), - "{ 'KEY_HASH_1':" - " { 'KEY_HASH_2': {'KEY_HASH_3': 'VALUE_HASH_1' }," - " 'KEY_HASH_3': {'KEY_HASH_4': 'VALUE_HASH_1' }" - " } }"); - EXPECT_EQ(JtlInterpreter::OK, interpreter.result()); - base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1); -} - -TEST(JtlInterpreter, StoreTwoValues) { - INIT_INTERPRETER( - OP_NAVIGATE(KEY_HASH_1) + - OP_NAVIGATE(KEY_HASH_2) + - OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE) + - OP_STORE_HASH(VAR_HASH_2, VALUE_HASH_1), - "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }"); - EXPECT_EQ(JtlInterpreter::OK, interpreter.result()); - base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1); - base::ExpectDictStringValue(VALUE_HASH_1, *interpreter.working_memory(), - VAR_HASH_2); -} - -TEST(JtlInterpreter, CompareStoredMatch) { - INIT_INTERPRETER( - OP_NAVIGATE(KEY_HASH_1) + - OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE) + - OP_NAVIGATE(KEY_HASH_2) + - OP_COMPARE_STORED_BOOL(VAR_HASH_1, VALUE_TRUE, VALUE_FALSE) + - OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE), - "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }"); - EXPECT_EQ(JtlInterpreter::OK, interpreter.result()); - base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1); - base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_2); -} - -TEST(JtlInterpreter, CompareStoredMismatch) { - INIT_INTERPRETER( - OP_NAVIGATE(KEY_HASH_1) + - OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE) + - OP_NAVIGATE(KEY_HASH_2) + - OP_COMPARE_STORED_BOOL(VAR_HASH_1, VALUE_FALSE, VALUE_TRUE) + - OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE), - "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }"); - EXPECT_EQ(JtlInterpreter::OK, interpreter.result()); - base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1); - EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2)); -} - -TEST(JtlInterpreter, CompareStoredNoValueMatchingDefault) { - INIT_INTERPRETER( - OP_NAVIGATE(KEY_HASH_1) + - OP_NAVIGATE(KEY_HASH_2) + - OP_COMPARE_STORED_BOOL(VAR_HASH_1, VALUE_TRUE, VALUE_TRUE) + - OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE), - "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }"); - EXPECT_EQ(JtlInterpreter::OK, interpreter.result()); - base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_2); -} - -TEST(JtlInterpreter, CompareStoredNoValueMismatchingDefault) { - INIT_INTERPRETER( - OP_NAVIGATE(KEY_HASH_1) + - OP_NAVIGATE(KEY_HASH_2) + - OP_COMPARE_STORED_BOOL(VAR_HASH_1, VALUE_TRUE, VALUE_FALSE) + - OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE), - "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }"); - EXPECT_EQ(JtlInterpreter::OK, interpreter.result()); - EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2)); -} - -TEST(JtlInterpreter, CompareBool) { - struct TestCase { - std::string expected_value; - const char* json; - bool expected_success; - } cases[] = { - { VALUE_TRUE, "{ 'KEY_HASH_1': true }", true }, - { VALUE_FALSE, "{ 'KEY_HASH_1': false }", true }, - { VALUE_TRUE, "{ 'KEY_HASH_1': false }", false }, - { VALUE_TRUE, "{ 'KEY_HASH_1': 'abc' }", false }, - { VALUE_TRUE, "{ 'KEY_HASH_1': 1 }", false }, - { VALUE_TRUE, "{ 'KEY_HASH_1': 1.2 }", false }, - { VALUE_TRUE, "{ 'KEY_HASH_1': [1] }", false }, - { VALUE_TRUE, "{ 'KEY_HASH_1': {'a': 'b'} }", false }, - }; - - for (size_t i = 0; i < arraysize(cases); ++i) { - SCOPED_TRACE(testing::Message() << "Iteration " << i); - INIT_INTERPRETER( - OP_NAVIGATE(KEY_HASH_1) + - OP_COMPARE_NODE_BOOL(cases[i].expected_value) + - OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE), - cases[i].json); - EXPECT_EQ(JtlInterpreter::OK, interpreter.result()); - if (cases[i].expected_success) { - base::ExpectDictBooleanValue( - true, *interpreter.working_memory(), VAR_HASH_1); - } else { - EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1)); - } - } -} - -TEST(JtlInterpreter, CompareHashString) { - struct TestCase { - std::string expected_value; - const char* json; - bool expected_success; - } cases[] = { - { VALUE_HASH_1, "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", true }, - { VALUE_HASH_1, "{ 'KEY_HASH_1': 'VALUE_HASH_2' }", false }, - { VALUE_HASH_1, "{ 'KEY_HASH_1': true }", false }, - { VALUE_HASH_1, "{ 'KEY_HASH_1': 1 }", false }, - { VALUE_HASH_1, "{ 'KEY_HASH_1': 1.1 }", false }, - { VALUE_HASH_1, "{ 'KEY_HASH_1': [1] }", false }, - { VALUE_HASH_1, "{ 'KEY_HASH_1': {'a': 'b'} }", false }, - - { GetHash("1.2"), "{ 'KEY_HASH_1': 1.2 }", true }, - { GetHash("1.2"), "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", false }, - { GetHash("1.2"), "{ 'KEY_HASH_1': true }", false }, - { GetHash("1.2"), "{ 'KEY_HASH_1': 1 }", false }, - { GetHash("1.2"), "{ 'KEY_HASH_1': 1.3 }", false }, - { GetHash("1.2"), "{ 'KEY_HASH_1': [1] }", false }, - { GetHash("1.2"), "{ 'KEY_HASH_1': {'a': 'b'} }", false }, - - { GetHash("1"), "{ 'KEY_HASH_1': 1 }", true }, - { GetHash("1"), "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", false }, - { GetHash("1"), "{ 'KEY_HASH_1': true }", false }, - { GetHash("1"), "{ 'KEY_HASH_1': 2 }", false }, - { GetHash("1"), "{ 'KEY_HASH_1': 1.1 }", false }, - { GetHash("1"), "{ 'KEY_HASH_1': [1] }", false }, - { GetHash("1"), "{ 'KEY_HASH_1': {'a': 'b'} }", false }, - }; - - for (size_t i = 0; i < arraysize(cases); ++i) { - SCOPED_TRACE(testing::Message() << "Iteration " << i); - INIT_INTERPRETER( - OP_NAVIGATE(KEY_HASH_1) + - OP_COMPARE_NODE_HASH(cases[i].expected_value) + - OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE), - cases[i].json); - EXPECT_EQ(JtlInterpreter::OK, interpreter.result()); - if (cases[i].expected_success) { - base::ExpectDictBooleanValue( - true, *interpreter.working_memory(), VAR_HASH_1); - } else { - EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1)); - } - } - - for (size_t i = 0; i < arraysize(cases); ++i) { - SCOPED_TRACE(testing::Message() << "Negated, Iteration " << i); - INIT_INTERPRETER( - OP_NAVIGATE(KEY_HASH_1) + - OP_COMPARE_NODE_HASH_NOT(cases[i].expected_value) + - OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE), - cases[i].json); - EXPECT_EQ(JtlInterpreter::OK, interpreter.result()); - if (!cases[i].expected_success) { - base::ExpectDictBooleanValue( - true, *interpreter.working_memory(), VAR_HASH_1); - } else { - EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1)); - } - } -} - -TEST(JtlInterpreter, StoreNodeBool) { - struct TestCase { - bool expected_value; - const char* json; - bool expected_success; - } cases[] = { - { true, "{ 'KEY_HASH_1': true }", true }, - { false, "{ 'KEY_HASH_1': false }", true }, - { false, "{ 'KEY_HASH_1': 'abc' }", false }, - { false, "{ 'KEY_HASH_1': 1 }", false }, - { false, "{ 'KEY_HASH_1': 1.2 }", false }, - { false, "{ 'KEY_HASH_1': [1] }", false }, - { false, "{ 'KEY_HASH_1': {'a': 'b'} }", false }, - }; - - for (size_t i = 0; i < arraysize(cases); ++i) { - SCOPED_TRACE(testing::Message() << "Iteration " << i); - INIT_INTERPRETER( - OP_NAVIGATE(KEY_HASH_1) + - OP_STORE_NODE_BOOL(VAR_HASH_1) + - OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE), - cases[i].json); - EXPECT_EQ(JtlInterpreter::OK, interpreter.result()); - if (cases[i].expected_success) { - base::ExpectDictBooleanValue( - cases[i].expected_value, *interpreter.working_memory(), VAR_HASH_1); - base::ExpectDictBooleanValue( - true, *interpreter.working_memory(), VAR_HASH_2); - } else { - EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1)); - EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2)); - } - } -} - -TEST(JtlInterpreter, CompareNodeToStoredBool) { - struct TestCase { - std::string stored_value; - const char* json; - bool expected_success; - } cases[] = { - { VALUE_TRUE, "{ 'KEY_HASH_1': true }", true }, - { VALUE_FALSE, "{ 'KEY_HASH_1': false }", true }, - { VALUE_FALSE, "{ 'KEY_HASH_1': true }", false }, - { std::string(), "{ 'KEY_HASH_1': true }", false }, - - { VALUE_HASH_1, "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", false }, - { GetHash("1"), "{ 'KEY_HASH_1': 1 }", false }, - { GetHash("1.2"), "{ 'KEY_HASH_1': 1.2 }", false }, - - { VALUE_HASH_1, "{ 'KEY_HASH_1': true }", false }, - { GetHash("1"), "{ 'KEY_HASH_1': true }", false }, - { GetHash("1.2"), "{ 'KEY_HASH_1': true }", false }, - - { VALUE_TRUE, "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", false }, - { VALUE_TRUE, "{ 'KEY_HASH_1': 1 }", false }, - { VALUE_TRUE, "{ 'KEY_HASH_1': 1.2 }", false }, - { VALUE_TRUE, "{ 'KEY_HASH_1': [1] }", false }, - { VALUE_TRUE, "{ 'KEY_HASH_1': {'a': 'b'} }", false }, - }; - - for (size_t i = 0; i < arraysize(cases); ++i) { - SCOPED_TRACE(testing::Message() << "Iteration " << i); - std::string store_op; - if (cases[i].stored_value == VALUE_TRUE || - cases[i].stored_value == VALUE_FALSE) - store_op = OP_STORE_BOOL(VAR_HASH_1, cases[i].stored_value); - else if (!cases[i].stored_value.empty()) - store_op = OP_STORE_HASH(VAR_HASH_1, cases[i].stored_value); - INIT_INTERPRETER( - store_op + - OP_NAVIGATE(KEY_HASH_1) + - OP_COMPARE_NODE_TO_STORED_BOOL(VAR_HASH_1) + - OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE), - cases[i].json); - EXPECT_EQ(JtlInterpreter::OK, interpreter.result()); - if (cases[i].expected_success) { - base::ExpectDictBooleanValue( - true, *interpreter.working_memory(), VAR_HASH_2); - } else { - EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2)); - } - } -} - -TEST(JtlInterpreter, StoreNodeHash) { - struct TestCase { - std::string expected_value; - const char* json; - bool expected_success; - } cases[] = { - { VALUE_HASH_1, "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", true }, - { VALUE_HASH_2, "{ 'KEY_HASH_1': 'VALUE_HASH_2' }", true }, - { GetHash("1"), "{ 'KEY_HASH_1': 1 }", true }, - { GetHash("1.2"), "{ 'KEY_HASH_1': 1.2 }", true }, - { std::string(), "{ 'KEY_HASH_1': true }", false }, - { std::string(), "{ 'KEY_HASH_1': [1] }", false }, - { std::string(), "{ 'KEY_HASH_1': {'a': 'b'} }", false }, - }; - - for (size_t i = 0; i < arraysize(cases); ++i) { - SCOPED_TRACE(testing::Message() << "Iteration " << i); - INIT_INTERPRETER( - OP_NAVIGATE(KEY_HASH_1) + - OP_STORE_NODE_HASH(VAR_HASH_1) + - OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE), - cases[i].json); - EXPECT_EQ(JtlInterpreter::OK, interpreter.result()); - if (cases[i].expected_success) { - base::ExpectDictStringValue( - cases[i].expected_value, *interpreter.working_memory(), VAR_HASH_1); - base::ExpectDictBooleanValue( - true, *interpreter.working_memory(), VAR_HASH_2); - } else { - EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1)); - EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2)); - } - } -} - -TEST(JtlInterpreter, CompareNodeToStoredHash) { - struct TestCase { - std::string stored_value; - const char* json; - bool expected_success; - } cases[] = { - { VALUE_HASH_1, "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", true }, - { VALUE_HASH_2, "{ 'KEY_HASH_1': 'VALUE_HASH_2' }", true }, - { std::string(), "{ 'KEY_HASH_1': 'VALUE_HASH_2' }", false }, - { VALUE_HASH_1, "{ 'KEY_HASH_1': 'VALUE_HASH_2' }", false }, - { VALUE_HASH_1, "{ 'KEY_HASH_1': true }", false }, - { VALUE_HASH_1, "{ 'KEY_HASH_1': 1 }", false }, - { VALUE_HASH_1, "{ 'KEY_HASH_1': 1.1 }", false }, - { VALUE_HASH_1, "{ 'KEY_HASH_1': [1] }", false }, - { VALUE_HASH_1, "{ 'KEY_HASH_1': {'a': 'b'} }", false }, - - { GetHash("1.2"), "{ 'KEY_HASH_1': 1.2 }", true }, - { GetHash("1.3"), "{ 'KEY_HASH_1': 1.3 }", true }, - { std::string(), "{ 'KEY_HASH_1': 1.2 }", false }, - { GetHash("1.2"), "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", false }, - { GetHash("1.2"), "{ 'KEY_HASH_1': true }", false }, - { GetHash("1.2"), "{ 'KEY_HASH_1': 1 }", false }, - { GetHash("1.2"), "{ 'KEY_HASH_1': 1.3 }", false }, - { GetHash("1.2"), "{ 'KEY_HASH_1': [1] }", false }, - { GetHash("1.2"), "{ 'KEY_HASH_1': {'a': 'b'} }", false }, - - { GetHash("1"), "{ 'KEY_HASH_1': 1 }", true }, - { GetHash("2"), "{ 'KEY_HASH_1': 2 }", true }, - { std::string(), "{ 'KEY_HASH_1': 2 }", false }, - { GetHash("1"), "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", false }, - { GetHash("1"), "{ 'KEY_HASH_1': true }", false }, - { GetHash("1"), "{ 'KEY_HASH_1': 2 }", false }, - { GetHash("1"), "{ 'KEY_HASH_1': 1.1 }", false }, - { GetHash("1"), "{ 'KEY_HASH_1': [1] }", false }, - { GetHash("1"), "{ 'KEY_HASH_1': {'a': 'b'} }", false }, - - { VALUE_TRUE, "{ 'KEY_HASH_1': 'VALUE_HASH_1' }", false }, - { VALUE_TRUE, "{ 'KEY_HASH_1': 1 }", false }, - { VALUE_TRUE, "{ 'KEY_HASH_1': 1.3 }", false }, - { VALUE_TRUE, "{ 'KEY_HASH_1': [1] }", false }, - { VALUE_TRUE, "{ 'KEY_HASH_1': {'a': 'b'} }", false }, - - { VALUE_TRUE, "{ 'KEY_HASH_1': true }", false }, - { VALUE_FALSE, "{ 'KEY_HASH_1': false }", false }, - }; - - for (size_t i = 0; i < arraysize(cases); ++i) { - SCOPED_TRACE(testing::Message() << "Iteration " << i); - std::string store_op; - if (cases[i].stored_value == VALUE_TRUE || - cases[i].stored_value == VALUE_FALSE) - store_op = OP_STORE_BOOL(VAR_HASH_1, cases[i].stored_value); - else if (!cases[i].stored_value.empty()) - store_op = OP_STORE_HASH(VAR_HASH_1, cases[i].stored_value); - INIT_INTERPRETER( - store_op + - OP_NAVIGATE(KEY_HASH_1) + - OP_COMPARE_NODE_TO_STORED_HASH(VAR_HASH_1) + - OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE), - cases[i].json); - EXPECT_EQ(JtlInterpreter::OK, interpreter.result()); - if (cases[i].expected_success) { - base::ExpectDictBooleanValue( - true, *interpreter.working_memory(), VAR_HASH_2); - } else { - EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2)); - } - } -} - -TEST(JtlInterpreter, CompareSubstring) { - struct TestCase { - std::string pattern; - const char* json; - bool expected_success; - } cases[] = { - { "abc", "{ 'KEY_HASH_1': 'abcdefghijklmnopqrstuvwxyz' }", true }, - { "xyz", "{ 'KEY_HASH_1': 'abcdefghijklmnopqrstuvwxyz' }", true }, - { "m", "{ 'KEY_HASH_1': 'abcdefghijklmnopqrstuvwxyz' }", true }, - { "abc", "{ 'KEY_HASH_1': 'abc' }", true }, - { "cba", "{ 'KEY_HASH_1': 'abcdefghijklmnopqrstuvwxyz' }", false }, - { "acd", "{ 'KEY_HASH_1': 'abcdefghijklmnopqrstuvwxyz' }", false }, - { "waaaaaaay_too_long", "{ 'KEY_HASH_1': 'abc' }", false }, - - { VALUE_HASH_1, "{ 'KEY_HASH_1': true }", false }, - { VALUE_HASH_1, "{ 'KEY_HASH_1': 1 }", false }, - { VALUE_HASH_1, "{ 'KEY_HASH_1': 1.1 }", false }, - { VALUE_HASH_1, "{ 'KEY_HASH_1': [1] }", false }, - { VALUE_HASH_1, "{ 'KEY_HASH_1': {'a': 'b'} }", false }, - }; - - for (size_t i = 0; i < arraysize(cases); ++i) { - SCOPED_TRACE(testing::Message() << "Iteration " << i); - std::string pattern = cases[i].pattern; - uint32 pattern_sum = std::accumulate( - pattern.begin(), pattern.end(), static_cast<uint32>(0u)); - INIT_INTERPRETER( - OP_NAVIGATE(KEY_HASH_1) + - OP_COMPARE_NODE_SUBSTRING(GetHash(pattern), - EncodeUint32(pattern.size()), - EncodeUint32(pattern_sum)) + - OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE), - cases[i].json); - EXPECT_EQ(JtlInterpreter::OK, interpreter.result()); - if (cases[i].expected_success) { - base::ExpectDictBooleanValue( - true, *interpreter.working_memory(), VAR_HASH_1); - } else { - EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1)); - } - } -} - -TEST(JtlInterpreter, StoreNodeRegisterableDomainHash) { - struct TestCase { - std::string expected_value; - const char* json; - bool expected_success; - } cases[] = { - { GetHash("google"), "{ 'KEY_HASH_1': 'http://google.com/path' }", true }, - { GetHash("google"), "{ 'KEY_HASH_1': 'http://mail.google.com/' }", true }, - { GetHash("google"), "{ 'KEY_HASH_1': 'http://google.co.uk/' }", true }, - { GetHash("google"), "{ 'KEY_HASH_1': 'http://google.com./' }", true }, - { GetHash("google"), "{ 'KEY_HASH_1': 'http://..google.com/' }", true }, - - { GetHash("foo"), "{ 'KEY_HASH_1': 'http://foo.bar/path' }", true }, - { GetHash("foo"), "{ 'KEY_HASH_1': 'http://sub.foo.bar' }", true }, - { GetHash("foo"), "{ 'KEY_HASH_1': 'http://foo.appspot.com/' }", true }, - { GetHash("foo"), "{ 'KEY_HASH_1': 'http://sub.foo.appspot.com' }", true }, - - { std::string(), "{ 'KEY_HASH_1': 'http://google.com../' }", false }, - - { std::string(), "{ 'KEY_HASH_1': 'http://bar/path' }", false }, - { std::string(), "{ 'KEY_HASH_1': 'http://co.uk/path' }", false }, - { std::string(), "{ 'KEY_HASH_1': 'http://appspot.com/path' }", false }, - { std::string(), "{ 'KEY_HASH_1': 'http://127.0.0.1/path' }", false }, - { std::string(), "{ 'KEY_HASH_1': 'file:///C:/bar.html' }", false }, - - { std::string(), "{ 'KEY_HASH_1': 1 }", false }, - { std::string(), "{ 'KEY_HASH_1': 1.2 }", false }, - { std::string(), "{ 'KEY_HASH_1': true }", false }, - { std::string(), "{ 'KEY_HASH_1': [1] }", false }, - { std::string(), "{ 'KEY_HASH_1': {'a': 'b'} }", false }, - }; - - for (size_t i = 0; i < arraysize(cases); ++i) { - SCOPED_TRACE(testing::Message() << "Iteration " << i); - INIT_INTERPRETER( - OP_NAVIGATE(KEY_HASH_1) + - OP_STORE_NODE_REGISTERABLE_DOMAIN_HASH(VAR_HASH_1) + - OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE), - cases[i].json); - EXPECT_EQ(JtlInterpreter::OK, interpreter.result()); - if (cases[i].expected_success) { - base::ExpectDictStringValue( - cases[i].expected_value, *interpreter.working_memory(), VAR_HASH_1); - base::ExpectDictBooleanValue( - true, *interpreter.working_memory(), VAR_HASH_2); - } else { - EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_1)); - EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2)); - } - } -} - -TEST(JtlInterpreter, Stop) { - INIT_INTERPRETER( - OP_NAVIGATE(KEY_HASH_1) + - OP_NAVIGATE(KEY_HASH_2) + - OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE) + - OP_STOP_EXECUTING_SENTENCE + - OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE), - "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }"); - EXPECT_EQ(JtlInterpreter::OK, interpreter.result()); - base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1); - EXPECT_FALSE(interpreter.working_memory()->HasKey(VAR_HASH_2)); -} - -TEST(JtlInterpreter, EndOfSentence) { - INIT_INTERPRETER( - OP_NAVIGATE(KEY_HASH_1) + - OP_NAVIGATE(KEY_HASH_2) + - OP_STORE_BOOL(VAR_HASH_1, VALUE_TRUE) + - OP_END_OF_SENTENCE + - OP_STORE_BOOL(VAR_HASH_2, VALUE_TRUE), - "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }"); - EXPECT_EQ(JtlInterpreter::OK, interpreter.result()); - base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_1); - base::ExpectDictBooleanValue(true, *interpreter.working_memory(), VAR_HASH_2); -} - -TEST(JtlInterpreter, InvalidBack) { - INIT_INTERPRETER( - OP_NAVIGATE(KEY_HASH_1) + - OP_NAVIGATE_BACK + - OP_NAVIGATE_BACK, - "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }"); - EXPECT_EQ(JtlInterpreter::RUNTIME_ERROR, interpreter.result()); -} - -TEST(JtlInterpreter, IncorrectPrograms) { - std::string missing_hash; - std::string missing_bool; - std::string invalid_hash("123"); - std::string invalid_bool("\x02", 1); - std::string invalid_operation("\x99", 1); - std::string programs[] = { - OP_NAVIGATE(missing_hash), - OP_NAVIGATE(invalid_hash), - OP_STORE_BOOL(VAR_HASH_1, invalid_bool), - OP_STORE_BOOL(missing_hash, VALUE_TRUE), - OP_STORE_BOOL(invalid_hash, VALUE_TRUE), - OP_COMPARE_STORED_BOOL(invalid_hash, VALUE_TRUE, VALUE_TRUE), - OP_COMPARE_STORED_BOOL(VAR_HASH_1, invalid_bool, VALUE_TRUE), - OP_COMPARE_STORED_BOOL(VAR_HASH_1, VALUE_TRUE, invalid_bool), - OP_COMPARE_STORED_BOOL(VAR_HASH_1, VALUE_TRUE, missing_bool), - OP_STORE_NODE_BOOL(missing_hash), - OP_STORE_NODE_BOOL(invalid_hash), - OP_STORE_NODE_HASH(missing_hash), - OP_STORE_NODE_HASH(invalid_hash), - OP_COMPARE_NODE_BOOL(missing_bool), - OP_COMPARE_NODE_BOOL(invalid_bool), - OP_COMPARE_NODE_HASH(missing_hash), - OP_COMPARE_NODE_HASH(invalid_hash), - OP_COMPARE_NODE_TO_STORED_BOOL(missing_hash), - OP_COMPARE_NODE_TO_STORED_BOOL(invalid_hash), - OP_COMPARE_NODE_TO_STORED_HASH(missing_hash), - OP_COMPARE_NODE_TO_STORED_HASH(invalid_hash), - invalid_operation, - }; - for (size_t i = 0; i < arraysize(programs); ++i) { - SCOPED_TRACE(testing::Message() << "Iteration " << i); - INIT_INTERPRETER(programs[i], - "{ 'KEY_HASH_1': { 'KEY_HASH_2': 'VALUE_HASH_1' } }"); - EXPECT_EQ(JtlInterpreter::PARSE_ERROR, interpreter.result()); - } -} - -TEST(JtlInterpreter, GetOutput) { - INIT_INTERPRETER( - OP_STORE_BOOL(GetHash("output1"), VALUE_TRUE) + - OP_STORE_HASH(GetHash("output2"), VALUE_HASH_1), - "{}"); - bool output1 = false; - std::string output2; - EXPECT_TRUE(interpreter.GetOutputBoolean("output1", &output1)); - EXPECT_EQ(true, output1); - EXPECT_TRUE(interpreter.GetOutputString("output2", &output2)); - EXPECT_EQ(VALUE_HASH_1, output2); - EXPECT_FALSE(interpreter.GetOutputBoolean("outputxx", &output1)); - EXPECT_FALSE(interpreter.GetOutputString("outputxx", &output2)); -} - -TEST(JtlInterpreter, CalculateProgramChecksum) { - const char kTestSeed[] = "Irrelevant seed value."; - const char kTestProgram[] = "The quick brown fox jumps over the lazy dog."; - // This program is invalid, but we are not actually executing it. - base::DictionaryValue input; - JtlInterpreter interpreter(kTestSeed, kTestProgram, &input); - EXPECT_EQ(0xef537f, interpreter.CalculateProgramChecksum()); -} - -} // namespace
diff --git a/chrome/browser/profile_resetter/profile_reset_global_error.cc b/chrome/browser/profile_resetter/profile_reset_global_error.cc deleted file mode 100644 index a355b642..0000000 --- a/chrome/browser/profile_resetter/profile_reset_global_error.cc +++ /dev/null
@@ -1,110 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/profile_resetter/profile_reset_global_error.h" - -#include "base/metrics/histogram.h" -#include "chrome/app/chrome_command_ids.h" -#include "chrome/browser/profile_resetter/automatic_profile_resetter.h" -#include "chrome/browser/profile_resetter/automatic_profile_resetter_factory.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/chrome_pages.h" -#include "chrome/browser/ui/global_error/global_error_service.h" -#include "chrome/browser/ui/global_error/global_error_service_factory.h" -#include "chrome/common/url_constants.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "ui/base/l10n/l10n_util.h" - -namespace { - -base::TimeDelta GetPromptDelayHistogramMaximum() { - return base::TimeDelta::FromDays(7); -} - -// Records the delay between when the reset prompt is triggered and when the -// bubble can actually be shown. -void RecordPromptDelay(const base::TimeDelta& delay) { - UMA_HISTOGRAM_CUSTOM_TIMES( - "AutomaticProfileReset.PromptDelay", delay, - base::TimeDelta::FromSeconds(1), GetPromptDelayHistogramMaximum(), 50); -} - -} // namespace - - -// ProfileResetGlobalError --------------------------------------------------- - -ProfileResetGlobalError::ProfileResetGlobalError(Profile* profile) - : profile_(profile), has_shown_bubble_view_(false), bubble_view_(NULL) { - AutomaticProfileResetter* automatic_profile_resetter = - AutomaticProfileResetterFactory::GetForBrowserContext(profile_); - if (automatic_profile_resetter) - automatic_profile_resetter_ = automatic_profile_resetter->AsWeakPtr(); -} - -ProfileResetGlobalError::~ProfileResetGlobalError() { - if (!has_shown_bubble_view_) - RecordPromptDelay(GetPromptDelayHistogramMaximum()); -} - -// static -bool ProfileResetGlobalError::IsSupportedOnPlatform(Browser* browser) { - return browser->window()->IsProfileResetBubbleSupported(); -} - -bool ProfileResetGlobalError::HasMenuItem() { return true; } - -int ProfileResetGlobalError::MenuItemCommandID() { - return IDC_SHOW_SETTINGS_RESET_BUBBLE; -} - -base::string16 ProfileResetGlobalError::MenuItemLabel() { - return l10n_util::GetStringFUTF16( - IDS_RESET_SETTINGS_MENU_ITEM, - l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME)); -} - -void ProfileResetGlobalError::ExecuteMenuItem(Browser* browser) { - chrome::ShowSettingsSubPage(browser, chrome::kResetProfileSettingsSubPage); -} - -bool ProfileResetGlobalError::HasBubbleView() { return true; } - -bool ProfileResetGlobalError::HasShownBubbleView() { - return has_shown_bubble_view_; -} - -void ProfileResetGlobalError::ShowBubbleView(Browser* browser) { - if (has_shown_bubble_view_) - return; - - has_shown_bubble_view_ = true; - bubble_view_ = browser->window()->ShowProfileResetBubble(AsWeakPtr()); - - if (automatic_profile_resetter_) - automatic_profile_resetter_->NotifyDidShowResetBubble(); - RecordPromptDelay(timer_.Elapsed()); -} - -void ProfileResetGlobalError::OnBubbleViewDidClose() { - bubble_view_ = NULL; -} - -void ProfileResetGlobalError::OnBubbleViewResetButtonPressed( - bool send_feedback) { - if (automatic_profile_resetter_) - automatic_profile_resetter_->TriggerProfileReset(send_feedback); -} - -void ProfileResetGlobalError::OnBubbleViewNoThanksButtonPressed() { - if (automatic_profile_resetter_) - automatic_profile_resetter_->SkipProfileReset(); -} - -GlobalErrorBubbleViewBase* ProfileResetGlobalError::GetBubbleView() { - return bubble_view_; -}
diff --git a/chrome/browser/profile_resetter/profile_reset_global_error.h b/chrome/browser/profile_resetter/profile_reset_global_error.h deleted file mode 100644 index e3031fc..0000000 --- a/chrome/browser/profile_resetter/profile_reset_global_error.h +++ /dev/null
@@ -1,72 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_PROFILE_RESETTER_PROFILE_RESET_GLOBAL_ERROR_H_ -#define CHROME_BROWSER_PROFILE_RESETTER_PROFILE_RESET_GLOBAL_ERROR_H_ - -#include "base/basictypes.h" -#include "base/memory/weak_ptr.h" -#include "base/timer/elapsed_timer.h" -#include "chrome/browser/ui/global_error/global_error.h" - -class AutomaticProfileResetter; -class GlobalErrorBubbleViewBase; -class Profile; - -// Encapsulates UI-related functionality for the one-time profile settings reset -// prompt. The UI consists of two parts: (1.) the profile reset (pop-up) bubble, -// and (2.) a menu item in the wrench menu (provided by us being a GlobalError). -class ProfileResetGlobalError - : public GlobalError, - public base::SupportsWeakPtr<ProfileResetGlobalError> { - public: - explicit ProfileResetGlobalError(Profile* profile); - ~ProfileResetGlobalError() override; - - // Returns whether or not the reset prompt is supported on this platform. - static bool IsSupportedOnPlatform(Browser* browser); - - // Called by the bubble view when it is closed. - void OnBubbleViewDidClose(); - - // Called when the user clicks on the 'Reset' button. The user can choose to - // send feedback containing the old settings that are now being reset, this is - // indicated by |send_feedback|. - void OnBubbleViewResetButtonPressed(bool send_feedback); - - // Called when the user clicks the 'No, thanks' button. - void OnBubbleViewNoThanksButtonPressed(); - - // GlobalError: - bool HasMenuItem() override; - int MenuItemCommandID() override; - base::string16 MenuItemLabel() override; - void ExecuteMenuItem(Browser* browser) override; - bool HasBubbleView() override; - bool HasShownBubbleView() override; - void ShowBubbleView(Browser* browser) override; - GlobalErrorBubbleViewBase* GetBubbleView() override; - - private: - Profile* profile_; - - // GlobalErrorService owns us, on which AutomaticProfileResetter depends, so - // during shutdown, it may get destroyed before we are. - // Note: the AutomaticProfileResetter expects call-backs from us to always be - // synchronous, so that there will be no call-backs once we are destroyed. - base::WeakPtr<AutomaticProfileResetter> automatic_profile_resetter_; - - // Used to measure the delay before the bubble actually gets shown. - base::ElapsedTimer timer_; - - // Whether or not we have already shown the bubble. - bool has_shown_bubble_view_; - - // The reset bubble, if we're currently showing one. - GlobalErrorBubbleViewBase* bubble_view_; - - DISALLOW_COPY_AND_ASSIGN(ProfileResetGlobalError); -}; - -#endif // CHROME_BROWSER_PROFILE_RESETTER_PROFILE_RESET_GLOBAL_ERROR_H_
diff --git a/chrome/browser/profile_resetter/resettable_settings_snapshot.cc b/chrome/browser/profile_resetter/resettable_settings_snapshot.cc index 42c6f59..504876b 100644 --- a/chrome/browser/profile_resetter/resettable_settings_snapshot.cc +++ b/chrome/browser/profile_resetter/resettable_settings_snapshot.cc
@@ -31,8 +31,7 @@ namespace { -// Feedback bucket labels. -const char kProfileResetPromptBucket[] = "SamplingOfSettingsResetPrompt"; +// Feedback bucket label. const char kProfileResetWebUIBucket[] = "ProfileResetReport"; // Dictionary keys for feedback report. @@ -222,19 +221,9 @@ } void SendSettingsFeedback(const std::string& report, - Profile* profile, - SnapshotCaller caller) { + Profile* profile) { scoped_refptr<FeedbackData> feedback_data = new FeedbackData(); - std::string bucket; - switch (caller) { - case PROFILE_RESET_WEBUI: - bucket = kProfileResetWebUIBucket; - break; - case PROFILE_RESET_PROMPT: - bucket = kProfileResetPromptBucket; - break; - } - feedback_data->set_category_tag(bucket); + feedback_data->set_category_tag(kProfileResetWebUIBucket); feedback_data->set_description(report); feedback_data->set_image(make_scoped_ptr(new std::string));
diff --git a/chrome/browser/profile_resetter/resettable_settings_snapshot.h b/chrome/browser/profile_resetter/resettable_settings_snapshot.h index 2022e97..e602cef 100644 --- a/chrome/browser/profile_resetter/resettable_settings_snapshot.h +++ b/chrome/browser/profile_resetter/resettable_settings_snapshot.h
@@ -115,12 +115,6 @@ DISALLOW_COPY_AND_ASSIGN(ResettableSettingsSnapshot); }; -// The caller of ResettableSettingsSnapshot. -enum SnapshotCaller { - PROFILE_RESET_WEBUI = 0, - PROFILE_RESET_PROMPT, -}; - // Serializes specified |snapshot| members to JSON format. |field_mask| is a bit // mask of ResettableSettingsSnapshot::Field values. std::string SerializeSettingsReport(const ResettableSettingsSnapshot& snapshot, @@ -129,8 +123,7 @@ // Sends |report| as a feedback. |report| is supposed to be result of // SerializeSettingsReport(). void SendSettingsFeedback(const std::string& report, - Profile* profile, - SnapshotCaller caller); + Profile* profile); // Returns list of key/value pairs for all available reported information // from the |profile| and some additional fields.
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc index d5f51d649..bb7784e 100644 --- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc +++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -123,7 +123,6 @@ #endif #if !defined(OS_ANDROID) -#include "chrome/browser/profile_resetter/automatic_profile_resetter_factory.h" #include "chrome/browser/ui/global_error/global_error_service_factory.h" #include "chrome/browser/usb/usb_chooser_context_factory.h" #endif @@ -184,9 +183,6 @@ AccountTrackerServiceFactory::GetInstance(); AccountFetcherServiceFactory::GetInstance(); autofill::PersonalDataManagerFactory::GetInstance(); -#if !defined(OS_ANDROID) - AutomaticProfileResetterFactory::GetInstance(); -#endif #if defined(ENABLE_BACKGROUND) BackgroundContentsServiceFactory::GetInstance(); #endif
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc index 3e331d5..83fe26b7 100644 --- a/chrome/browser/profiles/profile_io_data.cc +++ b/chrome/browser/profiles/profile_io_data.cc
@@ -128,7 +128,6 @@ #include "chrome/browser/chromeos/net/cert_verify_proc_chromeos.h" #include "chrome/browser/chromeos/net/client_cert_filter_chromeos.h" #include "chrome/browser/chromeos/net/client_cert_store_chromeos.h" -#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/policy/policy_cert_service.h" #include "chrome/browser/chromeos/policy/policy_cert_service_factory.h" #include "chrome/browser/chromeos/policy/policy_cert_verifier.h" @@ -449,14 +448,9 @@ user->username_hash(), profile->GetPath())); - // Use the device-wide system key slot only if the user is of the same - // domain as the device is registered to. - policy::BrowserPolicyConnectorChromeOS* connector = - g_browser_process->platform_part() - ->browser_policy_connector_chromeos(); - params->use_system_key_slot = - connector->GetUserAffiliation(user->email()) == - policy::USER_AFFILIATION_MANAGED; + // Use the device-wide system key slot only if the user is affiliated on + // the device. + params->use_system_key_slot = user->is_affiliated(); } }
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc index 1e571a2a..0e2dfe16 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -1547,12 +1547,6 @@ case IDC_SPELLPANEL_TOGGLE: case IDC_CONTENT_CONTEXT_LANGUAGE_SETTINGS: return true; - case IDC_CONTENT_CONTEXT_VIEWFRAMEINFO: - // Disabled if no browser is associated (e.g. desktop notifications). - if (chrome::FindBrowserWithWebContents(source_web_contents_) == NULL) - return false; - return true; - case IDC_CHECK_SPELLING_WHILE_TYPING: return prefs->GetBoolean(prefs::kEnableContinuousSpellcheck); @@ -2004,20 +1998,6 @@ params_.frame_page_state); break; - case IDC_CONTENT_CONTEXT_VIEWFRAMEINFO: { - Browser* browser = chrome::FindBrowserWithWebContents( - source_web_contents_); - SecurityStateModel::SecurityInfo security_info; - SecurityStateModel::SecurityInfoForRequest( - params_.frame_url, params_.security_info, - Profile::FromBrowserContext( - source_web_contents_->GetBrowserContext()), - &security_info); - chrome::ShowWebsiteSettings(browser, source_web_contents_, - params_.frame_url, security_info); - break; - } - case IDC_CONTENT_CONTEXT_UNDO: source_web_contents_->Undo(); break;
diff --git a/chrome/browser/resources/chromeos/chromevox/common/msgs.js b/chrome/browser/resources/chromeos/chromevox/common/msgs.js index 8a9628e..1492db7 100644 --- a/chrome/browser/resources/chromeos/chromevox/common/msgs.js +++ b/chrome/browser/resources/chromeos/chromevox/common/msgs.js
@@ -50,7 +50,7 @@ Msgs.getMsg = function(messageId, opt_subs) { var message = Msgs.Untranslated[messageId.toUpperCase()]; if (message !== undefined) - return message; + return Msgs.applySubstitutions_(message, opt_subs); message = chrome.i18n.getMessage( Msgs.NAMESPACE_ + messageId, opt_subs); if (message == undefined || message == '') { @@ -111,6 +111,23 @@ }; /** + * Applies substitions of the form $N, where N is a number from 1 to 9, to a + * string. The numbers are one-based indices into |opt_subs|. + * @param {string} message + * @param {Array<string>=} opt_subs + * @return {string} + * @private + */ +Msgs.applySubstitutions_ = function(message, opt_subs) { + if (opt_subs) { + for (var i = 0; i < opt_subs.length; i++) { + message = message.replace('$' + (i + 1), opt_subs[i]); + } + } + return message; +}; + +/** * Strings that are displayed in the user interface but don't need * be translated. * @type {Object<string>} @@ -156,6 +173,14 @@ ARIA_SELECTED_FALSE_BRL: '( )', /** Brailled after a menu if it has a submenu. */ HAS_SUBMENU_BRL: '->', - /** Brailled to describe a <time> tag. */ + /** Brailled to describe a <time> tag. */ TAG_TIME_BRL: ' ', + /** Spoken when describing an ARIA value. */ + ARIA_VALUE_NOW: '$1', + /** Brailled when describing an ARIA value. */ + ARIA_VALUE_NOW_BRL: '$1', + /** Spoken when describing an ARIA value text. */ + ARIA_VALUE_TEXT: '$1', + /** Brailled when describing an ARIA value text. */ + ARIA_VALUE_TEXT_BRL: '$1', };
diff --git a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd index d1b911c7..878212f 100644 --- a/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd +++ b/chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd
@@ -944,18 +944,6 @@ <message desc='Brailled when describing an ARIA value maximum. For example "Distance, in meters: 6 min:2 max:10".' name="IDS_CHROMEVOX_ARIA_VALUE_MAX_BRL"> max:<ph name="x">$1</ph> </message> - <message desc='Spoken when describing an ARIA value. For example "Distance, in meters textbox 6, min 2, max 10".' name="IDS_CHROMEVOX_ARIA_VALUE_NOW"> - <ph name="x">$1</ph> - </message> - <message desc='Brailled when describing an ARIA value. For example "Distance, in meters: 6 min:2 max:10".' name="IDS_CHROMEVOX_ARIA_VALUE_NOW_BRL"> - <ph name="x">$1</ph> - </message> - <message desc='Spoken when describing an ARIA value text. For example "Distance, short distance set"' name="IDS_CHROMEVOX_ARIA_VALUE_TEXT"> - <ph name="x">$1</ph> - </message> - <message desc='Brailled when describing an ARIA value text. For example "Distance, short distance set"' name="IDS_CHROMEVOX_ARIA_VALUE_TEXT_BRL"> - <ph name="x">$1</ph> - </message> <message desc="Describes an element with the ARIA role alert." name="IDS_CHROMEVOX_ROLE_ALERT"> Alert </message>
diff --git a/chrome/browser/resources/chromeos/chromevox/testing/test_msgs.js b/chrome/browser/resources/chromeos/chromevox/testing/test_msgs.js index 969dd04..beec2a6 100644 --- a/chrome/browser/resources/chromeos/chromevox/testing/test_msgs.js +++ b/chrome/browser/resources/chromeos/chromevox/testing/test_msgs.js
@@ -18,6 +18,12 @@ TestMsgs = function() {}; /** + * @type {function(string, Array<string>=): string} + * @private + */ +TestMsgs.applySubstitutions_ = Msgs.applySubstitutions_; + +/** * @type {Object<string>} */ TestMsgs.Untranslated = Msgs.Untranslated; @@ -38,30 +44,23 @@ if (!messageId) { throw Error('Message id required'); } - var message = TestMsgs.Untranslated[messageId.toUpperCase()]; - if (message !== undefined) - return message; - message = cvox.TestMessages[('chromevox_' + messageId).toUpperCase()]; - if (message === undefined) { - throw Error('missing-msg: ' + messageId); - } - - var messageString = message.message; - var placeholders = message.placeholders; - if (placeholders) { - for (name in placeholders) { - messageString = messageString.replace( - '$' + name + '$', - placeholders[name].content); + var messageString = TestMsgs.Untranslated[messageId.toUpperCase()]; + if (messageString === undefined) { + var messageObj = cvox.TestMessages[( + 'chromevox_' + messageId).toUpperCase()]; + if (messageObj === undefined) + throw Error('missing-msg: ' + messageId); + var messageString = messageObj.message; + var placeholders = messageObj.placeholders; + if (placeholders) { + for (name in placeholders) { + messageString = messageString.replace( + '$' + name + '$', + placeholders[name].content); + } } } - if (opt_subs) { - // Unshift a null to make opt_subs and message.placeholders line up. - for (var i = 0; i < opt_subs.length; i++) { - messageString = messageString.replace('$' + (i + 1), opt_subs[i]); - } - } - return messageString; + return Msgs.applySubstitutions_(messageString, opt_subs); }; /**
diff --git a/chrome/browser/resources/options/settings_banner.css b/chrome/browser/resources/options/automatic_settings_reset_banner.css similarity index 89% rename from chrome/browser/resources/options/settings_banner.css rename to chrome/browser/resources/options/automatic_settings_reset_banner.css index c4290ef..a62408f3 100644 --- a/chrome/browser/resources/options/settings_banner.css +++ b/chrome/browser/resources/options/automatic_settings_reset_banner.css
@@ -2,9 +2,6 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ -/* These styles are used by both reset_profile_settings_banner.html and - * automatic_settings_reset_banner.html. */ - .settings-banner { background-color: #f5f5f5; border-color: #c8c8c8; @@ -43,8 +40,8 @@ } .settings-banner .content-area { - -webkit-box-align: center; - display: -webkit-box; + align-items: center; + display: flex; padding: 17px; } @@ -57,8 +54,8 @@ } .settings-banner .content-area .text { - -webkit-box-flex: 1.0; -webkit-margin-start: 18px; + flex: 1.0; } .settings-banner .content-area .text p {
diff --git a/chrome/browser/resources/options/automatic_settings_reset_banner.js b/chrome/browser/resources/options/automatic_settings_reset_banner.js index e0747c58..bdd9090 100644 --- a/chrome/browser/resources/options/automatic_settings_reset_banner.js +++ b/chrome/browser/resources/options/automatic_settings_reset_banner.js
@@ -5,7 +5,6 @@ // Note: the native-side handler for this is AutomaticSettingsResetHandler. cr.define('options', function() { - /** @const */ var SettingsBannerBase = options.SettingsBannerBase; /** @const */ var PageManager = cr.ui.pageManager.PageManager; /** @@ -19,7 +18,38 @@ cr.addSingletonGetter(AutomaticSettingsResetBanner); AutomaticSettingsResetBanner.prototype = { - __proto__: SettingsBannerBase.prototype, + /** + * Whether or not the banner has already been dismissed. + * + * This is needed because of the surprising ordering of asynchronous + * JS<->native calls when the settings page is opened with specifying a + * given sub-page, e.g. chrome://settings/AutomaticSettingsReset. + * + * In such a case, AutomaticSettingsResetOverlay's didShowPage(), which + * calls our dismiss() method, would be called before the native Handlers' + * InitalizePage() methods have an effect in the JS, which includes calling + * our show() method. This would mean that the banner would be first + * dismissed, then shown. We want to prevent this. + * + * @type {boolean} + * @private + */ + hadBeenDismissed_: false, + + /** + * Metric name to send when a show event occurs. + */ + showMetricName_: '', + + /** + * Name of the native callback invoked when the banner is dismised. + */ + dismissNativeCallbackName_: '', + + /** + * DOM element whose visibility is set when setVisibility_ is called. + */ + setVisibilibyDomElement_: null, /** * Initializes the banner's event handlers. @@ -31,12 +61,12 @@ * private implementations using cr.makePublic(). */ initialize: function() { - this.showMetricName = 'AutomaticSettingsReset_WebUIBanner_BannerShown'; + this.showMetricName_ = 'AutomaticSettingsReset_WebUIBanner_BannerShown'; - this.dismissNativeCallbackName = + this.dismissNativeCallbackName_ = 'onDismissedAutomaticSettingsResetBanner'; - this.visibilityDomElement = $('automatic-settings-reset-banner'); + this.setVisibilibyDomElement_ = $('automatic-settings-reset-banner'); $('automatic-settings-reset-banner-close').onclick = function(event) { chrome.send('metricsHandler:recordAction', @@ -54,18 +84,45 @@ PageManager.showPageByName('resetProfileSettings'); }; }, + + /** + * Sets whether or not the reset profile settings banner shall be visible. + * @param {boolean} show Whether or not to show the banner. + * @protected + */ + setVisibility: function(show) { + this.setVisibilibyDomElement_.hidden = !show; + }, + + /** + * Called by the native code to show the banner if needed. + * @private + */ + show_: function() { + if (!this.hadBeenDismissed_) { + chrome.send('metricsHandler:recordAction', [this.showMetricName_]); + this.setVisibility(true); + } + }, + + /** + * Called when the banner should be closed as a result of something taking + * place on the WebUI page, i.e. when its close button is pressed, or when + * the confirmation dialog for the profile settings reset feature is opened. + * @private + */ + dismiss_: function() { + chrome.send(this.dismissNativeCallbackName_); + this.hadBeenDismissed_ = true; + this.setVisibility(false); + }, }; - // Forward public APIs to protected implementations. - [ + // Forward public APIs to private implementations. + cr.makePublic(AutomaticSettingsResetBanner, [ 'show', 'dismiss', - ].forEach(function(name) { - AutomaticSettingsResetBanner[name] = function() { - var instance = AutomaticSettingsResetBanner.getInstance(); - return instance[name].apply(instance, arguments); - }; - }); + ]); // Export return {
diff --git a/chrome/browser/resources/options/browser_options.html b/chrome/browser/resources/options/browser_options.html index 3dd0fdd..9733e77 100644 --- a/chrome/browser/resources/options/browser_options.html +++ b/chrome/browser/resources/options/browser_options.html
@@ -2,7 +2,6 @@ <header> <h1 i18n-content="settingsTitle"></h1> </header> - <include src="reset_profile_settings_banner.html"> <include src="automatic_settings_reset_banner.html"> <if expr="chromeos"> <link rel="import" href="chrome://resources/cr_elements/network/cr_network_icon.html">
diff --git a/chrome/browser/resources/options/options.html b/chrome/browser/resources/options/options.html index 14196b3..e6e1ee2b 100644 --- a/chrome/browser/resources/options/options.html +++ b/chrome/browser/resources/options/options.html
@@ -17,6 +17,7 @@ <link rel="stylesheet" href="alert_overlay.css"> <link rel="stylesheet" href="autofill_edit_overlay.css"> <link rel="stylesheet" href="autofill_options.css"> +<link rel="stylesheet" href="automatic_settings_reset_banner.css"> <link rel="stylesheet" href="browser_options.css"> <if expr="chromeos"> <link rel="stylesheet" href="chromeos/browser_options.css"> @@ -41,7 +42,6 @@ <link rel="stylesheet" href="reset_profile_settings_overlay.css"> <link rel="stylesheet" href="search_engine_manager.css"> <link rel="stylesheet" href="search_page.css"> -<link rel="stylesheet" href="settings_banner.css"> <link rel="stylesheet" href="spelling_confirm_overlay.css"> <link rel="stylesheet" href="startup_overlay.css"> <link rel="stylesheet" href="subpages_tab_controls.css">
diff --git a/chrome/browser/resources/options/options.js b/chrome/browser/resources/options/options.js index ab78887..d331855 100644 --- a/chrome/browser/resources/options/options.js +++ b/chrome/browser/resources/options/options.js
@@ -35,7 +35,6 @@ var PasswordManager = options.PasswordManager; var Preferences = options.Preferences; var PreferredNetworks = options.PreferredNetworks; -var ResetProfileSettingsBanner = options.ResetProfileSettingsBanner; var ResetProfileSettingsOverlay = options.ResetProfileSettingsOverlay; var SearchEngineManager = options.SearchEngineManager; var SearchPage = options.SearchPage; @@ -240,7 +239,6 @@ OptionsFocusManager.getInstance().initialize(); Preferences.getInstance().initialize(); - ResetProfileSettingsBanner.getInstance().initialize(); AutomaticSettingsResetBanner.getInstance().initialize(); OptionsPage.initialize(); PageManager.initialize(BrowserOptions.getInstance());
diff --git a/chrome/browser/resources/options/options_bundle.js b/chrome/browser/resources/options/options_bundle.js index 27502bf..8a72e0d 100644 --- a/chrome/browser/resources/options/options_bundle.js +++ b/chrome/browser/resources/options/options_bundle.js
@@ -14,7 +14,6 @@ <include src="options_page.js"> <include src="pref_ui.js"> <include src="settings_dialog.js"> -<include src="settings_banner.js"> <if expr="chromeos"> <include src="../chromeos/user_images_grid.js"> <include src="../help/channel_change_page.js"> @@ -104,7 +103,6 @@ <include src="password_manager.js"> <include src="password_manager_list.js"> <include src="profiles_icon_grid.js"> -<include src="reset_profile_settings_banner.js"> <include src="reset_profile_settings_overlay.js"> <include src="search_engine_manager.js"> <include src="search_engine_manager_engine_list.js">
diff --git a/chrome/browser/resources/options/reset_profile_settings_banner.html b/chrome/browser/resources/options/reset_profile_settings_banner.html deleted file mode 100644 index fd95c3c..0000000 --- a/chrome/browser/resources/options/reset_profile_settings_banner.html +++ /dev/null
@@ -1,18 +0,0 @@ -<div id="reset-profile-settings-banner" class="settings-banner" hidden> - <div id="reset-profile-settings-banner-close" class="close-button"></div> - <div class="content-area"> - <div class="badge"></div> - <div class="text"> - <p> - <span i18n-values=".innerHTML:resetProfileSettingsBannerText"> - </span> - <a class="nowrap" i18n-values="href:resetProfileSettingsLearnMoreUrl" - i18n-content="learnMore" target="_blank"></a> - </p> - </div> - <div class="button-area"> - <button id="reset-profile-settings-banner-activate" - i18n-content="resetProfileSettings"></button> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/reset_profile_settings_banner.js b/chrome/browser/resources/options/reset_profile_settings_banner.js deleted file mode 100644 index 4785113..0000000 --- a/chrome/browser/resources/options/reset_profile_settings_banner.js +++ /dev/null
@@ -1,66 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Note: the native-side handler for this is ResetProfileSettingsHandler. - -cr.define('options', function() { - /** @const */ var PageManager = cr.ui.pageManager.PageManager; - /** @const */ var SettingsBannerBase = options.SettingsBannerBase; - - /** - * ResetProfileSettingsBanner class - * Provides encapsulated handling of the Reset Profile Settings banner. - * @constructor - * @extends {options.SettingsBannerBase} - */ - function ResetProfileSettingsBanner() {} - - cr.addSingletonGetter(ResetProfileSettingsBanner); - - ResetProfileSettingsBanner.prototype = { - __proto__: SettingsBannerBase.prototype, - - /** - * Initializes the banner's event handlers. - * @suppress {checkTypes} - * TODO(vitalyp): remove the suppression. See the explanation in - * chrome/browser/resources/options/automatic_settings_reset_banner.js. - */ - initialize: function() { - this.showMetricName = 'AutomaticReset_WebUIBanner_BannerShown'; - - this.dismissNativeCallbackName = - 'onDismissedResetProfileSettingsBanner'; - - this.visibilityDomElement = $('reset-profile-settings-banner'); - - $('reset-profile-settings-banner-close').onclick = function(event) { - chrome.send('metricsHandler:recordAction', - ['AutomaticReset_WebUIBanner_ManuallyClosed']); - ResetProfileSettingsBanner.dismiss(); - }; - $('reset-profile-settings-banner-activate').onclick = function(event) { - chrome.send('metricsHandler:recordAction', - ['AutomaticReset_WebUIBanner_ResetClicked']); - PageManager.showPageByName('resetProfileSettings'); - }; - }, - }; - - // Forward public APIs to protected implementations. - [ - 'show', - 'dismiss', - ].forEach(function(name) { - ResetProfileSettingsBanner[name] = function() { - var instance = ResetProfileSettingsBanner.getInstance(); - return instance[name].apply(instance, arguments); - }; - }); - - // Export - return { - ResetProfileSettingsBanner: ResetProfileSettingsBanner - }; -});
diff --git a/chrome/browser/resources/options/reset_profile_settings_overlay.js b/chrome/browser/resources/options/reset_profile_settings_overlay.js index 2c247dc..7da9e29 100644 --- a/chrome/browser/resources/options/reset_profile_settings_overlay.js +++ b/chrome/browser/resources/options/reset_profile_settings_overlay.js
@@ -6,7 +6,6 @@ var Page = cr.ui.pageManager.Page; var AutomaticSettingsResetBanner = options.AutomaticSettingsResetBanner; - var ResetProfileSettingsBanner = options.ResetProfileSettingsBanner; /** * ResetProfileSettingsOverlay class @@ -57,7 +56,6 @@ $('reset-profile-settings-explanation').textContent = loadTimeData.getString('resetProfileSettingsExplanation'); - ResetProfileSettingsBanner.dismiss(); chrome.send('onShowResetProfileDialog'); },
diff --git a/chrome/browser/resources/options/settings_banner.js b/chrome/browser/resources/options/settings_banner.js deleted file mode 100644 index 666aaf2..0000000 --- a/chrome/browser/resources/options/settings_banner.js +++ /dev/null
@@ -1,89 +0,0 @@ -// Copyright 2014 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. - -cr.define('options', function() { - - /** - * Base class for banners that appear at the top of the settings page. - * @constructor - */ - function SettingsBannerBase() {} - - cr.addSingletonGetter(SettingsBannerBase); - - SettingsBannerBase.prototype = { - /** - * Whether or not the banner has already been dismissed. - * - * This is needed because of the surprising ordering of asynchronous - * JS<->native calls when the settings page is opened with specifying a - * given sub-page, e.g. chrome://settings/AutomaticSettingsReset. - * - * In such a case, AutomaticSettingsResetOverlay's didShowPage(), which - * calls our dismiss() method, would be called before the native Handlers' - * InitalizePage() methods have an effect in the JS, which includes calling - * our show() method. This would mean that the banner would be first - * dismissed, then shown. We want to prevent this. - * - * @type {boolean} - * @private - */ - hadBeenDismissed_: false, - - /** - * Metric name to send when a show event occurs. - * @protected - */ - showMetricName: '', - - /** - * Name of the native callback invoked when the banner is dismised. - * @protected - */ - dismissNativeCallbackName: '', - - /** - * DOM element whose visibility is set when setVisibility_ is called. - * @protected - */ - visibilityDomElement: null, - - /** - * Called by the native code to show the banner if needed. - * @protected - */ - show: function() { - if (!this.hadBeenDismissed_) { - chrome.send('metricsHandler:recordAction', [this.showMetricName]); - this.setVisibility_(true); - } - }, - - /** - * Called when the banner should be closed as a result of something taking - * place on the WebUI page, i.e. when its close button is pressed, or when - * the confirmation dialog for the profile settings reset feature is opened. - * @protected - */ - dismiss: function() { - chrome.send(this.dismissNativeCallbackName); - this.hadBeenDismissed_ = true; - this.setVisibility_(false); - }, - - /** - * Sets whether or not the reset profile settings banner shall be visible. - * @param {boolean} show Whether or not to show the banner. - * @private - */ - setVisibility_: function(show) { - this.visibilityDomElement.hidden = !show; - }, - }; - - // Export - return { - SettingsBannerBase: SettingsBannerBase - }; -});
diff --git a/chrome/browser/resources/options/triggered_reset_profile_settings_overlay.js b/chrome/browser/resources/options/triggered_reset_profile_settings_overlay.js index 9ed58cb..35cd029 100644 --- a/chrome/browser/resources/options/triggered_reset_profile_settings_overlay.js +++ b/chrome/browser/resources/options/triggered_reset_profile_settings_overlay.js
@@ -6,7 +6,6 @@ var Page = cr.ui.pageManager.Page; var ResetProfileSettingsOverlay = options.ResetProfileSettingsOverlay; - var ResetProfileSettingsBanner = options.ResetProfileSettingsBanner; /** * TriggeredResetProfileSettingsOverlay class @@ -37,7 +36,6 @@ loadTimeData.getString('triggeredResetProfileSettingsOverlay'); $('reset-profile-settings-explanation').textContent = loadTimeData.getString('triggeredResetProfileSettingsExplanation'); - ResetProfileSettingsBanner.dismiss(); chrome.send('onShowResetProfileDialog'); }, };
diff --git a/chrome/browser/safe_browsing/download_feedback_service.cc b/chrome/browser/safe_browsing/download_feedback_service.cc index 379f0ad..e5cabd5d 100644 --- a/chrome/browser/safe_browsing/download_feedback_service.cc +++ b/chrome/browser/safe_browsing/download_feedback_service.cc
@@ -178,13 +178,13 @@ const std::string& ping_response, const base::FilePath& path) { DCHECK(CalledOnValidThread()); - DownloadFeedback* feedback = + scoped_ptr<DownloadFeedback> feedback( DownloadFeedback::Create(request_context_getter_.get(), file_task_runner_.get(), path, ping_request, - ping_response); - active_feedback_.push_back(feedback); + ping_response)); + active_feedback_.push_back(feedback.Pass()); UMA_HISTOGRAM_COUNTS_100("SBDownloadFeedback.ActiveFeedbacks", active_feedback_.size());
diff --git a/chrome/browser/safe_browsing/download_feedback_service.h b/chrome/browser/safe_browsing/download_feedback_service.h index 65a7f1f..d1ef35c 100644 --- a/chrome/browser/safe_browsing/download_feedback_service.h +++ b/chrome/browser/safe_browsing/download_feedback_service.h
@@ -6,10 +6,11 @@ #define CHROME_BROWSER_SAFE_BROWSING_DOWNLOAD_FEEDBACK_SERVICE_H_ #include <string> +#include <vector> #include "base/basictypes.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_vector.h" +#include "base/memory/scoped_ptr.h" #include "base/threading/non_thread_safe.h" #include "chrome/browser/safe_browsing/download_protection_service.h" #include "content/public/browser/download_danger_type.h" @@ -85,7 +86,7 @@ // Currently active & pending uploads. The first item is active, remaining // items are pending. - ScopedVector<DownloadFeedback> active_feedback_; + std::vector<scoped_ptr<DownloadFeedback>> active_feedback_; base::WeakPtrFactory<DownloadFeedbackService> weak_ptr_factory_;
diff --git a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc index 14bddec..5f9ebab9 100644 --- a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc +++ b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc
@@ -124,10 +124,10 @@ // The incidents collected for this profile pending creation and/or upload. // Will contain null values for pruned incidents. - ScopedVector<Incident> incidents; + std::vector<scoped_ptr<Incident>> incidents; // The incidents data of which should be cleared. - ScopedVector<Incident> incidents_to_clear; + std::vector<scoped_ptr<Incident>> incidents_to_clear; // State storage for this profile; null until PROFILE_ADDED notification is // received. @@ -265,7 +265,7 @@ } IncidentReportingService::ProfileContext::~ProfileContext() { - for (Incident* incident : incidents) { + for (const auto& incident : incidents) { if (incident) LogIncidentDataType(DISCARDED, *incident); } @@ -459,7 +459,7 @@ // Drop all incidents associated with this profile that were received prior to // its addition if incident reporting is not enabled for it. if (!context->incidents.empty() && !enabled_for_profile) { - for (Incident* incident : context->incidents) + for (const auto& incident : context->incidents) LogIncidentDataType(DROPPED, *incident); context->incidents.clear(); } @@ -547,7 +547,7 @@ // TODO(grt): Persist incidents for upload on future profile load. // Remove the association with this profile context from all pending uploads. - for (UploadContext* upload : uploads_) + for (const auto& upload : uploads_) upload->profiles_to_state.erase(context.get()); // Forget about this profile. Incidents not yet sent for upload are lost. @@ -606,7 +606,7 @@ } // Take ownership of the incident. - context->incidents.push_back(incident.release()); + context->incidents.push_back(incident.Pass()); // Remember when the first incident for this report arrived. if (first_incident_time_.is_null()) @@ -628,7 +628,7 @@ void IncidentReportingService::ClearIncident(Profile* profile, scoped_ptr<Incident> incident) { ProfileContext* context = GetOrCreateProfileContext(profile); - context->incidents_to_clear.push_back(incident.release()); + context->incidents_to_clear.push_back(incident.Pass()); // Begin processing to handle cleared incidents following collation. BeginReportProcessing(); } @@ -858,17 +858,15 @@ if (eligible_profile) { ProfileContext* eligible_context = GetProfileContext(eligible_profile); // Move the incidents to the target context. - eligible_context->incidents.insert(eligible_context->incidents.end(), - null_context->incidents.begin(), - null_context->incidents.end()); - null_context->incidents.weak_clear(); - eligible_context->incidents_to_clear.insert( - eligible_context->incidents_to_clear.end(), - null_context->incidents_to_clear.begin(), - null_context->incidents_to_clear.end()); - null_context->incidents_to_clear.weak_clear(); + for (auto& incident : null_context->incidents) { + eligible_context->incidents.push_back(incident.Pass()); + } + null_context->incidents.clear(); + for (auto& incident : null_context->incidents_to_clear) + eligible_context->incidents_to_clear.push_back(incident.Pass()); + null_context->incidents_to_clear.clear(); } else { - for (Incident* incident : null_context->incidents) + for (const auto& incident : null_context->incidents) LogIncidentDataType(DROPPED, *incident); null_context->incidents.clear(); } @@ -884,7 +882,7 @@ } ProfileContext* context = profile_and_context.second; StateStore::Transaction transaction(context->state_store.get()); - for (Incident* incident : context->incidents_to_clear) + for (const auto& incident : context->incidents_to_clear) transaction.Clear(incident->GetType(), incident->GetKey()); context->incidents_to_clear.clear(); } @@ -909,7 +907,7 @@ if (context->incidents.empty()) continue; if (!IsEnabledForProfile(profile_and_context.first)) { - for (Incident* incident : context->incidents) + for (const auto& incident : context->incidents) LogIncidentDataType(DROPPED, *incident); context->incidents.clear(); continue; @@ -917,7 +915,7 @@ StateStore::Transaction transaction(context->state_store.get()); std::vector<PersistentIncidentState> states; // Prep persistent data and prune any incidents already sent. - for (Incident* incident : context->incidents) { + for (const auto& incident : context->incidents) { const PersistentIncidentState state = ComputeIncidentState(*incident); if (context->state_store->HasBeenReported(state.type, state.key, state.digest)) { @@ -965,7 +963,7 @@ // No database manager during testing. Take ownership of the context and // continue processing. UploadContext* temp_context = context.get(); - uploads_.push_back(context.release()); + uploads_.push_back(context.Pass()); IncidentReportingService::OnKillSwitchResult(temp_context, false); } else { if (content::BrowserThread::PostTaskAndReplyWithResult( @@ -976,7 +974,7 @@ base::Bind(&IncidentReportingService::OnKillSwitchResult, weak_ptr_factory_.GetWeakPtr(), context.get()))) { - uploads_.push_back(context.release()); + uploads_.push_back(context.Pass()); } // else should not happen. Let the context be deleted automatically. } } @@ -1035,12 +1033,13 @@ // The upload is no longer outstanding, so take ownership of the context (from // the collection of outstanding uploads) in this scope. - ScopedVector<UploadContext>::iterator it( - std::find(uploads_.begin(), uploads_.end(), context)); + auto it = std::find_if(uploads_.begin(), uploads_.end(), + [context] (const scoped_ptr<UploadContext>& value) { + return value.get() == context; + }); DCHECK(it != uploads_.end()); - scoped_ptr<UploadContext> upload(context); // == *it - *it = uploads_.back(); - uploads_.weak_erase(uploads_.end() - 1); + scoped_ptr<UploadContext> upload(it->Pass()); + uploads_.erase(it); if (result == IncidentReportUploader::UPLOAD_SUCCESS) HandleResponse(*upload);
diff --git a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h index f92c8d8..14ac749 100644 --- a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h +++ b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h
@@ -8,12 +8,12 @@ #include <stdint.h> #include <map> +#include <vector> #include "base/compiler_specific.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" -#include "base/memory/scoped_vector.h" #include "base/memory/weak_ptr.h" #include "base/threading/thread_checker.h" #include "base/time/time.h" @@ -336,7 +336,7 @@ DownloadMetadataManager download_metadata_manager_; // The collection of uploads in progress. - ScopedVector<UploadContext> uploads_; + std::vector<scoped_ptr<UploadContext>> uploads_; // An object that asynchronously searches for the most recent binary download. // Non-NULL while such a search is outstanding.
diff --git a/chrome/browser/safe_browsing/incident_reporting/mock_incident_receiver.h b/chrome/browser/safe_browsing/incident_reporting/mock_incident_receiver.h index fb54790..36bebe7 100644 --- a/chrome/browser/safe_browsing/incident_reporting/mock_incident_receiver.h +++ b/chrome/browser/safe_browsing/incident_reporting/mock_incident_receiver.h
@@ -42,7 +42,7 @@ // An action that passes ownership of the incident in |arg0| to the vector in // |incidents|. ACTION_P(TakeIncidentToVector, incidents) { - incidents->push_back(arg0->release()); + incidents->push_back(arg0->Pass()); } } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate_unittest.cc b/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate_unittest.cc index 0cf05dd..cd2ec7d2 100644 --- a/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate_unittest.cc +++ b/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate_unittest.cc
@@ -9,7 +9,7 @@ #include "base/bind.h" #include "base/compiler_specific.h" -#include "base/memory/scoped_vector.h" +#include "base/memory/scoped_ptr.h" #include "base/values.h" #include "chrome/browser/safe_browsing/incident_reporting/incident.h" #include "chrome/browser/safe_browsing/incident_reporting/mock_incident_receiver.h" @@ -27,7 +27,7 @@ // instance was provided with the expected data. class PreferenceValidationDelegateTest : public testing::Test { protected: - typedef ScopedVector<safe_browsing::Incident> IncidentVector; + typedef std::vector<scoped_ptr<safe_browsing::Incident>> IncidentVector; PreferenceValidationDelegateTest() : kPrefPath_("atomic.pref"),
diff --git a/chrome/browser/safe_browsing/local_database_manager.cc b/chrome/browser/safe_browsing/local_database_manager.cc index e44cc8b..0abdac70 100644 --- a/chrome/browser/safe_browsing/local_database_manager.cc +++ b/chrome/browser/safe_browsing/local_database_manager.cc
@@ -591,7 +591,7 @@ void LocalSafeBrowsingDatabaseManager::AddChunks( const std::string& list, - scoped_ptr<ScopedVector<SBChunkData> > chunks, + scoped_ptr<std::vector<scoped_ptr<SBChunkData>>> chunks, AddChunksCallback callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK(enabled_); @@ -973,11 +973,11 @@ void LocalSafeBrowsingDatabaseManager::AddDatabaseChunks( const std::string& list_name, - scoped_ptr<ScopedVector<SBChunkData> > chunks, + scoped_ptr<std::vector<scoped_ptr<SBChunkData>>> chunks, AddChunksCallback callback) { DCHECK(safe_browsing_task_runner_->RunsTasksOnCurrentThread()); if (chunks) - GetDatabase()->InsertChunks(list_name, chunks->get()); + GetDatabase()->InsertChunks(list_name, *chunks); BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, base::Bind(&LocalSafeBrowsingDatabaseManager::OnAddChunksComplete, this,
diff --git a/chrome/browser/safe_browsing/local_database_manager.h b/chrome/browser/safe_browsing/local_database_manager.h index d5cbe2e..3028346 100644 --- a/chrome/browser/safe_browsing/local_database_manager.h +++ b/chrome/browser/safe_browsing/local_database_manager.h
@@ -237,9 +237,10 @@ void DatabaseLoadComplete(); // Called on the database thread to add/remove chunks and host keys. - void AddDatabaseChunks(const std::string& list, - scoped_ptr<ScopedVector<SBChunkData> > chunks, - AddChunksCallback callback); + void AddDatabaseChunks( + const std::string& list, + scoped_ptr<std::vector<scoped_ptr<SBChunkData>>> chunks, + AddChunksCallback callback); void DeleteDatabaseChunks( scoped_ptr<std::vector<SBChunkDelete> > chunk_deletes); @@ -297,7 +298,7 @@ void UpdateFinished(bool success) override; void GetChunks(GetChunksCallback callback) override; void AddChunks(const std::string& list, - scoped_ptr<ScopedVector<SBChunkData>> chunks, + scoped_ptr<std::vector<scoped_ptr<SBChunkData>>> chunks, AddChunksCallback callback) override; void DeleteChunks( scoped_ptr<std::vector<SBChunkDelete>> chunk_deletes) override;
diff --git a/chrome/browser/safe_browsing/protocol_manager.cc b/chrome/browser/safe_browsing/protocol_manager.cc index ada474d..e746763 100644 --- a/chrome/browser/safe_browsing/protocol_manager.cc +++ b/chrome/browser/safe_browsing/protocol_manager.cc
@@ -6,7 +6,6 @@ #include "base/environment.h" #include "base/logging.h" -#include "base/memory/scoped_vector.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/sparse_histogram.h" #include "base/profiler/scoped_tracker.h" @@ -457,8 +456,8 @@ base::Time::Now() - chunk_request_start_); const ChunkUrl chunk_url = chunk_request_urls_.front(); - scoped_ptr<ScopedVector<SBChunkData>> chunks( - new ScopedVector<SBChunkData>); + scoped_ptr<std::vector<scoped_ptr<SBChunkData>>> chunks( + new std::vector<scoped_ptr<SBChunkData>>); UMA_HISTOGRAM_COUNTS("SB2.ChunkSize", length); update_size_ += length; if (!ParseChunk(data, length, chunks.get()))
diff --git a/chrome/browser/safe_browsing/protocol_manager.h b/chrome/browser/safe_browsing/protocol_manager.h index 71088ef..1d33c52 100644 --- a/chrome/browser/safe_browsing/protocol_manager.h +++ b/chrome/browser/safe_browsing/protocol_manager.h
@@ -432,9 +432,10 @@ // Add new chunks to the database. Invokes |callback| when complete, but must // call at a later time. - virtual void AddChunks(const std::string& list, - scoped_ptr<ScopedVector<SBChunkData> > chunks, - AddChunksCallback callback) = 0; + virtual void AddChunks( + const std::string& list, + scoped_ptr<std::vector<scoped_ptr<SBChunkData>>> chunks, + AddChunksCallback callback) = 0; // Delete chunks from the database. virtual void DeleteChunks(
diff --git a/chrome/browser/safe_browsing/protocol_manager_unittest.cc b/chrome/browser/safe_browsing/protocol_manager_unittest.cc index 10a366c..60bd467 100644 --- a/chrome/browser/safe_browsing/protocol_manager_unittest.cc +++ b/chrome/browser/safe_browsing/protocol_manager_unittest.cc
@@ -3,8 +3,9 @@ // found in the LICENSE file. // +#include <vector> + #include "base/memory/scoped_ptr.h" -#include "base/memory/scoped_vector.h" #include "base/strings/stringprintf.h" #include "base/test/test_simple_task_runner.h" #include "base/thread_task_runner_handle.h" @@ -328,11 +329,12 @@ // gmock does not work with scoped_ptr<> at this time. Add a local method to // mock, then call that from an override. Beware of object ownership when // making changes here. - MOCK_METHOD3(AddChunksRaw, void(const std::string& lists, - const ScopedVector<SBChunkData>& chunks, - AddChunksCallback)); + MOCK_METHOD3(AddChunksRaw, + void(const std::string& lists, + const std::vector<scoped_ptr<SBChunkData>>& chunks, + AddChunksCallback)); void AddChunks(const std::string& list, - scoped_ptr<ScopedVector<SBChunkData>> chunks, + scoped_ptr<std::vector<scoped_ptr<SBChunkData>>> chunks, AddChunksCallback callback) override { AddChunksRaw(list, *chunks, callback); } @@ -362,7 +364,7 @@ // SafeBrowsingProtocolManagerDelegate contract. void HandleAddChunks( const std::string& unused_list, - const ScopedVector<SBChunkData>& chunks, + const std::vector<scoped_ptr<SBChunkData>>& chunks, SafeBrowsingProtocolManagerDelegate::AddChunksCallback callback) { scoped_refptr<base::SingleThreadTaskRunner> task_runner( base::ThreadTaskRunnerHandle::Get());
diff --git a/chrome/browser/safe_browsing/protocol_parser.cc b/chrome/browser/safe_browsing/protocol_parser.cc index 1ba1e339..8f44267d 100644 --- a/chrome/browser/safe_browsing/protocol_parser.cc +++ b/chrome/browser/safe_browsing/protocol_parser.cc
@@ -350,7 +350,7 @@ // CHUNKDATA = Encoded ChunkData protocol message bool ParseChunk(const char* data, size_t length, - ScopedVector<SBChunkData>* chunks) { + std::vector<scoped_ptr<SBChunkData>>* chunks) { BufferReader reader(data, length); while (!reader.empty()) { @@ -366,7 +366,7 @@ if (!chunk->ParseFrom(reinterpret_cast<const unsigned char*>(p), l)) return false; - chunks->push_back(chunk.release()); + chunks->push_back(chunk.Pass()); } DCHECK(reader.empty());
diff --git a/chrome/browser/safe_browsing/protocol_parser.h b/chrome/browser/safe_browsing/protocol_parser.h index 4b7bf6c..9509734 100644 --- a/chrome/browser/safe_browsing/protocol_parser.h +++ b/chrome/browser/safe_browsing/protocol_parser.h
@@ -14,7 +14,6 @@ #include <vector> #include "base/basictypes.h" -#include "base/memory/scoped_vector.h" #include "chrome/browser/safe_browsing/safe_browsing_util.h" namespace base { @@ -44,7 +43,7 @@ // results should be discarded. bool ParseChunk(const char* chunk_data, size_t chunk_len, - ScopedVector<SBChunkData>* chunks); + std::vector<scoped_ptr<SBChunkData>>* chunks); // Parse body of "HTTP Response for Full-Length Hashes", returning the list of // full hashes. Returns |false| if the data could not be parsed correctly, in
diff --git a/chrome/browser/safe_browsing/protocol_parser_unittest.cc b/chrome/browser/safe_browsing/protocol_parser_unittest.cc index 5d4993f..3258650 100644 --- a/chrome/browser/safe_browsing/protocol_parser_unittest.cc +++ b/chrome/browser/safe_browsing/protocol_parser_unittest.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include <string> +#include <vector> #include "base/strings/stringprintf.h" #include "base/time/time.h" @@ -35,7 +36,7 @@ '9', '9', '9', '9', }; - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; EXPECT_TRUE(ParseChunk(kRawAddChunk, sizeof(kRawAddChunk), &chunks)); ASSERT_EQ(1U, chunks.size()); EXPECT_EQ(1, chunks[0]->ChunkNumber()); @@ -80,7 +81,7 @@ full_hash2.full_hash[i] = (i % 2) ? '3' : '2'; } - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; EXPECT_TRUE(ParseChunk(kRawAddChunk, sizeof(kRawAddChunk), &chunks)); ASSERT_EQ(1U, chunks.size()); EXPECT_EQ(1, chunks[0]->ChunkNumber()); @@ -120,7 +121,7 @@ 'g', 'g', 'g', 'g', }; - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; EXPECT_TRUE(ParseChunk(kRawAddChunk, sizeof(kRawAddChunk), &chunks)); ASSERT_EQ(2U, chunks.size()); @@ -160,7 +161,7 @@ '3', '3', '3', '3', }; - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; EXPECT_FALSE(ParseChunk(kRawAddChunk, sizeof(kRawAddChunk), &chunks)); } @@ -181,7 +182,7 @@ '0', '1', '0', '1', '0', '1', '0', '1', }; - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; EXPECT_FALSE(ParseChunk(kRawAddChunk, sizeof(kRawAddChunk), &chunks)); } @@ -198,7 +199,7 @@ '3', '3', '3', '3', }; - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; EXPECT_FALSE(ParseChunk(kRawAddChunk, sizeof(kRawAddChunk), &chunks)); } @@ -219,7 +220,7 @@ '\x07', '\x09', // varint 7, varint 9 }; - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; EXPECT_TRUE(ParseChunk(kRawSubChunk, sizeof(kRawSubChunk), &chunks)); ASSERT_EQ(1U, chunks.size()); EXPECT_EQ(3, chunks[0]->ChunkNumber()); @@ -268,7 +269,7 @@ full_hash2.full_hash[i] = i % 2 ? '3' : '2'; } - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; EXPECT_TRUE(ParseChunk(kRawSubChunk, sizeof(kRawSubChunk), &chunks)); ASSERT_EQ(1U, chunks.size()); EXPECT_EQ(2, chunks[0]->ChunkNumber()); @@ -551,7 +552,7 @@ '\x02', // chunk_number varint 2 }; - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; EXPECT_TRUE(ParseChunk(kEmptyAddChunk, sizeof(kEmptyAddChunk), &chunks)); ASSERT_EQ(1U, chunks.size()); EXPECT_EQ(2, chunks[0]->ChunkNumber()); @@ -622,7 +623,7 @@ '\x01', // enum ChunkType == SUB }; - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; EXPECT_TRUE(ParseChunk(kEmptySubChunk, sizeof(kEmptySubChunk), &chunks)); ASSERT_EQ(1U, chunks.size()); EXPECT_EQ(2, chunks[0]->ChunkNumber());
diff --git a/chrome/browser/safe_browsing/safe_browsing_database.cc b/chrome/browser/safe_browsing/safe_browsing_database.cc index c79d05d..8a8dddf 100644 --- a/chrome/browser/safe_browsing/safe_browsing_database.cc +++ b/chrome/browser/safe_browsing/safe_browsing_database.cc
@@ -1062,7 +1062,7 @@ void SafeBrowsingDatabaseNew::InsertChunks( const std::string& list_name, - const std::vector<SBChunkData*>& chunks) { + const std::vector<scoped_ptr<SBChunkData>>& chunks) { DCHECK(db_task_runner_->RunsTasksOnCurrentThread()); if (db_state_manager_.corruption_detected() || chunks.empty()) @@ -1082,11 +1082,11 @@ // TODO(shess): I believe that the list is always add or sub. Can this use // that productively? store->BeginChunk(); - for (size_t i = 0; i < chunks.size(); ++i) { - if (chunks[i]->IsAdd()) { - InsertAddChunk(store, list_id, *chunks[i]); - } else if (chunks[i]->IsSub()) { - InsertSubChunk(store, list_id, *chunks[i]); + for (const auto& chunk : chunks) { + if (chunk->IsAdd()) { + InsertAddChunk(store, list_id, *chunk); + } else if (chunk->IsSub()) { + InsertSubChunk(store, list_id, *chunk); } else { NOTREACHED(); }
diff --git a/chrome/browser/safe_browsing/safe_browsing_database.h b/chrome/browser/safe_browsing/safe_browsing_database.h index 5476256..17c7b8f 100644 --- a/chrome/browser/safe_browsing/safe_browsing_database.h +++ b/chrome/browser/safe_browsing/safe_browsing_database.h
@@ -169,8 +169,9 @@ // UpdateFinished(). If it returns false, the caller MUST NOT call // the other functions. virtual bool UpdateStarted(std::vector<SBListChunkRanges>* lists) = 0; - virtual void InsertChunks(const std::string& list_name, - const std::vector<SBChunkData*>& chunks) = 0; + virtual void InsertChunks( + const std::string& list_name, + const std::vector<scoped_ptr<SBChunkData>>& chunks) = 0; virtual void DeleteChunks( const std::vector<SBChunkDelete>& chunk_deletes) = 0; virtual void UpdateFinished(bool update_succeeded) = 0; @@ -333,8 +334,9 @@ std::vector<SBPrefix>* prefix_hits) override; bool ContainsMalwareIP(const std::string& ip_address) override; bool UpdateStarted(std::vector<SBListChunkRanges>* lists) override; - void InsertChunks(const std::string& list_name, - const std::vector<SBChunkData*>& chunks) override; + void InsertChunks( + const std::string& list_name, + const std::vector<scoped_ptr<SBChunkData>>& chunks) override; void DeleteChunks(const std::vector<SBChunkDelete>& chunk_deletes) override; void UpdateFinished(bool update_succeeded) override; void CacheHashResults(const std::vector<SBPrefix>& prefixes,
diff --git a/chrome/browser/safe_browsing/safe_browsing_database_unittest.cc b/chrome/browser/safe_browsing/safe_browsing_database_unittest.cc index b76173ca3..7264c9f 100644 --- a/chrome/browser/safe_browsing/safe_browsing_database_unittest.cc +++ b/chrome/browser/safe_browsing/safe_browsing_database_unittest.cc
@@ -9,7 +9,6 @@ #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/logging.h" -#include "base/memory/scoped_vector.h" #include "base/message_loop/message_loop.h" #include "base/sha1.h" #include "base/strings/string_number_conversions.h" @@ -62,12 +61,12 @@ } // Helper to build a chunk. Caller takes ownership. -SBChunkData* BuildChunk(int chunk_number, - ChunkData::ChunkType chunk_type, - ChunkData::PrefixType prefix_type, - const void* data, - size_t data_size, - const std::vector<int>& add_chunk_numbers) { +scoped_ptr<SBChunkData> BuildChunk(int chunk_number, + ChunkData::ChunkType chunk_type, + ChunkData::PrefixType prefix_type, + const void* data, + size_t data_size, + const std::vector<int>& add_chunk_numbers) { scoped_ptr<ChunkData> raw_data(new ChunkData); raw_data->set_chunk_number(chunk_number); raw_data->set_chunk_type(chunk_type); @@ -78,25 +77,25 @@ raw_data->add_add_numbers(add_chunk_numbers[i]); } - return new SBChunkData(raw_data.release()); + return make_scoped_ptr(new SBChunkData(raw_data.Pass())); } // Create add chunk with a single prefix. -SBChunkData* AddChunkPrefix(int chunk_number, SBPrefix prefix) { +scoped_ptr<SBChunkData> AddChunkPrefix(int chunk_number, SBPrefix prefix) { return BuildChunk(chunk_number, ChunkData::ADD, ChunkData::PREFIX_4B, &prefix, sizeof(prefix), std::vector<int>()); } // Create add chunk with a single prefix generated from |value|. -SBChunkData* AddChunkPrefixValue(int chunk_number, - const std::string& value) { +scoped_ptr<SBChunkData> AddChunkPrefixValue(int chunk_number, + const std::string& value) { return AddChunkPrefix(chunk_number, SBPrefixForString(value)); } // Generate an add chunk with two prefixes. -SBChunkData* AddChunkPrefix2Value(int chunk_number, - const std::string& value1, - const std::string& value2) { +scoped_ptr<SBChunkData> AddChunkPrefix2Value(int chunk_number, + const std::string& value1, + const std::string& value2) { const SBPrefix prefixes[2] = { SBPrefixForString(value1), SBPrefixForString(value2), @@ -106,11 +105,11 @@ } // Generate an add chunk with four prefixes. -SBChunkData* AddChunkPrefix4Value(int chunk_number, - const std::string& value1, - const std::string& value2, - const std::string& value3, - const std::string& value4) { +scoped_ptr<SBChunkData> AddChunkPrefix4Value(int chunk_number, + const std::string& value1, + const std::string& value2, + const std::string& value3, + const std::string& value4) { const SBPrefix prefixes[4] = { SBPrefixForString(value1), SBPrefixForString(value2), @@ -122,22 +121,23 @@ } // Generate an add chunk with a full hash. -SBChunkData* AddChunkFullHash(int chunk_number, SBFullHash full_hash) { +scoped_ptr<SBChunkData> AddChunkFullHash(int chunk_number, + SBFullHash full_hash) { return BuildChunk(chunk_number, ChunkData::ADD, ChunkData::FULL_32B, &full_hash, sizeof(full_hash), std::vector<int>()); } // Generate an add chunk with a full hash generated from |value|. -SBChunkData* AddChunkFullHashValue(int chunk_number, - const std::string& value) { +scoped_ptr<SBChunkData> AddChunkFullHashValue(int chunk_number, + const std::string& value) { return AddChunkFullHash(chunk_number, SBFullHashForString(value)); } // Generate an add chunk with two full hashes. -SBChunkData* AddChunkFullHash2Value(int chunk_number, - const std::string& value1, - const std::string& value2) { +scoped_ptr<SBChunkData> AddChunkFullHash2Value(int chunk_number, + const std::string& value1, + const std::string& value2) { const SBFullHash full_hashes[2] = { SBFullHashForString(value1), SBFullHashForString(value2), @@ -147,20 +147,20 @@ } // Generate a sub chunk with a prefix generated from |value|. -SBChunkData* SubChunkPrefixValue(int chunk_number, - const std::string& value, - int add_chunk_number) { +scoped_ptr<SBChunkData> SubChunkPrefixValue(int chunk_number, + const std::string& value, + int add_chunk_number) { const SBPrefix prefix = SBPrefixForString(value); return BuildChunk(chunk_number, ChunkData::SUB, ChunkData::PREFIX_4B, &prefix, sizeof(prefix), std::vector<int>(1, add_chunk_number)); } // Generate a sub chunk with two prefixes. -SBChunkData* SubChunkPrefix2Value(int chunk_number, - const std::string& value1, - int add_chunk_number1, - const std::string& value2, - int add_chunk_number2) { +scoped_ptr<SBChunkData> SubChunkPrefix2Value(int chunk_number, + const std::string& value1, + int add_chunk_number1, + const std::string& value2, + int add_chunk_number2) { const SBPrefix prefixes[2] = { SBPrefixForString(value1), SBPrefixForString(value2), @@ -173,27 +173,27 @@ } // Generate a sub chunk with a full hash. -SBChunkData* SubChunkFullHash(int chunk_number, - SBFullHash full_hash, - int add_chunk_number) { +scoped_ptr<SBChunkData> SubChunkFullHash(int chunk_number, + SBFullHash full_hash, + int add_chunk_number) { return BuildChunk(chunk_number, ChunkData::SUB, ChunkData::FULL_32B, &full_hash, sizeof(full_hash), std::vector<int>(1, add_chunk_number)); } // Generate a sub chunk with a full hash generated from |value|. -SBChunkData* SubChunkFullHashValue(int chunk_number, - const std::string& value, - int add_chunk_number) { +scoped_ptr<SBChunkData> SubChunkFullHashValue(int chunk_number, + const std::string& value, + int add_chunk_number) { return SubChunkFullHash(chunk_number, SBFullHashForString(value), add_chunk_number); } // Generate an add chunk with a single full hash for the ip blacklist. -SBChunkData* AddChunkHashedIpValue(int chunk_number, - const std::string& ip_str, - size_t prefix_size) { +scoped_ptr<SBChunkData> AddChunkHashedIpValue(int chunk_number, + const std::string& ip_str, + size_t prefix_size) { const std::string full_hash_str = HashedIpPrefix(ip_str, prefix_size); EXPECT_EQ(sizeof(SBFullHash), full_hash_str.size()); SBFullHash full_hash; @@ -331,14 +331,14 @@ // Tests retrieving list name information. TEST_F(SafeBrowsingDatabaseTest, BrowseListsInfo) { std::vector<SBListChunkRanges> lists; - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; chunks.push_back(AddChunkPrefixValue(1, "www.evil.com/malware.html")); chunks.push_back(AddChunkPrefixValue(2, "www.foo.com/malware.html")); chunks.push_back(AddChunkPrefixValue(3, "www.whatever.com/malware.html")); ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(kMalwareList, chunks.get()); + database_->InsertChunks(kMalwareList, chunks); database_->UpdateFinished(true); GetListsInfo(&lists); @@ -352,7 +352,7 @@ chunks.push_back(SubChunkPrefixValue(7, "www.subbed.com/noteveil1.html", 19)); ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(kMalwareList, chunks.get()); + database_->InsertChunks(kMalwareList, chunks); database_->UpdateFinished(true); GetListsInfo(&lists); @@ -378,7 +378,7 @@ SubChunkPrefixValue(201, "www.phishy2.com/notevil1.html", 1999)); ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(kPhishingList, chunks.get()); + database_->InsertChunks(kPhishingList, chunks); database_->UpdateFinished(true); GetListsInfo(&lists); @@ -392,50 +392,50 @@ } TEST_F(SafeBrowsingDatabaseTest, ListNames) { - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; std::vector<SBListChunkRanges> lists; ASSERT_TRUE(database_->UpdateStarted(&lists)); // Insert malware, phish, binurl and bindownload add chunks. chunks.push_back(AddChunkPrefixValue(1, "www.evil.com/malware.html")); - database_->InsertChunks(kMalwareList, chunks.get()); + database_->InsertChunks(kMalwareList, chunks); chunks.clear(); chunks.push_back(AddChunkPrefixValue(2, "www.foo.com/malware.html")); - database_->InsertChunks(kPhishingList, chunks.get()); + database_->InsertChunks(kPhishingList, chunks); chunks.clear(); chunks.push_back(AddChunkPrefixValue(3, "www.whatever.com/download.html")); - database_->InsertChunks(kBinUrlList, chunks.get()); + database_->InsertChunks(kBinUrlList, chunks); chunks.clear(); chunks.push_back(AddChunkFullHashValue(5, "www.forwhitelist.com/a.html")); - database_->InsertChunks(kCsdWhiteList, chunks.get()); + database_->InsertChunks(kCsdWhiteList, chunks); chunks.clear(); chunks.push_back(AddChunkFullHashValue(6, "www.download.com/")); - database_->InsertChunks(kDownloadWhiteList, chunks.get()); + database_->InsertChunks(kDownloadWhiteList, chunks); chunks.clear(); chunks.push_back(AddChunkFullHashValue(7, "www.inclusion.com/")); database_->InsertChunks(kInclusionWhitelist, - chunks.get()); + chunks); chunks.clear(); chunks.push_back(AddChunkFullHashValue(8, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")); database_->InsertChunks(kExtensionBlacklist, - chunks.get()); + chunks); chunks.clear(); chunks.push_back(AddChunkHashedIpValue(10, "::ffff:192.168.1.0", 120)); - database_->InsertChunks(kIPBlacklist, chunks.get()); + database_->InsertChunks(kIPBlacklist, chunks); chunks.clear(); chunks.push_back(AddChunkPrefixValue(11, "www.unwanted.com/software.html")); - database_->InsertChunks(kUnwantedUrlList, chunks.get()); + database_->InsertChunks(kUnwantedUrlList, chunks); database_->UpdateFinished(true); @@ -495,7 +495,7 @@ test_case.test_list_name); std::vector<SBListChunkRanges> lists; - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; chunks.push_back(AddChunkPrefix2Value(1, "www.evil.com/phishing.html", @@ -509,7 +509,7 @@ chunks.push_back(AddChunkFullHashValue(7, "www.evil.com/evil.html")); ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(test_case.test_list_name, chunks.get()); + database_->InsertChunks(test_case.test_list_name, chunks); database_->UpdateFinished(true); // Make sure they were added correctly. @@ -567,7 +567,7 @@ "www.evil.com/phishing.html", "www.evil.com/malware.html")); ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(test_case.test_list_name, chunks.get()); + database_->InsertChunks(test_case.test_list_name, chunks); database_->UpdateFinished(true); GetListsInfo(&lists); @@ -581,7 +581,7 @@ chunks.clear(); chunks.push_back(SubChunkPrefixValue(4, "www.evil.com/notevil1.html", 2)); ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(test_case.test_list_name, chunks.get()); + database_->InsertChunks(test_case.test_list_name, chunks); database_->UpdateFinished(true); EXPECT_TRUE((database_.get()->*test_case.test_list_contains_bad_url)( @@ -617,7 +617,7 @@ chunks.push_back(SubChunkPrefixValue(4, "www.evil.com/notevil1.html", 2)); ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(test_case.test_list_name, chunks.get()); + database_->InsertChunks(test_case.test_list_name, chunks); database_->UpdateFinished(true); GetListsInfo(&lists); @@ -654,7 +654,7 @@ chunks.clear(); chunks.push_back(AddChunkPrefixValue(44, "www.redherring.com/index.html")); ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(test_case.test_list_name, chunks.get()); + database_->InsertChunks(test_case.test_list_name, chunks); // Now remove the dummy entry. If there are any problems with the // transactions, asserts will fire. @@ -679,7 +679,7 @@ "www.notevilanymore.com/good.html", 10)); ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(test_case.test_list_name, chunks.get()); + database_->InsertChunks(test_case.test_list_name, chunks); database_->UpdateFinished(true); EXPECT_FALSE((database_.get()->*test_case.test_list_contains_bad_url)( @@ -694,7 +694,7 @@ "www.notevilanymore.com/index.html", "www.notevilanymore.com/good.html")); ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(test_case.test_list_name, chunks.get()); + database_->InsertChunks(test_case.test_list_name, chunks); database_->UpdateFinished(true); EXPECT_FALSE((database_.get()->*test_case.test_list_contains_bad_url)( @@ -731,7 +731,7 @@ // Test adding zero length chunks to the database. TEST_F(SafeBrowsingDatabaseTest, ZeroSizeChunk) { std::vector<SBListChunkRanges> lists; - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; // Populate with a couple of normal chunks. chunks.push_back(AddChunkPrefix2Value(1, @@ -742,7 +742,7 @@ "www.random.com/random2.html")); ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(kMalwareList, chunks.get()); + database_->InsertChunks(kMalwareList, chunks); database_->UpdateFinished(true); // Add an empty ADD and SUB chunk. @@ -759,7 +759,7 @@ std::vector<int>())); ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(kMalwareList, chunks.get()); + database_->InsertChunks(kMalwareList, chunks); database_->UpdateFinished(true); GetListsInfo(&lists); @@ -777,7 +777,7 @@ chunks.push_back(AddChunkPrefixValue(22, "www.notempty.com/full2.html")); ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(kMalwareList, chunks.get()); + database_->InsertChunks(kMalwareList, chunks); database_->UpdateFinished(true); std::vector<SBPrefix> prefix_hits; @@ -818,14 +818,14 @@ // Utility function for setting up the database for the caching test. void SafeBrowsingDatabaseTest::PopulateDatabaseForCacheTest() { // Add a couple prefixes. - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; chunks.push_back(AddChunkPrefix2Value(1, "www.evil.com/phishing.html", "www.evil.com/malware.html")); std::vector<SBListChunkRanges> lists; ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(kMalwareList, chunks.get()); + database_->InsertChunks(kMalwareList, chunks); database_->UpdateFinished(true); // Cache should be cleared after updating. @@ -886,12 +886,12 @@ cache_hits.clear(); // Test removing a prefix via a sub chunk. - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; chunks.push_back(SubChunkPrefixValue(2, "www.evil.com/phishing.html", 1)); std::vector<SBListChunkRanges> lists; ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(kMalwareList, chunks.get()); + database_->InsertChunks(kMalwareList, chunks); database_->UpdateFinished(true); // This prefix should still be there, but cached fullhash should be gone. @@ -1002,7 +1002,7 @@ "www.fullevil.com/bad1.html", "www.fullevil.com/bad2.html")); ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(kMalwareList, chunks.get()); + database_->InsertChunks(kMalwareList, chunks); database_->UpdateFinished(true); EXPECT_TRUE(database_->ContainsBrowseUrl( @@ -1027,7 +1027,7 @@ "www.fullevil.com/bad1.html", 20)); ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(kMalwareList, chunks.get()); + database_->InsertChunks(kMalwareList, chunks); database_->UpdateFinished(true); EXPECT_FALSE(database_->ContainsBrowseUrl( @@ -1060,9 +1060,9 @@ SBPrefixForString(kExampleCollision)); ASSERT_TRUE(database_->UpdateStarted(&lists)); { - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; chunks.push_back(AddChunkPrefixValue(21, kExampleCollision)); - database_->InsertChunks(kMalwareList, chunks.get()); + database_->InsertChunks(kMalwareList, chunks); } database_->UpdateFinished(true); @@ -1110,7 +1110,7 @@ database_->UpdateFinished(true); // Create a sub chunk to insert. - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; chunks.push_back(SubChunkPrefixValue(7, "www.subbed.com/notevil1.html", 19)); @@ -1131,7 +1131,7 @@ // Start an update. The insert will fail due to corruption. ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(kMalwareList, chunks.get()); + database_->InsertChunks(kMalwareList, chunks); database_->UpdateFinished(true); // Database file still exists until the corruption handler has run. @@ -1147,7 +1147,7 @@ // Run the update again successfully. ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(kMalwareList, chunks.get()); + database_->InsertChunks(kMalwareList, chunks); database_->UpdateFinished(true); EXPECT_TRUE(base::PathExists(database_filename_)); @@ -1160,12 +1160,12 @@ const char kEvil1Url2[] = "www.evil1.com/download2.html"; // Add a simple chunk with one hostkey for download url list. - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; chunks.push_back(AddChunkPrefix2Value(1, kEvil1Url1, kEvil1Url2)); std::vector<SBListChunkRanges> lists; ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(kBinUrlList, chunks.get()); + database_->InsertChunks(kBinUrlList, chunks); database_->UpdateFinished(true); std::vector<SBPrefix> prefix_hits; @@ -1332,7 +1332,7 @@ kGoodString)); } - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; // Add a few test chunks to the whitelist under test. chunks.push_back(AddChunkFullHash2Value(1, kGood1Url1, kGood1Url2)); @@ -1343,7 +1343,7 @@ std::vector<SBListChunkRanges> lists; ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(test_case.test_list_name, chunks.get()); + database_->InsertChunks(test_case.test_list_name, chunks); database_->UpdateFinished(true); EXPECT_FALSE( @@ -1413,7 +1413,7 @@ 15, "sb-ssl.google.com/safebrowsing/csd/killswitch_malware")); ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(kCsdWhiteList, chunks.get()); + database_->InsertChunks(kCsdWhiteList, chunks); database_->UpdateFinished(true); EXPECT_TRUE(database_->IsMalwareIPMatchKillSwitchOn()); @@ -1428,7 +1428,7 @@ 5, "sb-ssl.google.com/safebrowsing/csd/killswitch")); ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(test_case.test_list_name, chunks.get()); + database_->InsertChunks(test_case.test_list_name, chunks); database_->UpdateFinished(true); // Test CSD whitelist specific methods. @@ -1468,7 +1468,7 @@ } ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(test_case.test_list_name, chunks.get()); + database_->InsertChunks(test_case.test_list_name, chunks); database_->UpdateFinished(true); if (test_case.test_list_name == kCsdWhiteList) { @@ -1504,7 +1504,7 @@ // Test to make sure we could insert chunk list that // contains entries for the same host. TEST_F(SafeBrowsingDatabaseTest, SameHostEntriesOkay) { - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; // Add a malware add chunk with two entries of the same host. chunks.push_back(AddChunkPrefix2Value(1, @@ -1514,7 +1514,7 @@ // Insert the testing chunks into database. std::vector<SBListChunkRanges> lists; ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(kMalwareList, chunks.get()); + database_->InsertChunks(kMalwareList, chunks); database_->UpdateFinished(true); GetListsInfo(&lists); @@ -1530,7 +1530,7 @@ "www.evil.com/phishing2.html")); ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(kPhishingList, chunks.get()); + database_->InsertChunks(kPhishingList, chunks); database_->UpdateFinished(true); GetListsInfo(&lists); @@ -1559,14 +1559,14 @@ chunks.clear(); chunks.push_back(SubChunkPrefixValue(4, "www.evil.com/malware1.html", 1)); ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(kMalwareList, chunks.get()); + database_->InsertChunks(kMalwareList, chunks); database_->UpdateFinished(true); // Remove the prefix that added last. chunks.clear(); chunks.push_back(SubChunkPrefixValue(5, "www.evil.com/phishing2.html", 47)); ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(kPhishingList, chunks.get()); + database_->InsertChunks(kPhishingList, chunks); database_->UpdateFinished(true); // Verify that the database contains urls expected. @@ -1584,7 +1584,7 @@ // This isn't a functionality requirement, but it is a useful // optimization. TEST_F(SafeBrowsingDatabaseTest, EmptyUpdate) { - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; base::FilePath filename = database_->BrowseDBFilename(database_filename_); @@ -1592,7 +1592,7 @@ std::vector<SBListChunkRanges> lists; ASSERT_TRUE(database_->UpdateStarted(&lists)); chunks.push_back(AddChunkPrefixValue(1, "www.evil.com/malware.html")); - database_->InsertChunks(kMalwareList, chunks.get()); + database_->InsertChunks(kMalwareList, chunks); database_->UpdateFinished(true); // Get an older time to reset the lastmod time for detecting whether @@ -1609,7 +1609,7 @@ ASSERT_TRUE(base::GetFileInfo(filename, &before_info)); ASSERT_TRUE(database_->UpdateStarted(&lists)); chunks.push_back(AddChunkPrefixValue(2, "www.foo.com/malware.html")); - database_->InsertChunks(kMalwareList, chunks.get()); + database_->InsertChunks(kMalwareList, chunks); database_->UpdateFinished(true); ASSERT_TRUE(base::GetFileInfo(filename, &after_info)); EXPECT_LT(before_info.last_modified, after_info.last_modified); @@ -1642,9 +1642,9 @@ std::vector<SBListChunkRanges> lists; ASSERT_TRUE(database_->UpdateStarted(&lists)); - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; chunks.push_back(AddChunkPrefixValue(1, "www.evil.com/malware.html")); - database_->InsertChunks(kMalwareList, chunks.get()); + database_->InsertChunks(kMalwareList, chunks); database_->UpdateFinished(true); } @@ -1688,13 +1688,13 @@ SBFullHashForPrefixAndSuffix(kPrefix2, "\x01"); // Insert prefix kPrefix1 and kPrefix2 into database. - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; chunks.push_back(AddChunkPrefix(1, kPrefix1)); chunks.push_back(AddChunkPrefix(2, kPrefix2)); std::vector<SBListChunkRanges> lists; ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(kMalwareList, chunks.get()); + database_->InsertChunks(kMalwareList, chunks); database_->UpdateFinished(true); { @@ -1743,13 +1743,13 @@ SBFullHashForPrefixAndSuffix(kPrefix3, "\x01"); // Insert prefix kPrefix1 and kPrefix2 into database. - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; chunks.push_back(AddChunkPrefix(1, kPrefix1)); chunks.push_back(AddChunkPrefix(2, kPrefix2)); std::vector<SBListChunkRanges> lists; ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(kMalwareList, chunks.get()); + database_->InsertChunks(kMalwareList, chunks); database_->UpdateFinished(true); { @@ -1888,13 +1888,13 @@ SBFullHashForPrefixAndSuffix(kPrefix1, "\x03"); // Insert two full hashes with a shared prefix. - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; chunks.push_back(AddChunkFullHash(1, kFullHash1_1)); chunks.push_back(AddChunkFullHash(2, kFullHash1_2)); std::vector<SBListChunkRanges> lists; ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(kMalwareList, chunks.get()); + database_->InsertChunks(kMalwareList, chunks); database_->UpdateFinished(true); { @@ -1972,7 +1972,7 @@ chunks.push_back(SubChunkFullHash(11, kFullHash1_1, 1)); ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(kMalwareList, chunks.get()); + database_->InsertChunks(kMalwareList, chunks); database_->UpdateFinished(true); // Cache should be cleared after updating. @@ -2010,7 +2010,7 @@ chunks.push_back(SubChunkFullHash(12, kFullHash1_2, 2)); ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(kMalwareList, chunks.get()); + database_->InsertChunks(kMalwareList, chunks); database_->UpdateFinished(true); // Cache should be cleared after updating. @@ -2037,12 +2037,12 @@ const SBFullHash kFullHash1_2 = SBFullHashForPrefixAndSuffix(kPrefix1, "\x02"); - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; chunks.push_back(AddChunkFullHash(1, kFullHash1_1)); std::vector<SBListChunkRanges> lists; ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(kMalwareList, chunks.get()); + database_->InsertChunks(kMalwareList, chunks); database_->UpdateFinished(true); { @@ -2059,7 +2059,7 @@ chunks.push_back(AddChunkPrefix(2, kPrefix1)); ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(kMalwareList, chunks.get()); + database_->InsertChunks(kMalwareList, chunks); database_->UpdateFinished(true); { @@ -2079,7 +2079,7 @@ chunks.push_back(SubChunkFullHash(11, kFullHash1_1, 1)); ASSERT_TRUE(database_->UpdateStarted(&lists)); - database_->InsertChunks(kMalwareList, chunks.get()); + database_->InsertChunks(kMalwareList, chunks); database_->UpdateFinished(true); { @@ -2099,7 +2099,7 @@ std::vector<SBListChunkRanges> lists; ASSERT_TRUE(database_->UpdateStarted(&lists)); - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; // IPv4 prefix match for ::ffff:192.168.1.0/120. chunks.push_back(AddChunkHashedIpValue(1, "::ffff:192.168.1.0", 120)); @@ -2119,7 +2119,7 @@ // IPv4 prefix match for ::ffff:192.1.128.0/113. chunks.push_back(AddChunkHashedIpValue(6, "::ffff:192.1.128.0", 113)); - database_->InsertChunks(kIPBlacklist, chunks.get()); + database_->InsertChunks(kIPBlacklist, chunks); database_->UpdateFinished(true); EXPECT_FALSE(database_->ContainsMalwareIP("192.168.0.255")); @@ -2167,17 +2167,17 @@ // Add a host-level hit. { - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; chunks.push_back(AddChunkPrefixValue(1, "www.evil.com/")); - database_->InsertChunks(kMalwareList, chunks.get()); + database_->InsertChunks(kMalwareList, chunks); } // Add a specific fullhash. static const char kWhateverMalware[] = "www.whatever.com/malware.html"; { - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; chunks.push_back(AddChunkFullHashValue(2, kWhateverMalware)); - database_->InsertChunks(kMalwareList, chunks.get()); + database_->InsertChunks(kMalwareList, chunks); } // Add a fullhash which has a prefix collision for a known url. @@ -2187,9 +2187,9 @@ ASSERT_EQ(SBPrefixForString(kExampleFine), SBPrefixForString(kExampleCollision)); { - ScopedVector<SBChunkData> chunks; + std::vector<scoped_ptr<SBChunkData>> chunks; chunks.push_back(AddChunkFullHashValue(3, kExampleCollision)); - database_->InsertChunks(kMalwareList, chunks.get()); + database_->InsertChunks(kMalwareList, chunks); } database_->UpdateFinished(true);
diff --git a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc index 33c75ac..f0c507b 100644 --- a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc +++ b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
@@ -178,8 +178,9 @@ ADD_FAILURE() << "Not implemented."; return false; } - void InsertChunks(const std::string& list_name, - const std::vector<SBChunkData*>& chunks) override { + void InsertChunks( + const std::string& list_name, + const std::vector<scoped_ptr<SBChunkData>>& chunks) override { ADD_FAILURE() << "Not implemented."; } void DeleteChunks(const std::vector<SBChunkDelete>& chunk_deletes) override {
diff --git a/chrome/browser/safe_browsing/safe_browsing_util.cc b/chrome/browser/safe_browsing/safe_browsing_util.cc index 1d4ec5f..167e103 100644 --- a/chrome/browser/safe_browsing/safe_browsing_util.cc +++ b/chrome/browser/safe_browsing/safe_browsing_util.cc
@@ -22,8 +22,8 @@ SBChunkData::SBChunkData() { } -SBChunkData::SBChunkData(ChunkData* raw_data) - : chunk_data_(raw_data) { +SBChunkData::SBChunkData(scoped_ptr<ChunkData> data) + : chunk_data_(data.Pass()) { DCHECK(chunk_data_.get()); }
diff --git a/chrome/browser/safe_browsing/safe_browsing_util.h b/chrome/browser/safe_browsing/safe_browsing_util.h index c4d1812..94972a2d 100644 --- a/chrome/browser/safe_browsing/safe_browsing_util.h +++ b/chrome/browser/safe_browsing/safe_browsing_util.h
@@ -37,7 +37,7 @@ // Create with manufactured data, for testing only. // TODO(shess): Right now the test code calling this is in an anonymous // namespace. Figure out how to shift this into private:. - explicit SBChunkData(ChunkData* chunk_data); + explicit SBChunkData(scoped_ptr<ChunkData> data); // Read serialized ChunkData, returning true if the parse suceeded. bool ParseFrom(const unsigned char* data, size_t length);
diff --git a/chrome/browser/supervised_user/supervised_user_whitelist_service.cc b/chrome/browser/supervised_user/supervised_user_whitelist_service.cc index 7fdc0c1..458e573 100644 --- a/chrome/browser/supervised_user/supervised_user_whitelist_service.cc +++ b/chrome/browser/supervised_user/supervised_user_whitelist_service.cc
@@ -67,13 +67,31 @@ weak_ptr_factory_.GetWeakPtr())); // Register whitelists specified on the command line. + for (const auto& whitelist : GetWhitelistsFromCommandLine()) + RegisterWhitelist(whitelist.first, whitelist.second, FROM_COMMAND_LINE); +} + +void SupervisedUserWhitelistService::AddSiteListsChangedCallback( + const SiteListsChangedCallback& callback) { + site_lists_changed_callbacks_.push_back(callback); + + std::vector<scoped_refptr<SupervisedUserSiteList>> whitelists; + GetLoadedWhitelists(&whitelists); + callback.Run(whitelists); +} + +// static +std::map<std::string, std::string> +SupervisedUserWhitelistService::GetWhitelistsFromCommandLine() { + std::map<std::string, std::string> whitelists; const base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); std::string command_line_whitelists = command_line->GetSwitchValueASCII( switches::kInstallSupervisedUserWhitelists); - for (const base::StringPiece& whitelist : base::SplitStringPiece( - command_line_whitelists, ",", - base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) { + std::vector<base::StringPiece> string_pieces = + base::SplitStringPiece(command_line_whitelists, ",", + base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); + for (const base::StringPiece& whitelist : string_pieces) { std::string id; std::string name; size_t separator = whitelist.find(':'); @@ -84,17 +102,11 @@ whitelist.CopyToString(&id); } - RegisterWhitelist(id, name, FROM_COMMAND_LINE); + const bool result = whitelists.insert(std::make_pair(id, name)).second; + DCHECK(result); } -} -void SupervisedUserWhitelistService::AddSiteListsChangedCallback( - const SiteListsChangedCallback& callback) { - site_lists_changed_callbacks_.push_back(callback); - - std::vector<scoped_refptr<SupervisedUserSiteList>> whitelists; - GetLoadedWhitelists(&whitelists); - callback.Run(whitelists); + return whitelists; } void SupervisedUserWhitelistService::LoadWhitelistForTesting(
diff --git a/chrome/browser/supervised_user/supervised_user_whitelist_service.h b/chrome/browser/supervised_user/supervised_user_whitelist_service.h index e31f344d..cf80bfb1 100644 --- a/chrome/browser/supervised_user/supervised_user_whitelist_service.h +++ b/chrome/browser/supervised_user/supervised_user_whitelist_service.h
@@ -57,6 +57,10 @@ // site lists. void AddSiteListsChangedCallback(const SiteListsChangedCallback& callback); + // Returns a map (from CRX ID to name) of whitelists to be installed, + // specified on the command line. + static std::map<std::string, std::string> GetWhitelistsFromCommandLine(); + // Loads an already existing whitelist on disk (i.e. without downloading it as // a component). void LoadWhitelistForTesting(const std::string& id,
diff --git a/chrome/browser/themes/theme_properties.cc b/chrome/browser/themes/theme_properties.cc index 406aa36..2ea97c9 100644 --- a/chrome/browser/themes/theme_properties.cc +++ b/chrome/browser/themes/theme_properties.cc
@@ -10,6 +10,7 @@ #include "chrome/browser/themes/browser_theme_pack.h" #include "grit/theme_resources.h" #include "ui/base/resource/material_design/material_design_controller.h" +#include "ui/gfx/color_palette.h" #include "ui/resources/grit/ui_resources.h" namespace { @@ -313,7 +314,6 @@ return kDefaultColorToolbarStrokeInactive; #endif default: - // Return a debugging red color. - return SK_ColorRED; + return gfx::kPlaceholderColor; } }
diff --git a/chrome/browser/themes/theme_properties.h b/chrome/browser/themes/theme_properties.h index 33755a4..9171723 100644 --- a/chrome/browser/themes/theme_properties.h +++ b/chrome/browser/themes/theme_properties.h
@@ -146,7 +146,7 @@ static color_utils::HSL GetDefaultTint(int id); // Returns the default color for the given color |id| COLOR_* enum value. - // Returns SK_ColorRED if |id| is invalid. + // Returns gfx::kPlaceholderColor if |id| is invalid. static SkColor GetDefaultColor(int id); private:
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate_chromeos.cc b/chrome/browser/ui/ash/chrome_shell_delegate_chromeos.cc index 80b6b095..c330a95 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate_chromeos.cc +++ b/chrome/browser/ui/ash/chrome_shell_delegate_chromeos.cc
@@ -18,6 +18,7 @@ #include "chrome/browser/chromeos/background/ash_user_wallpaper_delegate.h" #include "chrome/browser/chromeos/display/display_configuration_observer.h" #include "chrome/browser/chromeos/display/display_preferences.h" +#include "chrome/browser/chromeos/policy/display_rotation_default_handler.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" @@ -224,6 +225,8 @@ void ChromeShellDelegate::PreInit() { chromeos::LoadDisplayPreferences(IsFirstRunAfterBoot()); + // Object owns itself, and deletes itself when Observer::OnShutdown is called: + new policy::DisplayRotationDefaultHandler(); // Set the observer now so that we can save the initial state // in Shell::Init. display_configuration_observer_.reset(
diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h index 7f4d216..b41962f 100644 --- a/chrome/browser/ui/browser_window.h +++ b/chrome/browser/ui/browser_window.h
@@ -268,11 +268,6 @@ translate::TranslateErrors::Type error_type, bool is_user_gesture) = 0; - // Shows the profile reset bubble on the platforms that support it. - virtual bool IsProfileResetBubbleSupported() const = 0; - virtual GlobalErrorBubbleViewBase* ShowProfileResetBubble( - const base::WeakPtr<ProfileResetGlobalError>& global_error) = 0; - #if defined(ENABLE_ONE_CLICK_SIGNIN) enum OneClickSigninBubbleType { ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE,
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.h b/chrome/browser/ui/cocoa/browser_window_cocoa.h index c58e1be..43f633c4 100644 --- a/chrome/browser/ui/cocoa/browser_window_cocoa.h +++ b/chrome/browser/ui/cocoa/browser_window_cocoa.h
@@ -124,9 +124,6 @@ translate::TranslateStep step, translate::TranslateErrors::Type error_type, bool is_user_gesture) override; - bool IsProfileResetBubbleSupported() const override; - GlobalErrorBubbleViewBase* ShowProfileResetBubble( - const base::WeakPtr<ProfileResetGlobalError>& global_error) override; #if defined(ENABLE_ONE_CLICK_SIGNIN) void ShowOneClickSigninBubble( OneClickSigninBubbleType type,
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.mm b/chrome/browser/ui/cocoa/browser_window_cocoa.mm index d98c565..0c703069 100644 --- a/chrome/browser/ui/cocoa/browser_window_cocoa.mm +++ b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
@@ -661,16 +661,6 @@ errorType:error_type]; } -bool BrowserWindowCocoa::IsProfileResetBubbleSupported() const { - return false; -} - -GlobalErrorBubbleViewBase* BrowserWindowCocoa::ShowProfileResetBubble( - const base::WeakPtr<ProfileResetGlobalError>& global_error) { - NOTREACHED(); - return nullptr; -} - #if defined(ENABLE_ONE_CLICK_SIGNIN) void BrowserWindowCocoa::ShowOneClickSigninBubble( OneClickSigninBubbleType type,
diff --git a/chrome/browser/ui/cocoa/passwords/passwords_list_view_controller_unittest.mm b/chrome/browser/ui/cocoa/passwords/passwords_list_view_controller_unittest.mm index 7f8f3bd..adf8ea8 100644 --- a/chrome/browser/ui/cocoa/passwords/passwords_list_view_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/passwords/passwords_list_view_controller_unittest.mm
@@ -37,7 +37,7 @@ ManagePasswordsControllerTest::SetUp(); PasswordStoreFactory::GetInstance()->SetTestingFactory( profile(), - password_manager::BuildPasswordStoreService< + password_manager::BuildPasswordStore< content::BrowserContext, password_manager::MockPasswordStore>); }
diff --git a/chrome/browser/ui/extensions/extension_action_view_controller.cc b/chrome/browser/ui/extensions/extension_action_view_controller.cc index 22decd3..84ed17a 100644 --- a/chrome/browser/ui/extensions/extension_action_view_controller.cc +++ b/chrome/browser/ui/extensions/extension_action_view_controller.cc
@@ -27,6 +27,7 @@ #include "extensions/common/extension.h" #include "extensions/common/feature_switch.h" #include "extensions/common/manifest_constants.h" +#include "ui/base/resource/material_design/material_design_controller.h" #include "ui/gfx/image/image_skia.h" #include "ui/gfx/image/image_skia_operations.h" @@ -364,7 +365,18 @@ int tab_id = SessionTabHelper::IdForTab(web_contents); scoped_ptr<IconWithBadgeImageSource> image_source( new IconWithBadgeImageSource(size)); - image_source->SetIcon(icon_factory_.GetIcon(tab_id)); + + gfx::Image icon(icon_factory_.GetIcon(tab_id)); + if (ui::MaterialDesignController::IsModeMaterial()) { + // TODO(tdanderson): Use a 16x16 icon if it exists instead of resizing. + icon = gfx::Image(gfx::ImageSkiaOperations::CreateResizedImage( + *icon.ToImageSkia(), + skia::ImageOperations::RESIZE_BEST, + gfx::Size(extension_misc::EXTENSION_ICON_BITTY, + extension_misc::EXTENSION_ICON_BITTY))); + } + image_source->SetIcon(icon); + scoped_ptr<IconWithBadgeImageSource::Badge> badge; std::string badge_text = extension_action_->GetBadgeText(tab_id); if (!badge_text.empty()) {
diff --git a/chrome/browser/ui/login/login_prompt_browsertest.cc b/chrome/browser/ui/login/login_prompt_browsertest.cc index b28c248..c4a7738c 100644 --- a/chrome/browser/ui/login/login_prompt_browsertest.cc +++ b/chrome/browser/ui/login/login_prompt_browsertest.cc
@@ -1423,22 +1423,12 @@ } } -// Fails on non-aura because of crbug.com/555804. -// TODO(meacer): Enable for all when that bug is fixed. -#if defined(USE_AURA) -#define MAYBE_ShouldNotProceedExistingInterstitial \ - ShouldNotProceedExistingInterstitial -#else -#define MAYBE_ShouldNotProceedExistingInterstitial \ - DISABLED_MAYBE_ShouldNotProceedExistingInterstitial -#endif - // Test that the login interstitial isn't proceeding itself or any other // interstitial. If this test becomes flaky, it's likely that the logic that // prevents the tested scenario from happening got broken, rather than the test // itself. IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest, - MAYBE_ShouldNotProceedExistingInterstitial) { + ShouldNotProceedExistingInterstitial) { net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED); ASSERT_TRUE(https_server.Start());
diff --git a/chrome/browser/ui/passwords/password_manager_presenter_unittest.cc b/chrome/browser/ui/passwords/password_manager_presenter_unittest.cc index a2ebe32..ccb7e01 100644 --- a/chrome/browser/ui/passwords/password_manager_presenter_unittest.cc +++ b/chrome/browser/ui/passwords/password_manager_presenter_unittest.cc
@@ -59,7 +59,7 @@ void SetUp() override { PasswordStoreFactory::GetInstance()->SetTestingFactory( &profile_, - password_manager::BuildPasswordStoreService< + password_manager::BuildPasswordStore< content::BrowserContext, password_manager::MockPasswordStore>); mock_controller_.reset(new MockPasswordUIView(&profile_)); }
diff --git a/chrome/browser/ui/views/app_list/app_list_dialog_container.cc b/chrome/browser/ui/views/app_list/app_list_dialog_container.cc index 4b23b2e0..55fbbc32 100644 --- a/chrome/browser/ui/views/app_list/app_list_dialog_container.cc +++ b/chrome/browser/ui/views/app_list/app_list_dialog_container.cc
@@ -13,6 +13,7 @@ #include "ui/events/event_constants.h" #include "ui/events/keycodes/keyboard_codes.h" #include "ui/gfx/canvas.h" +#include "ui/gfx/color_palette.h" #include "ui/resources/grit/ui_resources.h" #include "ui/views/background.h" #include "ui/views/border.h" @@ -214,7 +215,7 @@ views::Widget* widget) override { FullSizeBubbleFrameView* frame = new FullSizeBubbleFrameView(); scoped_ptr<views::BubbleBorder> border(new views::BubbleBorder( - views::BubbleBorder::FLOAT, kShadowType, SK_ColorRED)); + views::BubbleBorder::FLOAT, kShadowType, gfx::kPlaceholderColor)); border->set_use_theme_background_color(true); frame->SetBubbleBorder(border.Pass()); return frame;
diff --git a/chrome/browser/ui/views/download/download_item_view_md.cc b/chrome/browser/ui/views/download/download_item_view_md.cc index ecfd25f..8b11b4a 100644 --- a/chrome/browser/ui/views/download/download_item_view_md.cc +++ b/chrome/browser/ui/views/download/download_item_view_md.cc
@@ -220,7 +220,7 @@ SkColor DownloadItemViewMd::GetTextColorForThemeProvider( ui::ThemeProvider* theme) { return theme ? theme->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT) - : SK_ColorRED; + : gfx::kPlaceholderColor; } void DownloadItemViewMd::OnExtractIconComplete(gfx::Image* icon_bitmap) {
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 810d9f0..1271b2f 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -80,7 +80,6 @@ #include "chrome/browser/ui/views/omnibox/omnibox_view_views.h" #include "chrome/browser/ui/views/profiles/avatar_menu_button.h" #include "chrome/browser/ui/views/profiles/profile_chooser_view.h" -#include "chrome/browser/ui/views/profiles/profile_reset_bubble_view.h" #include "chrome/browser/ui/views/session_crashed_bubble_view.h" #include "chrome/browser/ui/views/settings_api_bubble_helper_views.h" #include "chrome/browser/ui/views/status_bubble_views.h" @@ -1330,15 +1329,6 @@ : TranslateBubbleView::AUTOMATIC); } -bool BrowserView::IsProfileResetBubbleSupported() const { - return true; -} - -GlobalErrorBubbleViewBase* BrowserView::ShowProfileResetBubble( - const base::WeakPtr<ProfileResetGlobalError>& global_error) { - return ProfileResetBubbleView::ShowBubble(global_error, browser_.get()); -} - #if defined(ENABLE_ONE_CLICK_SIGNIN) void BrowserView::ShowOneClickSigninBubble( OneClickSigninBubbleType type,
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h index 1f0e6c0..5b1490c 100644 --- a/chrome/browser/ui/views/frame/browser_view.h +++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -326,9 +326,6 @@ translate::TranslateStep step, translate::TranslateErrors::Type error_type, bool is_user_gesture) override; - bool IsProfileResetBubbleSupported() const override; - GlobalErrorBubbleViewBase* ShowProfileResetBubble( - const base::WeakPtr<ProfileResetGlobalError>& global_error) override; #if defined(ENABLE_ONE_CLICK_SIGNIN) void ShowOneClickSigninBubble( OneClickSigninBubbleType type,
diff --git a/chrome/browser/ui/views/location_bar/keyword_hint_view.cc b/chrome/browser/ui/views/location_bar/keyword_hint_view.cc index 02d1ff61..80f4d17 100644 --- a/chrome/browser/ui/views/location_bar/keyword_hint_view.cc +++ b/chrome/browser/ui/views/location_bar/keyword_hint_view.cc
@@ -21,6 +21,7 @@ #include "ui/base/resource/material_design/material_design_controller.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/canvas.h" +#include "ui/gfx/color_palette.h" #include "ui/strings/grit/ui_strings.h" #include "ui/views/controls/image_view.h" #include "ui/views/controls/label.h" @@ -48,7 +49,11 @@ TabKeyBubbleView::TabKeyBubbleView(const gfx::FontList& font_list, SkColor text_color, SkColor background_color) - : IconLabelBubbleView(0, font_list, SK_ColorRED, background_color, false), + : IconLabelBubbleView(0, + font_list, + gfx::kPlaceholderColor, + background_color, + false), text_color_(text_color) { SetLabel(l10n_util::GetStringUTF16(IDS_APP_TAB_KEY)); }
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc index 0ab0325d..3154225 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
@@ -257,7 +257,7 @@ } NOTREACHED(); - return SK_ColorRED; + return gfx::kPlaceholderColor; } void OmniboxResultView::SetMatch(const AutocompleteMatch& match) {
diff --git a/chrome/browser/ui/views/profiles/profile_reset_bubble_view.cc b/chrome/browser/ui/views/profiles/profile_reset_bubble_view.cc deleted file mode 100644 index 8aaed74..0000000 --- a/chrome/browser/ui/views/profiles/profile_reset_bubble_view.cc +++ /dev/null
@@ -1,438 +0,0 @@ -// Copyright 2014 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/views/profiles/profile_reset_bubble_view.h" - -#include "chrome/app/chrome_command_ids.h" -#include "chrome/browser/profile_resetter/profile_reset_global_error.h" -#include "chrome/browser/profile_resetter/resettable_settings_snapshot.h" -#include "chrome/browser/ui/global_error/global_error_service.h" -#include "chrome/browser/ui/global_error/global_error_service_factory.h" -#include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/toolbar/app_menu_button.h" -#include "chrome/browser/ui/views/toolbar/toolbar_view.h" -#include "chrome/common/url_constants.h" -#include "components/google/core/browser/google_util.h" -#include "content/public/browser/page_navigator.h" -#include "content/public/browser/user_metrics.h" -#include "grit/chromium_strings.h" -#include "grit/components_strings.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/gfx/image/image_skia_operations.h" -#include "ui/views/background.h" -#include "ui/views/controls/button/checkbox.h" -#include "ui/views/controls/button/image_button.h" -#include "ui/views/controls/button/label_button.h" -#include "ui/views/controls/label.h" -#include "ui/views/controls/link.h" -#include "ui/views/controls/scroll_view.h" -#include "ui/views/controls/separator.h" -#include "ui/views/layout/grid_layout.h" -#include "ui/views/layout/layout_constants.h" - -using views::GridLayout; - -namespace { - -// Fixed width of the column holding the description label of the bubble. -const int kWidthOfDescriptionText = 370; - -// Margins width for the top rows to compensate for the bottom panel for which -// we don't want any margin. -const int kMarginWidth = 12; -const int kMarginHeight = kMarginWidth; - -// Width of a colum in the FeedbackView. -const int kFeedbackViewColumnWidth = kWidthOfDescriptionText / 2 + kMarginWidth; - -// Width of the column used to disaplay the help button. -const int kHelpButtonColumnWidth = 30; - -// Width of the reporting checkbox column. -const int kReportingCheckboxColumnWidth = - kWidthOfDescriptionText + 2 * kMarginWidth; - -// Full width including all columns. -const int kAllColumnsWidth = - kReportingCheckboxColumnWidth + kHelpButtonColumnWidth; - -// Maximum height of the scrollable feedback view. -const int kMaxFeedbackViewHeight = 450; - -// The vertical padding between two values in the feedback view. -const int kInterFeedbackValuePadding = 4; - -// We subtract 2 to account for the natural button padding, and -// to bring the separation visually in line with the row separation -// height. -const int kButtonPadding = views::kRelatedButtonHSpacing - 2; - -// The color of the background of the sub panel to report current settings. -const SkColor kLightGrayBackgroundColor = 0xFFF5F5F5; - -// This view is used to contain the scrollable contents that are shown the user -// to expose what feedback will be sent back to Google. -class FeedbackView : public views::View { - public: - FeedbackView() {} - - // Setup the layout manager of the Feedback view using the content of the - // |feedback| ListValue which contains a list of key/value pairs stored in - // DictionaryValues. The key is to be displayed right aligned on the left, and - // the value as a left aligned multiline text on the right. - void SetupLayoutManager(const base::ListValue& feedback) { - RemoveAllChildViews(true); - set_background(views::Background::CreateSolidBackground( - kLightGrayBackgroundColor)); - - GridLayout* layout = new GridLayout(this); - SetLayoutManager(layout); - - // We only need a single column set for left/right text and middle margin. - views::ColumnSet* cs = layout->AddColumnSet(0); - cs->AddColumn(GridLayout::FILL, GridLayout::LEADING, 1, - GridLayout::FIXED, kFeedbackViewColumnWidth, 0); - cs->AddPaddingColumn(0, kMarginWidth); - cs->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::FIXED, kFeedbackViewColumnWidth, 0); - for (size_t i = 0; i < feedback.GetSize(); ++i) { - const base::DictionaryValue* dictionary = NULL; - if (!feedback.GetDictionary(i, &dictionary) || !dictionary) - continue; - - base::string16 key; - if (!dictionary->GetString("key", &key)) - continue; - - base::string16 value; - if (!dictionary->GetString("value", &value)) - continue; - - // The key is shown on the left, multi-line (required to allow wrapping in - // case the key name does not fit), and right-aligned. - views::Label* left_text_label = new views::Label(key); - left_text_label->SetMultiLine(true); - left_text_label->SetEnabledColor(SK_ColorGRAY); - left_text_label->SetHorizontalAlignment(gfx::ALIGN_RIGHT); - - // The value is shown on the right, multi-line, left-aligned. - views::Label* right_text_label = new views::Label(value); - right_text_label->SetMultiLine(true); - right_text_label->SetEnabledColor(SK_ColorDKGRAY); - right_text_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); - - layout->StartRow(0, 0); - layout->AddView(left_text_label); - layout->AddView(right_text_label); - layout->AddPaddingRow(0, kInterFeedbackValuePadding); - } - - // We need to set our size to our preferred size because our parent is a - // scroll view and doesn't know which size to set us to. Also since our - // parent scrolls, we are not bound to its size. So our size is based on the - // size computed by the our layout manager, which is what - // SizeToPreferredSize() does. - SizeToPreferredSize(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(FeedbackView); -}; - -} // namespace - -// ProfileResetBubbleView --------------------------------------------------- - -// static -ProfileResetBubbleView* ProfileResetBubbleView::ShowBubble( - const base::WeakPtr<ProfileResetGlobalError>& global_error, - Browser* browser) { - views::View* anchor_view = BrowserView::GetBrowserViewForBrowser(browser) - ->toolbar() - ->app_menu_button(); - ProfileResetBubbleView* reset_bubble = new ProfileResetBubbleView( - global_error, anchor_view, browser, browser->profile()); - views::BubbleDelegateView::CreateBubble(reset_bubble)->Show(); - content::RecordAction(base::UserMetricsAction("SettingsResetBubble.Show")); - return reset_bubble; -} - -ProfileResetBubbleView::~ProfileResetBubbleView() {} - -views::View* ProfileResetBubbleView::GetInitiallyFocusedView() { - return controls_.reset_button; -} - -void ProfileResetBubbleView::WindowClosing() { - if (global_error_) - global_error_->OnBubbleViewDidClose(); -} - -ProfileResetBubbleView::ProfileResetBubbleView( - const base::WeakPtr<ProfileResetGlobalError>& global_error, - views::View* anchor_view, - content::PageNavigator* navigator, - Profile* profile) - : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT), - navigator_(navigator), - profile_(profile), - global_error_(global_error), - resetting_(false), - chose_to_reset_(false), - show_help_pane_(false), - weak_factory_(this) { -} - -void ProfileResetBubbleView::ResetAllChildren() { - controls_.Reset(); - SetLayoutManager(NULL); - RemoveAllChildViews(true); -} - -void ProfileResetBubbleView::Init() { - set_margins(gfx::Insets(kMarginHeight, 0, 0, 0)); - // Start requesting the feedback data. - snapshot_.reset(new ResettableSettingsSnapshot(profile_)); - snapshot_->RequestShortcuts( - base::Bind(&ProfileResetBubbleView::UpdateFeedbackDetails, - weak_factory_.GetWeakPtr())); - SetupLayoutManager(true); -} - -void ProfileResetBubbleView::SetupLayoutManager(bool report_checked) { - ResetAllChildren(); - - base::string16 product_name( - l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME)); - ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); - - // Bubble title label. - views::Label* title_label = new views::Label( - l10n_util::GetStringFUTF16(IDS_RESET_BUBBLE_TITLE, product_name), - rb.GetFontList(ui::ResourceBundle::BoldFont)); - title_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); - - // Description text label. - views::Label* text_label = new views::Label( - l10n_util::GetStringFUTF16(IDS_RESET_BUBBLE_TEXT, product_name)); - text_label->SetMultiLine(true); - text_label->SetLineHeight(20); - text_label->SetEnabledColor(SK_ColorDKGRAY); - text_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); - - // Learn more link. - views::Link* learn_more_link = new views::Link( - l10n_util::GetStringUTF16(IDS_LEARN_MORE)); - learn_more_link->SetHorizontalAlignment(gfx::ALIGN_LEFT); - learn_more_link->set_listener(this); - learn_more_link->SetUnderline(false); - - // Reset button's name is based on |resetting_| state. - int reset_button_string_id = IDS_RESET_PROFILE_SETTINGS_COMMIT_BUTTON; - if (resetting_) - reset_button_string_id = IDS_RESETTING; - controls_.reset_button = new views::LabelButton( - this, l10n_util::GetStringUTF16(reset_button_string_id)); - controls_.reset_button->SetStyle(views::Button::STYLE_BUTTON); - controls_.reset_button->SetIsDefault(true); - controls_.reset_button->SetFontList( - rb.GetFontList(ui::ResourceBundle::BoldFont)); - controls_.reset_button->SetEnabled(!resetting_); - // For the Resetting... text to fit. - gfx::Size reset_button_size = controls_.reset_button->GetPreferredSize(); - reset_button_size.set_width(100); - controls_.reset_button->SetMinSize(reset_button_size); - - // No thanks button. - controls_.no_thanks_button = new views::LabelButton( - this, l10n_util::GetStringUTF16(IDS_NO_THANKS)); - controls_.no_thanks_button->SetStyle(views::Button::STYLE_BUTTON); - controls_.no_thanks_button->SetEnabled(!resetting_); - - // Checkbox for reporting settings or not. - controls_.report_settings_checkbox = new views::Checkbox( - l10n_util::GetStringUTF16(IDS_REPORT_BUBBLE_TEXT)); - controls_.report_settings_checkbox->SetTextColor( - views::Button::STATE_NORMAL, SK_ColorGRAY); - controls_.report_settings_checkbox->SetChecked(report_checked); - controls_.report_settings_checkbox->SetTextMultiLine(true); - controls_.report_settings_checkbox->set_background( - views::Background::CreateSolidBackground(kLightGrayBackgroundColor)); - // Have a smaller margin on the right, to have the |controls_.help_button| - // closer to the edge. - controls_.report_settings_checkbox->SetBorder( - views::Border::CreateSolidSidedBorder(kMarginWidth, - kMarginWidth, - kMarginWidth, - kMarginWidth / 2, - kLightGrayBackgroundColor)); - - // Help button to toggle the bottom panel on or off. - controls_.help_button = new views::ImageButton(this); - const gfx::ImageSkia* help_image = rb.GetImageSkiaNamed(IDR_QUESTION_MARK); - color_utils::HSL hsl_shift = { -1, 0, 0.8 }; - brighter_help_image_ = gfx::ImageSkiaOperations::CreateHSLShiftedImage( - *help_image, hsl_shift); - controls_.help_button->SetImage( - views::Button::STATE_NORMAL, &brighter_help_image_); - controls_.help_button->SetImage(views::Button::STATE_HOVERED, help_image); - controls_.help_button->SetImage(views::Button::STATE_PRESSED, help_image); - controls_.help_button->set_background( - views::Background::CreateSolidBackground(kLightGrayBackgroundColor)); - controls_.help_button->SetImageAlignment(views::ImageButton::ALIGN_CENTER, - views::ImageButton::ALIGN_MIDDLE); - - GridLayout* layout = new GridLayout(this); - SetLayoutManager(layout); - - // Title row. - const int kTitleColumnSetId = 0; - views::ColumnSet* cs = layout->AddColumnSet(kTitleColumnSetId); - cs->AddPaddingColumn(0, kMarginWidth); - cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - cs->AddPaddingColumn(0, kMarginWidth); - - // Text row. - const int kTextColumnSetId = 1; - cs = layout->AddColumnSet(kTextColumnSetId); - cs->AddPaddingColumn(0, kMarginWidth); - cs->AddColumn(GridLayout::FILL, GridLayout::FILL, 0, - GridLayout::FIXED, kWidthOfDescriptionText, 0); - cs->AddPaddingColumn(0, kMarginWidth); - - // Learn more link & buttons row. - const int kButtonsColumnSetId = 2; - cs = layout->AddColumnSet(kButtonsColumnSetId); - cs->AddPaddingColumn(0, kMarginWidth); - cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - cs->AddPaddingColumn(1, views::kRelatedControlHorizontalSpacing); - cs->AddColumn(GridLayout::LEADING, GridLayout::TRAILING, 0, - GridLayout::USE_PREF, 0, 0); - cs->AddPaddingColumn(0, kButtonPadding); - cs->AddColumn(GridLayout::LEADING, GridLayout::TRAILING, 0, - GridLayout::USE_PREF, 0, 0); - cs->AddPaddingColumn(0, kMarginWidth); - - // Separator. - const int kSeparatorColumnSetId = 3; - cs = layout->AddColumnSet(kSeparatorColumnSetId); - cs->AddColumn(GridLayout::FILL, GridLayout::FILL, 0, - GridLayout::FIXED, kAllColumnsWidth, 0); - - // Reporting row. - const int kReportColumnSetId = 4; - cs = layout->AddColumnSet(kReportColumnSetId); - cs->AddColumn(GridLayout::FILL, GridLayout::FILL, 0, - GridLayout::FIXED, kReportingCheckboxColumnWidth, 0); - cs->AddColumn(GridLayout::FILL, GridLayout::FILL, 0, - GridLayout::FIXED, kHelpButtonColumnWidth, 0); - - layout->StartRow(0, kTitleColumnSetId); - layout->AddView(title_label); - layout->AddPaddingRow(0, kMarginHeight); - - layout->StartRow(0, kTextColumnSetId); - layout->AddView(text_label); - layout->AddPaddingRow(0, kMarginHeight); - - layout->StartRow(0, kButtonsColumnSetId); - layout->AddView(learn_more_link); - layout->AddView(controls_.reset_button); - layout->AddView(controls_.no_thanks_button); - layout->AddPaddingRow(0, kMarginHeight); - - layout->StartRow(0, kSeparatorColumnSetId); - layout->AddView(new views::Separator(views::Separator::HORIZONTAL)); - - layout->StartRow(0, kReportColumnSetId); - layout->AddView(controls_.report_settings_checkbox); - layout->AddView(controls_.help_button); - - if (show_help_pane_ && snapshot_) { - // We need a single row to add the scroll view containing the feedback. - const int kReportDetailsColumnSetId = 5; - cs = layout->AddColumnSet(kReportDetailsColumnSetId); - cs->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - - FeedbackView* feedback_view = new FeedbackView(); - scoped_ptr<base::ListValue> feedback_data = - GetReadableFeedbackForSnapshot(profile_, *snapshot_); - feedback_view->SetupLayoutManager(*feedback_data); - - views::ScrollView* scroll_view = new views::ScrollView(); - scroll_view->set_background(views::Background::CreateSolidBackground( - kLightGrayBackgroundColor)); - scroll_view->SetContents(feedback_view); - - layout->StartRow(1, kReportDetailsColumnSetId); - layout->AddView(scroll_view, 1, 1, GridLayout::FILL, - GridLayout::FILL, kAllColumnsWidth, - std::min(feedback_view->height() + kMarginHeight, - kMaxFeedbackViewHeight)); - } - - Layout(); - AddAccelerator(ui::Accelerator(ui::VKEY_RETURN, ui::EF_NONE)); -} - -void ProfileResetBubbleView::ButtonPressed(views::Button* sender, - const ui::Event& event) { - if (sender == controls_.reset_button) { - DCHECK(!resetting_); - content::RecordAction( - base::UserMetricsAction("SettingsResetBubble.Reset")); - - // Remember that the user chose to reset, and that resetting is underway. - chose_to_reset_ = true; - resetting_ = true; - - controls_.reset_button->SetText(l10n_util::GetStringUTF16(IDS_RESETTING)); - controls_.reset_button->SetEnabled(false); - controls_.no_thanks_button->SetEnabled(false); - SchedulePaint(); - - if (global_error_) { - global_error_->OnBubbleViewResetButtonPressed( - controls_.report_settings_checkbox->checked()); - } - } else if (sender == controls_.no_thanks_button) { - DCHECK(!resetting_); - content::RecordAction( - base::UserMetricsAction("SettingsResetBubble.NoThanks")); - - if (global_error_) - global_error_->OnBubbleViewNoThanksButtonPressed(); - GetWidget()->Close(); - return; - } else if (sender == controls_.help_button) { - show_help_pane_ = !show_help_pane_; - - SetupLayoutManager(controls_.report_settings_checkbox->checked()); - SizeToContents(); - } -} - -void ProfileResetBubbleView::LinkClicked(views::Link* source, int flags) { - content::RecordAction( - base::UserMetricsAction("SettingsResetBubble.LearnMore")); - navigator_->OpenURL(content::OpenURLParams( - GURL(chrome::kResetProfileSettingsLearnMoreURL), content::Referrer(), - NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_LINK, false)); -} - -void ProfileResetBubbleView::CloseBubbleView() { - resetting_ = false; - GetWidget()->Close(); -} - -void ProfileResetBubbleView::UpdateFeedbackDetails() { - if (show_help_pane_) - SetupLayoutManager(controls_.report_settings_checkbox->checked()); -}
diff --git a/chrome/browser/ui/views/profiles/profile_reset_bubble_view.h b/chrome/browser/ui/views/profiles/profile_reset_bubble_view.h deleted file mode 100644 index 771822a..0000000 --- a/chrome/browser/ui/views/profiles/profile_reset_bubble_view.h +++ /dev/null
@@ -1,137 +0,0 @@ -// Copyright 2014 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_VIEWS_PROFILES_PROFILE_RESET_BUBBLE_VIEW_H_ -#define CHROME_BROWSER_UI_VIEWS_PROFILES_PROFILE_RESET_BUBBLE_VIEW_H_ - -#include "base/callback.h" -#include "base/memory/scoped_ptr.h" -#include "base/memory/weak_ptr.h" -#include "base/values.h" -#include "chrome/browser/ui/global_error/global_error_bubble_view_base.h" -#include "ui/gfx/image/image_skia.h" -#include "ui/views/bubble/bubble_delegate.h" -#include "ui/views/controls/button/button.h" -#include "ui/views/controls/link_listener.h" - -namespace content { -class PageNavigator; -} - -namespace views { -class Checkbox; -class ImageButton; -class LabelButton; -class Link; -} - -class Browser; -class Profile; -class ProfileResetGlobalError; -class ResettableSettingsSnapshot; - -// ProfileResetBubbleView warns the user that a settings reset might be needed. -// It is intended to be used as the content of a bubble anchored off of the -// Chrome toolbar. -class ProfileResetBubbleView : public views::BubbleDelegateView, - public views::ButtonListener, - public views::LinkListener, - public GlobalErrorBubbleViewBase { - public: - static ProfileResetBubbleView* ShowBubble( - const base::WeakPtr<ProfileResetGlobalError>& global_error, - Browser* browser); - - // views::BubbleDelegateView methods. - views::View* GetInitiallyFocusedView() override; - void Init() override; - - // views::WidgetDelegate method. - void WindowClosing() override; - - // GlobalErrorBubbleViewBase: - void CloseBubbleView() override; - - private: - ProfileResetBubbleView( - const base::WeakPtr<ProfileResetGlobalError>& global_error, - views::View* anchor_view, - content::PageNavigator* navigator, - Profile* profile); - - ~ProfileResetBubbleView() override; - - // Reset all child views members and remove children from view hierarchy. - void ResetAllChildren(); - - // Sets up the layout manager and set the report checkbox to the value passed - // in |report_checked|. - void SetupLayoutManager(bool report_checked); - - // views::ButtonListener method. - void ButtonPressed(views::Button* sender, const ui::Event& event) override; - - // views::LinkListener method. - void LinkClicked(views::Link* source, int event_flags) override; - - // Sets the fully populated feedback data. - void UpdateFeedbackDetails(); - - struct Controls { - Controls() { - Reset(); - } - void Reset() { - reset_button = NULL; - no_thanks_button = NULL; - help_button = NULL; - report_settings_checkbox = NULL; - } - - // Button for the user to confirm a settings reset. - views::LabelButton* reset_button; - - // Button for the user to refuse a settings reset. - views::LabelButton* no_thanks_button; - - // Button for the user to get more info about reporting settings. - views::ImageButton* help_button; - - // Checkbox for the user to choose to report the settings or not. - views::Checkbox* report_settings_checkbox; - } controls_; - - // The snapshot is used to show user feedback information. - scoped_ptr<ResettableSettingsSnapshot> snapshot_; - - // A version of the help image that is brighter. - gfx::ImageSkia brighter_help_image_; - - // Used for opening the learn more link. - content::PageNavigator* navigator_; - - // Used to access profile specific stuff like the global error or readable - // feedback. - Profile* profile_; - - // The GlobalError this Bubble belongs to. - base::WeakPtr<ProfileResetGlobalError> global_error_; - - // Remembers if we are currently resetting or not. - bool resetting_; - - // Remembers if the reset button was hit before closing the bubble. - bool chose_to_reset_; - - // Toggles when the user clicks on the |help_button_| to identify if we should - // show the help pane or not. - bool show_help_pane_; - - // To cancel pending callbacks after destruction. - base::WeakPtrFactory<ProfileResetBubbleView> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(ProfileResetBubbleView); -}; - -#endif // CHROME_BROWSER_UI_VIEWS_PROFILES_PROFILE_RESET_BUBBLE_VIEW_H_
diff --git a/chrome/browser/ui/views/toolbar/app_menu_button.cc b/chrome/browser/ui/views/toolbar/app_menu_button.cc index fe81877..c8f79fb 100644 --- a/chrome/browser/ui/views/toolbar/app_menu_button.cc +++ b/chrome/browser/ui/views/toolbar/app_menu_button.cc
@@ -157,7 +157,7 @@ void AppMenuButton::UpdateIcon() { DCHECK(ui::MaterialDesignController::IsModeMaterial()); - SkColor color = SK_ColorRED; + SkColor color = gfx::kPlaceholderColor; switch (severity_) { case AppMenuIconPainter::SEVERITY_NONE: color = GetThemeProvider()->GetColor(
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 1d69d5f..5b115ff 100644 --- a/chrome/browser/ui/webui/options/reset_profile_settings_handler.cc +++ b/chrome/browser/ui/webui/options/reset_profile_settings_handler.cc
@@ -11,8 +11,6 @@ #include "base/strings/string16.h" #include "base/values.h" #include "chrome/browser/google/google_brand.h" -#include "chrome/browser/profile_resetter/automatic_profile_resetter.h" -#include "chrome/browser/profile_resetter/automatic_profile_resetter_factory.h" #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" @@ -32,9 +30,7 @@ namespace options { -ResetProfileSettingsHandler::ResetProfileSettingsHandler() - : automatic_profile_resetter_(NULL), - has_shown_confirmation_dialog_(false) { +ResetProfileSettingsHandler::ResetProfileSettingsHandler() { google_brand::GetBrand(&brandcode_); } @@ -43,25 +39,12 @@ void ResetProfileSettingsHandler::InitializeHandler() { Profile* profile = Profile::FromWebUI(web_ui()); resetter_.reset(new ProfileResetter(profile)); - automatic_profile_resetter_ = - AutomaticProfileResetterFactory::GetForBrowserContext(profile); } void ResetProfileSettingsHandler::InitializePage() { web_ui()->CallJavascriptFunction( "ResetProfileSettingsOverlay.setResettingState", base::FundamentalValue(resetter_->IsActive())); - if (automatic_profile_resetter_ && - automatic_profile_resetter_->ShouldShowResetBanner()) { - web_ui()->CallJavascriptFunction("ResetProfileSettingsBanner.show"); - } -} - -void ResetProfileSettingsHandler::Uninitialize() { - if (has_shown_confirmation_dialog_ && automatic_profile_resetter_) { - automatic_profile_resetter_->NotifyDidCloseWebUIResetDialog( - false /*performed_reset*/); - } } void ResetProfileSettingsHandler::GetLocalizedValues( @@ -69,8 +52,6 @@ DCHECK(localized_strings); static OptionsStringResource resources[] = { - { "resetProfileSettingsBannerText", - IDS_RESET_PROFILE_SETTINGS_BANNER_TEXT }, { "resetProfileSettingsCommit", IDS_RESET_PROFILE_SETTINGS_COMMIT_BUTTON }, { "resetProfileSettingsExplanation", IDS_RESET_PROFILE_SETTINGS_EXPLANATION }, @@ -131,10 +112,6 @@ web_ui()->RegisterMessageCallback("onHideResetProfileDialog", base::Bind(&ResetProfileSettingsHandler::OnHideResetProfileDialog, base::Unretained(this))); - web_ui()->RegisterMessageCallback("onDismissedResetProfileSettingsBanner", - base::Bind(&ResetProfileSettingsHandler:: - OnDismissedResetProfileSettingsBanner, - base::Unretained(this))); } void ResetProfileSettingsHandler::HandleResetProfileSettings( @@ -166,17 +143,10 @@ setting_snapshot_->Subtract(current_snapshot); std::string report = SerializeSettingsReport(*setting_snapshot_, difference); - bool is_reset_prompt_active = automatic_profile_resetter_ && - automatic_profile_resetter_->IsResetPromptFlowActive(); - SendSettingsFeedback(report, profile, is_reset_prompt_active ? - PROFILE_RESET_PROMPT : PROFILE_RESET_WEBUI); + SendSettingsFeedback(report, profile); } } setting_snapshot_.reset(); - if (automatic_profile_resetter_) { - automatic_profile_resetter_->NotifyDidCloseWebUIResetDialog( - true /*performed_reset*/); - } } void ResetProfileSettingsHandler::OnShowResetProfileDialog( @@ -189,10 +159,6 @@ UpdateFeedbackUI(); } - if (automatic_profile_resetter_) - automatic_profile_resetter_->NotifyDidOpenWebUIResetDialog(); - has_shown_confirmation_dialog_ = true; - if (brandcode_.empty()) return; config_fetcher_.reset(new BrandcodeConfigFetcher( @@ -208,12 +174,6 @@ setting_snapshot_.reset(); } -void ResetProfileSettingsHandler::OnDismissedResetProfileSettingsBanner( - const base::ListValue* args) { - if (automatic_profile_resetter_) - automatic_profile_resetter_->NotifyDidCloseWebUIResetBanner(); -} - void ResetProfileSettingsHandler::OnSettingsFetched() { DCHECK(config_fetcher_); DCHECK(!config_fetcher_->IsActive());
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 e4e3440..5c1bf2d 100644 --- a/chrome/browser/ui/webui/options/reset_profile_settings_handler.h +++ b/chrome/browser/ui/webui/options/reset_profile_settings_handler.h
@@ -17,7 +17,6 @@ class ListValue; } // namespace base -class AutomaticProfileResetter; class BrandcodeConfigFetcher; class ProfileResetter; class ResettableSettingsSnapshot; @@ -37,7 +36,6 @@ void GetLocalizedValues(base::DictionaryValue* localized_strings) override; void InitializeHandler() override; void InitializePage() override; - void Uninitialize() override; // WebUIMessageHandler implementation. void RegisterMessages() override; @@ -55,9 +53,6 @@ // Called when the confirmation box disappears. void OnHideResetProfileDialog(const base::ListValue* value); - // Called when the reset banner is dismissed from the WebUI. - void OnDismissedResetProfileSettingsBanner(const base::ListValue* args); - // Called when BrandcodeConfigFetcher completed fetching settings. void OnSettingsFetched(); @@ -68,14 +63,6 @@ // Sets new values for the feedback area. void UpdateFeedbackUI(); - // Destroyed with the Profile, thus it should outlive us. This will be NULL if - // the underlying profile is off-the-record (e.g. in Guest mode on Chrome OS). - AutomaticProfileResetter* automatic_profile_resetter_; - - // Records whether or not the Profile Reset confirmation dialog was opened at - // least once during the lifetime of the settings page. - bool has_shown_confirmation_dialog_; - scoped_ptr<ProfileResetter> resetter_; scoped_ptr<BrandcodeConfigFetcher> config_fetcher_;
diff --git a/chrome/browser/ui/webui/settings/reset_settings_handler.cc b/chrome/browser/ui/webui/settings/reset_settings_handler.cc index 73a0783e..53b19a9 100644 --- a/chrome/browser/ui/webui/settings/reset_settings_handler.cc +++ b/chrome/browser/ui/webui/settings/reset_settings_handler.cc
@@ -11,8 +11,6 @@ #include "base/strings/string16.h" #include "base/values.h" #include "chrome/browser/google/google_brand.h" -#include "chrome/browser/profile_resetter/automatic_profile_resetter.h" -#include "chrome/browser/profile_resetter/automatic_profile_resetter_factory.h" #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" @@ -49,8 +47,6 @@ google_brand::GetBrand(&brandcode_); Profile* profile = Profile::FromWebUI(web_ui); resetter_.reset(new ProfileResetter(profile)); - automatic_profile_resetter_ = - AutomaticProfileResetterFactory::GetForBrowserContext(profile); #if defined(OS_CHROMEOS) policy::BrowserPolicyConnectorChromeOS* connector = @@ -62,12 +58,7 @@ #endif // defined(OS_CHROMEOS) } -ResetSettingsHandler::~ResetSettingsHandler() { - if (has_shown_confirmation_dialog_ && automatic_profile_resetter_) { - automatic_profile_resetter_->NotifyDidCloseWebUIResetDialog( - false /*performed_reset*/); - } -} +ResetSettingsHandler::~ResetSettingsHandler() {} void ResetSettingsHandler::RegisterMessages() { web_ui()->RegisterMessageCallback("performResetProfileSettings", @@ -120,17 +111,10 @@ setting_snapshot_->Subtract(current_snapshot); std::string report = SerializeSettingsReport(*setting_snapshot_, difference); - bool is_reset_prompt_active = automatic_profile_resetter_ && - automatic_profile_resetter_->IsResetPromptFlowActive(); - SendSettingsFeedback(report, profile, is_reset_prompt_active ? - PROFILE_RESET_PROMPT : PROFILE_RESET_WEBUI); + SendSettingsFeedback(report, profile); } } setting_snapshot_.reset(); - if (automatic_profile_resetter_) { - automatic_profile_resetter_->NotifyDidCloseWebUIResetDialog( - true /*performed_reset*/); - } } void ResetSettingsHandler::OnShowResetProfileDialog( @@ -143,10 +127,6 @@ UpdateFeedbackUI(); } - if (automatic_profile_resetter_) - automatic_profile_resetter_->NotifyDidOpenWebUIResetDialog(); - has_shown_confirmation_dialog_ = true; - if (brandcode_.empty()) return; config_fetcher_.reset(new BrandcodeConfigFetcher(
diff --git a/chrome/browser/ui/webui/settings/reset_settings_handler.h b/chrome/browser/ui/webui/settings/reset_settings_handler.h index 2f615b52..0407947 100644 --- a/chrome/browser/ui/webui/settings/reset_settings_handler.h +++ b/chrome/browser/ui/webui/settings/reset_settings_handler.h
@@ -22,7 +22,6 @@ class WebUIDataSource; } -class AutomaticProfileResetter; class BrandcodeConfigFetcher; class ProfileResetter; class ResettableSettingsSnapshot; @@ -78,14 +77,6 @@ bool allow_powerwash_ = false; #endif // defined(OS_CHROMEOS) - // Destroyed with the Profile, thus it should outlive us. This will be NULL if - // the underlying profile is off-the-record (e.g. in Guest mode on Chrome OS). - AutomaticProfileResetter* automatic_profile_resetter_ = nullptr; - - // Records whether or not the Profile Reset confirmation dialog was opened at - // least once during the lifetime of the settings page. - bool has_shown_confirmation_dialog_ = false; - scoped_ptr<ProfileResetter> resetter_; scoped_ptr<BrandcodeConfigFetcher> config_fetcher_;
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index ffc7bf3..62e9b11 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi
@@ -1253,25 +1253,10 @@ 'browser/process_singleton_posix.cc', 'browser/process_singleton_startup_lock.cc', 'browser/process_singleton_startup_lock.h', - 'browser/profile_resetter/automatic_profile_resetter.cc', - 'browser/profile_resetter/automatic_profile_resetter.h', - 'browser/profile_resetter/automatic_profile_resetter_delegate.cc', - 'browser/profile_resetter/automatic_profile_resetter_delegate.h', - 'browser/profile_resetter/automatic_profile_resetter_factory.cc', - 'browser/profile_resetter/automatic_profile_resetter_factory.h', - 'browser/profile_resetter/automatic_profile_resetter_mementos.cc', - 'browser/profile_resetter/automatic_profile_resetter_mementos.h', 'browser/profile_resetter/brandcode_config_fetcher.cc', 'browser/profile_resetter/brandcode_config_fetcher.h', 'browser/profile_resetter/brandcoded_default_settings.cc', 'browser/profile_resetter/brandcoded_default_settings.h', - 'browser/profile_resetter/jtl_foundation.cc', - 'browser/profile_resetter/jtl_foundation.h', - 'browser/profile_resetter/jtl_instructions.h', - 'browser/profile_resetter/jtl_interpreter.cc', - 'browser/profile_resetter/jtl_interpreter.h', - 'browser/profile_resetter/profile_reset_global_error.cc', - 'browser/profile_resetter/profile_reset_global_error.h', 'browser/profile_resetter/profile_resetter.cc', 'browser/profile_resetter/profile_resetter.h', 'browser/profile_resetter/resettable_settings_snapshot.cc',
diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi index 719f40d..2ed0784 100644 --- a/chrome/chrome_browser_chromeos.gypi +++ b/chrome/chrome_browser_chromeos.gypi
@@ -112,6 +112,8 @@ 'browser/chromeos/display/output_protection_delegate.h', 'browser/chromeos/display/overscan_calibrator.cc', 'browser/chromeos/display/overscan_calibrator.h', + 'browser/chromeos/policy/display_rotation_default_handler.cc', + 'browser/chromeos/policy/display_rotation_default_handler.h', 'browser/chromeos/drive/debug_info_collector.cc', 'browser/chromeos/drive/debug_info_collector.h', 'browser/chromeos/drive/download_handler.cc',
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index 03b508f..fdddd1c9 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi
@@ -2347,8 +2347,6 @@ 'browser/ui/views/profiles/avatar_menu_button.h', 'browser/ui/views/profiles/profile_chooser_view.cc', 'browser/ui/views/profiles/profile_chooser_view.h', - 'browser/ui/views/profiles/profile_reset_bubble_view.cc', - 'browser/ui/views/profiles/profile_reset_bubble_view.h', 'browser/ui/views/profiles/supervised_user_avatar_label.cc', 'browser/ui/views/profiles/supervised_user_avatar_label.h', 'browser/ui/views/profiles/user_manager_view.cc',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 6520a78..c8cd2c92 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi
@@ -790,6 +790,8 @@ 'browser/chromeos/net/network_portal_detector_impl_browsertest.cc', 'browser/chromeos/ownership/fake_owner_settings_service.cc', 'browser/chromeos/ownership/fake_owner_settings_service.h', + 'browser/chromeos/policy/affiliation_test_helper.cc', + 'browser/chromeos/policy/affiliation_test_helper.h', 'browser/chromeos/policy/blocking_login_browsertest.cc', 'browser/chromeos/policy/device_cloud_policy_browsertest.cc', 'browser/chromeos/policy/device_local_account_browsertest.cc', @@ -797,6 +799,7 @@ 'browser/chromeos/policy/device_policy_cros_browser_test.h', 'browser/chromeos/policy/device_status_collector_browsertest.cc', 'browser/chromeos/policy/device_system_use_24hour_clock_browsertest.cc', + 'browser/chromeos/policy/display_rotation_default_handler_browsertest.cc', 'browser/chromeos/policy/force_maximize_on_first_run_chromeos_browsertest.cc', 'browser/chromeos/policy/login_policy_test_base.cc', 'browser/chromeos/policy/login_policy_test_base.h', @@ -804,6 +807,7 @@ 'browser/chromeos/policy/policy_cert_verifier_browsertest.cc', 'browser/chromeos/policy/power_policy_browsertest.cc', 'browser/chromeos/policy/restore_on_startup_browsertest_chromeos.cc', + 'browser/chromeos/policy/user_affiliation_browsertest.cc', 'browser/chromeos/policy/user_cloud_external_data_manager_browsertest.cc', 'browser/chromeos/policy/user_cloud_policy_manager_chromeos_browsertest.cc', 'browser/chromeos/policy/user_policy_test_helper.cc', @@ -3235,7 +3239,7 @@ ], }, { - 'target_name': 'telemetry_perf_unittests', + 'target_name': 'telemetry_perf_unittests_run', 'type': 'none', 'dependencies': [ 'chrome_run', @@ -3249,7 +3253,7 @@ ], }, { - 'target_name': 'telemetry_gpu_unittests', + 'target_name': 'telemetry_gpu_unittests_run', 'type': 'none', 'dependencies': [ '../content/content_shell_and_tests.gyp:telemetry_base',
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index eb28aa8d..8cec80c1 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi
@@ -2680,7 +2680,6 @@ }, { # 'OS!="android" and OS!="ios"' 'dependencies': [ '../components/components.gyp:bubble_test_support', - 'tools/profile_reset/jtl_compiler.gyp:jtl_compiler_lib', ], }], ['OS != "android" and chromeos == 0', {
diff --git a/chrome/common/chrome_constants.cc b/chrome/common/chrome_constants.cc index 49e4009a..ab1c7e3 100644 --- a/chrome/common/chrome_constants.cc +++ b/chrome/common/chrome_constants.cc
@@ -159,8 +159,6 @@ const base::FilePath::CharType kProtectedPreferencesFilenameDeprecated[] = FPL("Protected Preferences"); const base::FilePath::CharType kReadmeFilename[] = FPL("README"); -const base::FilePath::CharType kResetPromptMementoFilename[] = - FPL("Reset Prompt Memento"); const base::FilePath::CharType kSafeBrowsingBaseFilename[] = FPL("Safe Browsing"); const base::FilePath::CharType kSecurePreferencesFilename[] =
diff --git a/chrome/common/chrome_constants.h b/chrome/common/chrome_constants.h index 933a3c3..33b4008 100644 --- a/chrome/common/chrome_constants.h +++ b/chrome/common/chrome_constants.h
@@ -72,7 +72,6 @@ extern const base::FilePath::CharType kPreferencesFilename[]; extern const base::FilePath::CharType kProtectedPreferencesFilenameDeprecated[]; extern const base::FilePath::CharType kReadmeFilename[]; -extern const base::FilePath::CharType kResetPromptMementoFilename[]; extern const base::FilePath::CharType kSafeBrowsingBaseFilename[]; extern const base::FilePath::CharType kSecurePreferencesFilename[]; extern const base::FilePath::CharType kServiceStateFileName[];
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 94952ba..442529f9 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -1121,11 +1121,6 @@ // List pref containing the users supervised by this user. const char kSupervisedUsers[] = "profile.managed_users"; -// String that indicates that the profile reset prompt has already been shown to -// the user (profile). -const char kProfileResetPromptMementoInProfilePrefs[] = - "profile.reset_prompt_memento"; - // List pref containing the extension ids which are not allowed to send // notifications to the message center. const char kMessageCenterDisabledExtensionIds[] = @@ -1246,14 +1241,6 @@ // them. const char kProfileInfoCache[] = "profile.info_cache"; -// Dictionary that maps profile keys to strings that indicate that the profile -// reset prompt has already been shown to the corresponding user (profile). -// This is semantically similar to kProfileResetPromptMementoInProfilePrefs, see -// chrome/browser/profile_resetter/automatic_profile_resetter_mementos.h for an -// explanation of why this redundancy is needed. -const char kProfileResetPromptMementosInLocalState[] = - "profile.reset_prompt_mementos"; - // Boolean that specifies whether or not crash reports are sent // over the network for analysis. #if defined(OS_ANDROID)
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 7c200ed..0f8d51a 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -379,8 +379,6 @@ extern const char kSupervisedUserCreationAllowed[]; extern const char kSupervisedUsers[]; -extern const char kProfileResetPromptMementoInProfilePrefs[]; - extern const char kMessageCenterDisabledExtensionIds[]; extern const char kMessageCenterDisabledSystemComponentIds[]; extern const char kWelcomeNotificationDismissed[]; @@ -430,7 +428,6 @@ extern const char kProfilesNumCreated[]; extern const char kProfileInfoCache[]; extern const char kProfileCreatedByVersion[]; -extern const char kProfileResetPromptMementosInLocalState[]; extern const char kStabilityOtherUserCrashCount[]; extern const char kStabilityKernelCrashCount[];
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index df501b27..85dddc40 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2006,8 +2006,6 @@ "../browser/ui/bookmarks/bookmark_ui_utils_desktop_unittest.cc", "../browser/ui/sync/sync_promo_ui_unittest.cc", ] - } else { - deps += [ "//chrome/tools/profile_reset:jtl_compiler_lib" ] } if (!is_android && !is_chromeos) { sources += rebase_path( @@ -2104,7 +2102,6 @@ "../common/crash_keys.cc", "../common/crash_keys.h", ] - deps = [ ":test_support", "//breakpad:client",
diff --git a/chrome/test/base/test_browser_window.cc b/chrome/test/base/test_browser_window.cc index 41dbb5c..3175183c 100644 --- a/chrome/test/base/test_browser_window.cc +++ b/chrome/test/base/test_browser_window.cc
@@ -177,15 +177,6 @@ return nullptr; } -bool TestBrowserWindow::IsProfileResetBubbleSupported() const { - return false; -} - -GlobalErrorBubbleViewBase* TestBrowserWindow::ShowProfileResetBubble( - const base::WeakPtr<ProfileResetGlobalError>& global_error) { - return nullptr; -} - bool TestBrowserWindow::IsDownloadShelfVisible() const { return false; }
diff --git a/chrome/test/base/test_browser_window.h b/chrome/test/base/test_browser_window.h index 0bce5fac..0e4bfcda 100644 --- a/chrome/test/base/test_browser_window.h +++ b/chrome/test/base/test_browser_window.h
@@ -119,9 +119,6 @@ translate::TranslateStep step, translate::TranslateErrors::Type error_type, bool is_user_gesture) override {} - bool IsProfileResetBubbleSupported() const override; - GlobalErrorBubbleViewBase* ShowProfileResetBubble( - const base::WeakPtr<ProfileResetGlobalError>& global_error) override; #if defined(ENABLE_ONE_CLICK_SIGNIN) void ShowOneClickSigninBubble( OneClickSigninBubbleType type,
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index 7c3fd77..c8aea26 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -2383,6 +2383,12 @@ ] }, + "DisplayRotationDefault": { + "os": ["chromeos"], + "can_be_recommended": false, + "test_policy": { "DisplayRotationDefault": 1 } + }, + "ChromeOsReleaseChannel": { },
diff --git a/chrome/tools/profile_reset/BUILD.gn b/chrome/tools/profile_reset/BUILD.gn deleted file mode 100644 index 1cebad1..0000000 --- a/chrome/tools/profile_reset/BUILD.gn +++ /dev/null
@@ -1,32 +0,0 @@ -# Copyright 2015 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. - -executable("jtl_compiler") { - sources = [ - "//chrome/browser/profile_resetter/jtl_foundation.cc", - "//chrome/browser/profile_resetter/jtl_foundation.h", - "jtl_compiler_frontend.cc", - ] - deps = [ - ":jtl_compiler_lib", - "//base", - "//build/config/sanitizers:deps", - "//crypto", - ] -} - -source_set("jtl_compiler_lib") { - sources = [ - "//chrome/browser/profile_resetter/jtl_foundation.h", - "//chrome/browser/profile_resetter/jtl_instructions.h", - "jtl_compiler.cc", - "jtl_compiler.h", - "jtl_parser.cc", - "jtl_parser.h", - ] - deps = [ - "//base", - "//third_party/re2", - ] -}
diff --git a/chrome/tools/profile_reset/OWNERS b/chrome/tools/profile_reset/OWNERS deleted file mode 100644 index de6863ee..0000000 --- a/chrome/tools/profile_reset/OWNERS +++ /dev/null
@@ -1,3 +0,0 @@ -battre@chromium.org -engedy@chromium.org -
diff --git a/chrome/tools/profile_reset/jtl_compiler.cc b/chrome/tools/profile_reset/jtl_compiler.cc deleted file mode 100644 index ffa5ec2..0000000 --- a/chrome/tools/profile_reset/jtl_compiler.cc +++ /dev/null
@@ -1,252 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/tools/profile_reset/jtl_compiler.h" - -#include <limits> -#include <map> -#include <numeric> - -#include "base/logging.h" -#include "chrome/browser/profile_resetter/jtl_foundation.h" -#include "chrome/tools/profile_reset/jtl_parser.h" - -namespace jtl = jtl_foundation; - -namespace { - -// Serializes symbols into byte-code in a streaming manner. -class ByteCodeWriter { - public: - explicit ByteCodeWriter(std::string* output) : output_(output) {} - ~ByteCodeWriter() {} - - void WriteUint8(uint8 value) { output_->push_back(static_cast<char>(value)); } - void WriteUint32(uint32 value) { - for (int i = 0; i < 4; ++i) { - output_->push_back(static_cast<char>(value & 0xFFu)); - value >>= 8; - } - } - void WriteOpCode(uint8 op_code) { WriteUint8(op_code); } - void WriteHash(const std::string& hash) { - CHECK(jtl::Hasher::IsHash(hash)); - *output_ += hash; - } - void WriteBool(bool value) { WriteUint8(value ? 1u : 0u); } - - private: - std::string* output_; - - DISALLOW_COPY_AND_ASSIGN(ByteCodeWriter); -}; - -// Encapsulates meta-data about all instructions, and is capable of transcoding -// each instruction from a parsed text-based format to byte-code. -class InstructionSet { - public: - InstructionSet() { - // Define each instruction in this list. - // Note: - // - Instructions ending in "hash" will write their 'HashString' arguments - // directly into the byte-code. - // - Instructions ending in "hashed" will first hash their 'String' - // arguments, and will write this hash to the byte-code. - Add(Instruction("go", jtl::NAVIGATE, Arguments(String))); - Add(Instruction("any", jtl::NAVIGATE_ANY, Arguments())); - Add(Instruction("back", jtl::NAVIGATE_BACK, Arguments())); - Add(Instruction("store_bool", jtl::STORE_BOOL, Arguments(String, Bool))); - Add(Instruction("store_hash", - jtl::STORE_HASH, Arguments(String, HashString))); - Add(Instruction("store_hashed", - jtl::STORE_HASH, Arguments(String, String))); - Add(Instruction("store_node_bool", - jtl::STORE_NODE_BOOL, Arguments(String))); - Add(Instruction("store_node_hash", - jtl::STORE_NODE_HASH, Arguments(String))); - Add(Instruction("store_node_registerable_domain_hash", - jtl::STORE_NODE_REGISTERABLE_DOMAIN_HASH, - Arguments(String))); - Add(Instruction("compare_bool", jtl::COMPARE_NODE_BOOL, Arguments(Bool))); - Add(Instruction("compare_hashed", - jtl::COMPARE_NODE_HASH, Arguments(String))); - Add(Instruction("compare_hashed_not", - jtl::COMPARE_NODE_HASH_NOT, Arguments(String))); - Add(Instruction("compare_stored_bool", - jtl::COMPARE_STORED_BOOL, - Arguments(String, Bool, Bool))); - Add(Instruction("compare_stored_hashed", - jtl::COMPARE_STORED_HASH, - Arguments(String, String, String))); - Add(Instruction("compare_to_stored_bool", - jtl::COMPARE_NODE_TO_STORED_BOOL, - Arguments(String))); - Add(Instruction("compare_to_stored_hash", - jtl::COMPARE_NODE_TO_STORED_HASH, - Arguments(String))); - Add(Instruction("compare_substring_hashed", - jtl::COMPARE_NODE_SUBSTRING, - Arguments(StringPattern))); - Add(Instruction("break", jtl::STOP_EXECUTING_SENTENCE, Arguments())); - } - - JtlCompiler::CompileError::ErrorCode TranscodeInstruction( - const std::string& name, - const base::ListValue& arguments, - bool ends_sentence, - const jtl::Hasher& hasher, - ByteCodeWriter* target) const { - if (instruction_map_.count(name) == 0) - return JtlCompiler::CompileError::INVALID_OPERATION_NAME; - const Instruction& instruction(instruction_map_.at(name)); - if (instruction.argument_types.size() != arguments.GetSize()) - return JtlCompiler::CompileError::INVALID_ARGUMENT_COUNT; - target->WriteOpCode(instruction.op_code); - for (size_t i = 0; i < arguments.GetSize(); ++i) { - switch (instruction.argument_types[i]) { - case Bool: { - bool value = false; - if (!arguments.GetBoolean(i, &value)) - return JtlCompiler::CompileError::INVALID_ARGUMENT_TYPE; - target->WriteBool(value); - break; - } - case String: { - std::string value; - if (!arguments.GetString(i, &value)) - return JtlCompiler::CompileError::INVALID_ARGUMENT_TYPE; - target->WriteHash(hasher.GetHash(value)); - break; - } - case StringPattern: { - std::string value; - if (!arguments.GetString(i, &value)) - return JtlCompiler::CompileError::INVALID_ARGUMENT_TYPE; - if (value.empty() || - value.size() > std::numeric_limits<uint32>::max()) - return JtlCompiler::CompileError::INVALID_ARGUMENT_VALUE; - target->WriteHash(hasher.GetHash(value)); - target->WriteUint32(static_cast<uint32>(value.size())); - uint32 pattern_sum = std::accumulate( - value.begin(), value.end(), static_cast<uint32>(0u)); - target->WriteUint32(pattern_sum); - break; - } - case HashString: { - std::string hash_value; - if (!arguments.GetString(i, &hash_value) || - !jtl::Hasher::IsHash(hash_value)) - return JtlCompiler::CompileError::INVALID_ARGUMENT_TYPE; - target->WriteHash(hash_value); - break; - } - default: - NOTREACHED(); - return JtlCompiler::CompileError::INVALID_ARGUMENT_TYPE; - } - } - if (ends_sentence) - target->WriteOpCode(jtl::END_OF_SENTENCE); - return JtlCompiler::CompileError::ERROR_NONE; - } - - private: - // The possible types of an operation's argument. - enum ArgumentType { - None, - Bool, - String, - StringPattern, - HashString - }; - - // Encapsulates meta-data about one instruction. - struct Instruction { - Instruction() : op_code(jtl::END_OF_SENTENCE) {} - Instruction(const char* name, - jtl_foundation::OpCodes op_code, - const std::vector<ArgumentType>& argument_types) - : name(name), op_code(op_code), argument_types(argument_types) {} - - std::string name; - jtl::OpCodes op_code; - std::vector<ArgumentType> argument_types; - }; - - static std::vector<ArgumentType> Arguments(ArgumentType arg1_type = None, - ArgumentType arg2_type = None, - ArgumentType arg3_type = None) { - std::vector<ArgumentType> result; - if (arg1_type != None) - result.push_back(arg1_type); - if (arg2_type != None) - result.push_back(arg2_type); - if (arg3_type != None) - result.push_back(arg3_type); - return result; - } - - void Add(const Instruction& instruction) { - instruction_map_[instruction.name] = instruction; - } - - std::map<std::string, Instruction> instruction_map_; - - DISALLOW_COPY_AND_ASSIGN(InstructionSet); -}; - -} // namespace - -bool JtlCompiler::Compile(const std::string& source_code, - const std::string& hash_seed, - std::string* output_bytecode, - CompileError* error_details) { - DCHECK(output_bytecode); - InstructionSet instruction_set; - ByteCodeWriter bytecode_writer(output_bytecode); - jtl::Hasher hasher(hash_seed); - - std::string compacted_source_code; - std::vector<size_t> newline_indices; - size_t mismatched_quotes_line; - if (!JtlParser::RemoveCommentsAndAllWhitespace(source_code, - &compacted_source_code, - &newline_indices, - &mismatched_quotes_line)) { - if (error_details) { - error_details->context = ""; // No meaningful intra-line context here. - error_details->line_number = mismatched_quotes_line; - error_details->error_code = CompileError::MISMATCHED_DOUBLE_QUOTES; - } - return false; - } - - JtlParser parser(compacted_source_code, newline_indices); - while (!parser.HasFinished()) { - std::string operation_name; - base::ListValue arguments; - bool ends_sentence = false; - if (!parser.ParseNextOperation( - &operation_name, &arguments, &ends_sentence)) { - if (error_details) { - error_details->context = parser.GetLastContext(); - error_details->line_number = parser.GetLastLineNumber(); - error_details->error_code = CompileError::PARSING_ERROR; - } - return false; - } - CompileError::ErrorCode error_code = instruction_set.TranscodeInstruction( - operation_name, arguments, ends_sentence, hasher, &bytecode_writer); - if (error_code != CompileError::ERROR_NONE) { - if (error_details) { - error_details->context = parser.GetLastContext(); - error_details->line_number = parser.GetLastLineNumber(); - error_details->error_code = error_code; - } - return false; - } - } - - return true; -}
diff --git a/chrome/tools/profile_reset/jtl_compiler.gyp b/chrome/tools/profile_reset/jtl_compiler.gyp deleted file mode 100644 index 40dca37..0000000 --- a/chrome/tools/profile_reset/jtl_compiler.gyp +++ /dev/null
@@ -1,40 +0,0 @@ -{ - 'variables': { - 'chromium_code': 1, - }, - 'targets': [ - { - # GN version: //chrome/tools/profile_reset:jtl_compiler - 'target_name': 'jtl_compiler', - 'type': 'executable', - 'dependencies': [ - '../../../base/base.gyp:base', - '../../../crypto/crypto.gyp:crypto', - 'jtl_compiler_lib', - ], - 'sources': [ - '../../browser/profile_resetter/jtl_foundation.cc', - '../../browser/profile_resetter/jtl_foundation.h', - 'jtl_compiler_frontend.cc', - ], - }, - { - # GN version: //chrome/tools/profile_reset:jtl_compiler_lib - 'target_name': 'jtl_compiler_lib', - 'type': 'static_library', - 'product_name': 'jtl_compiler', - 'dependencies': [ - '../../../third_party/re2/re2.gyp:re2', - '../../../base/base.gyp:base', - ], - 'sources': [ - '../../browser/profile_resetter/jtl_foundation.h', - '../../browser/profile_resetter/jtl_instructions.h', - 'jtl_compiler.cc', - 'jtl_compiler.h', - 'jtl_parser.cc', - 'jtl_parser.h', - ], - }, - ], -}
diff --git a/chrome/tools/profile_reset/jtl_compiler.h b/chrome/tools/profile_reset/jtl_compiler.h deleted file mode 100644 index cd81b81f..0000000 --- a/chrome/tools/profile_reset/jtl_compiler.h +++ /dev/null
@@ -1,74 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_TOOLS_PROFILE_RESET_JTL_COMPILER_H_ -#define CHROME_TOOLS_PROFILE_RESET_JTL_COMPILER_H_ - -#include <string> - -#include "base/basictypes.h" - -// Compiles text-based JTL source code into JTL byte-code. -// -// For an overview of JTL (JSON Traversal Language), and the exhaustive list of -// instructions, please see "chrome/browser/profile_resetter/jtl_foundation.h". -// -// The text-based JTL syntax itself much resembles C/C++. A program consists of -// zero or more sentences. Each sentence is terminated by a semi-colon (;), and -// is composed of *one* or more operations, separated by periods (.). -// -// Each operation resembles a C/C++ function call and consists of an instruction -// name, and an optional argument list, which takes Boolean values and/or string -// literals. The text-based instruction names are defined in "jtl_compiler.cc". -// -// Whitespace does not matter, except for inside string literals. C++-style, -// double-slash-introduced comments are also supported. -// -// Example source code: -// -// // Store "x"=true if path "foo.bar" is found. -// go("foo").go("bar").store_bool("x", true); -// -// // Store "y"="1" if the above value is set. -// compare_stored_bool("x", true, false).store_hash("y", "1"); -// -class JtlCompiler { - public: - struct CompileError { - enum ErrorCode { - ERROR_NONE, - MISMATCHED_DOUBLE_QUOTES, - PARSING_ERROR, - INVALID_OPERATION_NAME, - INVALID_ARGUMENT_COUNT, - INVALID_ARGUMENT_TYPE, - INVALID_ARGUMENT_VALUE - }; - - CompileError() : line_number(0), error_code(ERROR_NONE) {} - CompileError(size_t line_number, - const std::string& context, - ErrorCode error_code) - : line_number(line_number), context(context), error_code(error_code) {} - - size_t line_number; // 0-based. - std::string context; - ErrorCode error_code; - }; - - // Compiles text-based JTL source code contained in |source_code| into JTL - // byte-code to |output_bytecode|. Variable, node names, and string literals - // will be hashed using the seed in |hash_seed|. - // On success, returns true. Otherwise, returns false and fills |error| with - // more information (if it is non-NULL). - static bool Compile(const std::string& source_code, - const std::string& hash_seed, - std::string* output_bytecode, - CompileError* error); - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(JtlCompiler); -}; - -#endif // CHROME_TOOLS_PROFILE_RESET_JTL_COMPILER_H_
diff --git a/chrome/tools/profile_reset/jtl_compiler_frontend.cc b/chrome/tools/profile_reset/jtl_compiler_frontend.cc deleted file mode 100644 index 634d3a7c..0000000 --- a/chrome/tools/profile_reset/jtl_compiler_frontend.cc +++ /dev/null
@@ -1,112 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// A simple command-line compiler for JTL (JSON Traversal Language). -// -// Translates rules from a text-based, human-readable format to an easy-to-parse -// byte-code format, which then can be interpreted by JtlInterpreter. -// -// Example usage: -// jtl_compiler --input=blah.txt --hash-seed="foobar" --output=blah.dat - -#include <iostream> -#include <string> - -#include "base/command_line.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "chrome/tools/profile_reset/jtl_compiler.h" - -namespace { - -// Command-line argument name: path to the input text-based JTL source code. -const char kInputPath[] = "input"; - -// Command-line argument name: path to the output byte-code. -const char kOutputPath[] = "output"; - -// Command-line argument name: the hash seed to use. -const char kHashSeed[] = "hash-seed"; - -// Error codes. -const char kMismatchedDoubleQuotes[] = "Mismatched double-quotes before EOL."; -const char kParsingError[] = "Parsing error. Input is ill-formed."; -const char kArgumentCountError[] = "Wrong number of arguments for operation."; -const char kArgumentTypeError[] = "Wrong argument type(s) for operation."; -const char kArgumentValueError[] = "Wrong argument value(s) for operation."; -const char kUnknownOperationError[] = "No operation by this name."; -const char kUnknownError[] = "Unknown error."; - -const char* ResolveErrorCode(JtlCompiler::CompileError::ErrorCode code) { - switch (code) { - case JtlCompiler::CompileError::MISMATCHED_DOUBLE_QUOTES: - return kMismatchedDoubleQuotes; - case JtlCompiler::CompileError::PARSING_ERROR: - return kParsingError; - case JtlCompiler::CompileError::INVALID_ARGUMENT_COUNT: - return kArgumentCountError; - case JtlCompiler::CompileError::INVALID_ARGUMENT_TYPE: - return kArgumentTypeError; - case JtlCompiler::CompileError::INVALID_ARGUMENT_VALUE: - return kArgumentValueError; - case JtlCompiler::CompileError::INVALID_OPERATION_NAME: - return kUnknownOperationError; - default: - return kUnknownError; - } -} - -} // namespace - -int main(int argc, char* argv[]) { - base::CommandLine::Init(argc, argv); - base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); - if (!cmd_line->HasSwitch(kInputPath) || !cmd_line->HasSwitch(kHashSeed) || - !cmd_line->HasSwitch(kOutputPath)) { - std::cerr << "Usage: " << argv[0] << " <required switches>" << std::endl; - std::cerr << "\nRequired switches are:" << std::endl; - std::cerr << " --" << kInputPath << "=<file>" - << "\t\tPath to the input text-based JTL source code." - << std::endl; - std::cerr << " --" << kOutputPath << "=<file>" - << "\t\tPath to the output byte-code." << std::endl; - std::cerr << " --" << kHashSeed << "=<value>" - << "\t\tThe hash seed to use." << std::endl; - return -1; - } - - base::FilePath source_code_path = - MakeAbsoluteFilePath(cmd_line->GetSwitchValuePath(kInputPath)); - std::string source_code; - if (!base::ReadFileToString(source_code_path, &source_code)) { - std::cerr << "ERROR: Cannot read input file." << std::endl; - return -3; - } - - std::string bytecode; - JtlCompiler::CompileError error; - std::string hash_seed = cmd_line->GetSwitchValueASCII(kHashSeed); - if (!JtlCompiler::Compile(source_code, hash_seed, &bytecode, &error)) { - std::cerr << "COMPILE ERROR: " << ResolveErrorCode(error.error_code) - << std::endl; - std::cerr << " Line number: " << (error.line_number + 1) << std::endl; - std::cerr << " Context: " << (error.context.size() > 63 - ? error.context.substr(0, 60) + "..." - : error.context) << std::endl; - return -2; - } - - base::FilePath bytecode_path = - MakeAbsoluteFilePath(cmd_line->GetSwitchValuePath(kOutputPath)); - int bytes_written = - base::WriteFile(cmd_line->GetSwitchValuePath(kOutputPath), - bytecode.data(), - static_cast<int>(bytecode.size())); - if (bytes_written != static_cast<int>(bytecode.size())) { - std::cerr << "ERROR: Cannot write output file." << std::endl; - return -3; - } - - return 0; -}
diff --git a/chrome/tools/profile_reset/jtl_compiler_unittest.cc b/chrome/tools/profile_reset/jtl_compiler_unittest.cc deleted file mode 100644 index c39e59a4..0000000 --- a/chrome/tools/profile_reset/jtl_compiler_unittest.cc +++ /dev/null
@@ -1,218 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/tools/profile_reset/jtl_compiler.h" - -#include <string> - -#include "base/values.h" -#include "chrome/browser/profile_resetter/jtl_foundation.h" -#include "chrome/browser/profile_resetter/jtl_instructions.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace { - -const char kTestHashSeed[] = "test-hash-seed"; - -// Helpers ------------------------------------------------------------------- - -std::string GetHash(const std::string& input) { - return jtl_foundation::Hasher(kTestHashSeed).GetHash(input); -} - -static std::string EncodeUint32(uint32 value) { - std::string bytecode; - for (int i = 0; i < 4; ++i) { - bytecode.push_back(static_cast<char>(value & 0xFFu)); - value >>= 8; - } - return bytecode; -} - -// Tests --------------------------------------------------------------------- - -// Note: Parsing and parsing-related errors are unit-tested separately in more -// detail in "jtl_parser_unittest.cc". Here, most of the time, we assume that -// creating the parse tree works. - -TEST(JtlCompiler, CompileSingleInstructions) { - struct TestCase { - std::string source_code; - std::string expected_bytecode; - } cases[] = { - {"go(\"foo\").", OP_NAVIGATE(GetHash("foo"))}, - {"go(\"has whitespace\t\").", OP_NAVIGATE(GetHash("has whitespace\t"))}, - {"any.", OP_NAVIGATE_ANY}, - {"back.", OP_NAVIGATE_BACK}, - {"store_bool(\"name\", true).", - OP_STORE_BOOL(GetHash("name"), VALUE_TRUE)}, - {"compare_stored_bool(\"name\", true, false).", - OP_COMPARE_STORED_BOOL(GetHash("name"), VALUE_TRUE, VALUE_FALSE)}, - {"store_hash(\"name\", \"" + GetHash("value") + "\").", - OP_STORE_HASH(GetHash("name"), GetHash("value"))}, - {"store_hashed(\"name\", \"value\").", - OP_STORE_HASH(GetHash("name"), GetHash("value"))}, - {"store_node_bool(\"name\").", OP_STORE_NODE_BOOL(GetHash("name"))}, - {"store_node_hash(\"name\").", OP_STORE_NODE_HASH(GetHash("name"))}, - {"store_node_registerable_domain_hash(\"name\").", - OP_STORE_NODE_REGISTERABLE_DOMAIN_HASH(GetHash("name"))}, - {"compare_stored_hashed(\"name\", \"value\", \"default\").", - OP_COMPARE_STORED_HASH( - GetHash("name"), GetHash("value"), GetHash("default"))}, - {"compare_bool(false).", OP_COMPARE_NODE_BOOL(VALUE_FALSE)}, - {"compare_bool(true).", OP_COMPARE_NODE_BOOL(VALUE_TRUE)}, - {"compare_hashed(\"foo\").", OP_COMPARE_NODE_HASH(GetHash("foo"))}, - {"compare_hashed_not(\"foo\").", - OP_COMPARE_NODE_HASH_NOT(GetHash("foo"))}, - {"compare_to_stored_bool(\"name\").", - OP_COMPARE_NODE_TO_STORED_BOOL(GetHash("name"))}, - {"compare_to_stored_hash(\"name\").", - OP_COMPARE_NODE_TO_STORED_HASH(GetHash("name"))}, - {"compare_substring_hashed(\"pattern\").", - OP_COMPARE_NODE_SUBSTRING( - GetHash("pattern"), EncodeUint32(7), EncodeUint32(766))}, - {"break.", OP_STOP_EXECUTING_SENTENCE}, - {"break;", OP_STOP_EXECUTING_SENTENCE + OP_END_OF_SENTENCE}}; - - for (size_t i = 0; i < arraysize(cases); ++i) { - SCOPED_TRACE(cases[i].source_code); - std::string bytecode; - EXPECT_TRUE(JtlCompiler::Compile( - cases[i].source_code, kTestHashSeed, &bytecode, NULL)); - EXPECT_EQ(cases[i].expected_bytecode, bytecode); - } -} - -TEST(JtlCompiler, CompileEntireProgram) { - const char kSourceCode[] = - "// Store \"x\"=true if path is found.\n" - "go(\"foo\").go(\"bar\").store_bool(\"x\", true);\n" - "// ...\n" - "// Store \"y\"=\"1\" if above value is set.\n" - "compare_stored_bool(\"x\", true, false).store_hashed(\"y\", \"1\");\n"; - - std::string expected_bytecode = - OP_NAVIGATE(GetHash("foo")) + - OP_NAVIGATE(GetHash("bar")) + - OP_STORE_BOOL(GetHash("x"), VALUE_TRUE) + OP_END_OF_SENTENCE + - OP_COMPARE_STORED_BOOL(GetHash("x"), VALUE_TRUE, VALUE_FALSE) + - OP_STORE_HASH(GetHash("y"), GetHash("1")) + OP_END_OF_SENTENCE; - - std::string bytecode; - EXPECT_TRUE( - JtlCompiler::Compile(kSourceCode, kTestHashSeed, &bytecode, NULL)); - EXPECT_EQ(expected_bytecode, bytecode); -} - -TEST(JtlCompiler, InvalidOperationName) { - const char kSourceCode[] = "any()\n.\nnon_existent_instruction\n(\n)\n;\n"; - - std::string bytecode; - JtlCompiler::CompileError error; - EXPECT_FALSE( - JtlCompiler::Compile(kSourceCode, kTestHashSeed, &bytecode, &error)); - EXPECT_THAT(error.context, - testing::base::StartsWith("non_existent_instruction")); - EXPECT_EQ(2u, error.line_number); - EXPECT_EQ(JtlCompiler::CompileError::INVALID_OPERATION_NAME, - error.error_code); -} - -TEST(JtlCompiler, InvalidArgumentsCount) { - const char* const kSourceCodes[] = { - "any().\nstore_bool(\"name\", true, \"superfluous argument\");\n", - "any().\nstore_bool(\"name\");"}; // missing argument - - for (size_t i = 0; i < arraysize(kSourceCodes); ++i) { - SCOPED_TRACE(kSourceCodes[i]); - std::string bytecode; - JtlCompiler::CompileError error; - EXPECT_FALSE(JtlCompiler::Compile( - kSourceCodes[i], kTestHashSeed, &bytecode, &error)); - EXPECT_THAT(error.context, testing::base::StartsWith("store_bool")); - EXPECT_EQ(1u, error.line_number); - EXPECT_EQ(JtlCompiler::CompileError::INVALID_ARGUMENT_COUNT, - error.error_code); - } -} - -TEST(JtlCompiler, InvalidArgumentType) { - struct TestCase { - std::string expected_context_prefix; - std::string source_code; - } cases[] = { - {"compare_bool", "any()\n.\ncompare_bool(\"foo\");"}, - {"compare_bool", - "any()\n.\ncompare_bool(\"01234567890123456789012345678901\");"}, - {"compare_hashed", "any()\n.\ncompare_hashed(false);"}, - {"store_hash", "any()\n.\nstore_hash(\"name\", false);"}, - {"store_hash", "any()\n.\nstore_hash(\"name\", \"foo\");"}, - {"compare_stored_bool", - "any()\n.\ncompare_stored_bool(\"name\", \"need a bool\", false);"}, - {"compare_stored_bool", - "any()\n.\ncompare_stored_bool(\"name\", false, \"need a bool\");"}, - {"compare_substring_hashed", - "any()\n.\ncompare_substring_hashed(true);"}}; - - for (size_t i = 0; i < arraysize(cases); ++i) { - SCOPED_TRACE(cases[i].source_code); - std::string bytecode; - JtlCompiler::CompileError error; - EXPECT_FALSE(JtlCompiler::Compile( - cases[i].source_code, kTestHashSeed, &bytecode, &error)); - EXPECT_THAT(error.context, - testing::base::StartsWith(cases[i].expected_context_prefix)); - EXPECT_EQ(2u, error.line_number); - EXPECT_EQ(JtlCompiler::CompileError::INVALID_ARGUMENT_TYPE, - error.error_code); - } -} - -TEST(JtlCompiler, InvalidArgumentValue) { - struct TestCase { - std::string expected_context_prefix; - std::string source_code; - } cases[] = { - {"compare_substring_hashed", "compare_substring_hashed(\"\");"}}; - - for (size_t i = 0; i < arraysize(cases); ++i) { - SCOPED_TRACE(cases[i].source_code); - std::string bytecode; - JtlCompiler::CompileError error; - EXPECT_FALSE(JtlCompiler::Compile( - cases[i].source_code, kTestHashSeed, &bytecode, &error)); - EXPECT_THAT(error.context, - testing::base::StartsWith(cases[i].expected_context_prefix)); - EXPECT_EQ(0u, error.line_number); - EXPECT_EQ(JtlCompiler::CompileError::INVALID_ARGUMENT_VALUE, - error.error_code); - } -} - -TEST(JtlCompiler, MistmatchedDoubleQuotes) { - const char kSourceCode[] = "any().\ngo(\"ok\", \"stray quote).break();"; - - std::string bytecode; - JtlCompiler::CompileError error; - EXPECT_FALSE( - JtlCompiler::Compile(kSourceCode, kTestHashSeed, &bytecode, &error)); - EXPECT_EQ(1u, error.line_number); - EXPECT_EQ(JtlCompiler::CompileError::MISMATCHED_DOUBLE_QUOTES, - error.error_code); -} - -TEST(JtlCompiler, ParsingError) { - const char kSourceCode[] = "any().\ngo()missing_separator();"; - - std::string bytecode; - JtlCompiler::CompileError error; - EXPECT_FALSE( - JtlCompiler::Compile(kSourceCode, kTestHashSeed, &bytecode, &error)); - EXPECT_THAT(error.context, testing::base::StartsWith("go")); - EXPECT_EQ(1u, error.line_number); - EXPECT_EQ(JtlCompiler::CompileError::PARSING_ERROR, error.error_code); -} - -} // namespace
diff --git a/chrome/tools/profile_reset/jtl_parser.cc b/chrome/tools/profile_reset/jtl_parser.cc deleted file mode 100644 index c1d9c157..0000000 --- a/chrome/tools/profile_reset/jtl_parser.cc +++ /dev/null
@@ -1,167 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/tools/profile_reset/jtl_parser.h" - -#include <algorithm> - -#include "base/logging.h" -#include "third_party/re2/re2/re2.h" - -namespace { - -// RegEx that matches the first line of a text. Will throw away any potential -// double-slash-introduced comments and the potential trailing EOL character. -// Note: will fail in case the first line contains an unmatched double-quote -// outside of comments. -const char kSingleLineWithMaybeCommentsRE[] = - // Non-greedily match and capture sequences of 1.) string literals inside - // correctly matched double-quotes, or 2.) any other character. - "^((?:\"[^\"\\n]*\"|[^\"\\n])*?)" - // Greedily match and throw away the potential comment. - "(?://.*)?" - // Match and throw away EOL, or match end-of-string. - "(?:\n|$)"; - -// RegEx to match either a double-quote-enclosed string literal or a whitespace. -// Applied repeatedly and without overlapping, can be used to remove whitespace -// outside of string literals. -const char kRemoveWhitespaceRE[] = "(\"[^\"]*\")|\\s"; - -// The substitution pattern to use together with the above when replacing. As -// the whitespace is not back-referenced here, it will get removed. -const char kRemoveWhitespaceRewrite[] = "\\1"; - -// Separator to terminate a sentence. -const char kEndOfSentenceSeparator[] = ";"; - -// The 'true' Boolean keyword. -const char kTrueKeyword[] = "true"; - -// RegEx that matches and captures one argument, which is either a double-quote -// enclosed string, or a Boolean value. Will throw away a trailing comma. -const char kSingleArgumentRE[] = "(?:(?:\"([^\"]*)\"|(true|false))(?:,|$))"; - -// RegEx-es that, when concatenated, will match a single operation, and capture -// the: operation name, the optional arguments, and the separator that follows. -const char kOperationNameRE[] = "([[:word:]]+)"; -const char kMaybeArgumentListRE[] = - "(?:\\(" // Opening parenthesis. - "((?:\"[^\"]*\"|[^\")])*)" // Capture: anything inside, quote-aware. - "\\))?"; // Closing parenthesis + everything optional. -const char kOperationSeparatorRE[] = "(;|\\.)"; - -} // namespace - -struct JtlParser::ParsingState { - explicit ParsingState(const re2::StringPiece& compacted_source) - : single_operation_regex(std::string(kOperationNameRE) + - kMaybeArgumentListRE + - kOperationSeparatorRE), - single_argument_regex(kSingleArgumentRE), - remaining_compacted_source(compacted_source), - last_line_number(0) {} - - RE2 single_operation_regex; - RE2 single_argument_regex; - re2::StringPiece remaining_compacted_source; - re2::StringPiece last_context; - size_t last_line_number; -}; - -JtlParser::JtlParser(const std::string& compacted_source_code, - const std::vector<size_t>& newline_indices) - : compacted_source_(compacted_source_code), - newline_indices_(newline_indices) { - state_.reset(new ParsingState(compacted_source_)); -} - -JtlParser::~JtlParser() {} - -// static -bool JtlParser::RemoveCommentsAndAllWhitespace( - const std::string& verbose_text, - std::string* compacted_text, - std::vector<size_t>* newline_indices, - size_t* error_line_number) { - DCHECK(compacted_text); - DCHECK(newline_indices); - std::string line; - RE2 single_line_regex(kSingleLineWithMaybeCommentsRE); - RE2 remove_whitespace_regex(kRemoveWhitespaceRE); - re2::StringPiece verbose_text_piece(verbose_text); - compacted_text->clear(); - newline_indices->clear(); - while (!verbose_text_piece.empty()) { - if (!RE2::Consume(&verbose_text_piece, single_line_regex, &line)) { - if (error_line_number) - *error_line_number = newline_indices->size(); - return false; - } - RE2::GlobalReplace( - &line, remove_whitespace_regex, kRemoveWhitespaceRewrite); - *compacted_text += line; - newline_indices->push_back(compacted_text->size()); - } - return true; -} - -bool JtlParser::HasFinished() { - return state_->remaining_compacted_source.empty(); -} - -bool JtlParser::ParseNextOperation(std::string* name, - base::ListValue* argument_list, - bool* ends_sentence) { - DCHECK(name); - DCHECK(argument_list); - DCHECK(ends_sentence); - - state_->last_context = state_->remaining_compacted_source; - state_->last_line_number = GetOriginalLineNumber( - compacted_source_.size() - state_->remaining_compacted_source.length()); - - std::string arguments, separator; - if (!RE2::Consume(&state_->remaining_compacted_source, - state_->single_operation_regex, - name, - &arguments, - &separator)) - return false; - - *ends_sentence = (separator == kEndOfSentenceSeparator); - state_->last_context.remove_suffix(state_->remaining_compacted_source.size()); - - re2::StringPiece arguments_piece(arguments); - std::string string_value, boolean_value; - while (!arguments_piece.empty()) { - if (!RE2::Consume(&arguments_piece, - state_->single_argument_regex, - &string_value, - &boolean_value)) - return false; - - if (!boolean_value.empty()) { - argument_list->Append( - new base::FundamentalValue(boolean_value == kTrueKeyword)); - } else { - // |string_value| might be empty for an empty string - argument_list->Append(new base::StringValue(string_value)); - } - } - return true; -} - -size_t JtlParser::GetOriginalLineNumber(size_t compacted_index) const { - return static_cast<size_t>(std::upper_bound(newline_indices_.begin(), - newline_indices_.end(), - compacted_index) - - newline_indices_.begin()); -} - -size_t JtlParser::GetLastLineNumber() const { return state_->last_line_number; } - -std::string JtlParser::GetLastContext() const { - return state_->last_context.ToString(); -}
diff --git a/chrome/tools/profile_reset/jtl_parser.h b/chrome/tools/profile_reset/jtl_parser.h deleted file mode 100644 index e758211..0000000 --- a/chrome/tools/profile_reset/jtl_parser.h +++ /dev/null
@@ -1,83 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_TOOLS_PROFILE_RESET_JTL_PARSER_H_ -#define CHROME_TOOLS_PROFILE_RESET_JTL_PARSER_H_ - -#include <string> -#include <vector> - -#include "base/basictypes.h" -#include "base/memory/scoped_ptr.h" -#include "base/values.h" - -// Parses text-based JTL source code into a stream of operation names, arguments -// and separator kinds. -class JtlParser { - public: - // Creates a new parser to parse |compacted_source_code|, which should already - // be stripped of all comments and whitespace (except inside string literals). - // Use RemoveCommentsAndAllWhitespace() to manufacture these arguments, also - // see its comments for a description of |newline_indices|. - JtlParser(const std::string& compacted_source_code, - const std::vector<size_t>& newline_indices); - ~JtlParser(); - - // Removes comments from |verbose_text| and compacts it into whitespace-free - // format (except inside string literals). Elements in |newline_indices| will - // be monotonically increasing and will refer to positions in |compacted_text| - // such that a new line has been removed before that position. - // Example: - // verbose_text = "H e l l o // my\n" - // " dear \n" - // "\n" - // "world\" ! \"" - // compacted_text = "Hellodearworld\" ! \"" - // 01234567890123... - // newline_indices = {5, 9, 9} - // Returns true on success, false if there were unmatched quotes in a line, in - // which case |error_line_number| will be set accordingly if it is non-NULL. - static bool RemoveCommentsAndAllWhitespace( - const std::string& verbose_text, - std::string* compacted_text, - std::vector<size_t>* newline_indices, - size_t* error_line_number); - - // Returns true if the entire input has been successfully consumed. Note that - // even when this returns false, a subsequent call to ParseNextOperation() - // might still fail if the next operation cannot be parsed. - bool HasFinished(); - - // Fetches the |name| and the |argument_list| of the next operation, and also - // whether or not it |ends_the_sentence|, i.e. it is followed by the - // end-of-sentence separator. - // Returns false if there is a parsing error, in which case the values for the - // output parameters are undefined, and |this| parser shall no longer be used. - bool ParseNextOperation(std::string* name, - base::ListValue* argument_list, - bool* ends_the_sentence); - - // Returns the compacted source code that was passed in to the constructor. - const std::string& compacted_source() const { return compacted_source_; } - - // Returns at which line the character at position |compacted_index| in the - // |compacted_source()| was originally located. - size_t GetOriginalLineNumber(size_t compacted_index) const; - - size_t GetLastLineNumber() const; - std::string GetLastContext() const; - - private: - // Contains pre-compiled regular expressions and related state. Factored out - // to avoid this header depending on RE2 headers. - struct ParsingState; - - std::string compacted_source_; - std::vector<size_t> newline_indices_; - scoped_ptr<ParsingState> state_; - - DISALLOW_COPY_AND_ASSIGN(JtlParser); -}; - -#endif // CHROME_TOOLS_PROFILE_RESET_JTL_PARSER_H_
diff --git a/chrome/tools/profile_reset/jtl_parser_unittest.cc b/chrome/tools/profile_reset/jtl_parser_unittest.cc deleted file mode 100644 index 87b7ebc5..0000000 --- a/chrome/tools/profile_reset/jtl_parser_unittest.cc +++ /dev/null
@@ -1,346 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/tools/profile_reset/jtl_parser.h" - -#include "base/json/json_writer.h" -#include "base/memory/scoped_ptr.h" -#include "base/values.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace { - -// Helpers ------------------------------------------------------------------- - -void ExpectNextOperation(JtlParser* parser, - const char* expected_name, - const char* expected_args_json, - bool expected_ends_sentence) { - std::string actual_name; - base::ListValue actual_args; - std::string actual_args_json; - bool actual_ends_sentence; - - EXPECT_FALSE(parser->HasFinished()); - EXPECT_TRUE(parser->ParseNextOperation( - &actual_name, &actual_args, &actual_ends_sentence)); - EXPECT_EQ(expected_name, actual_name); - base::JSONWriter::Write(&actual_args, &actual_args_json); - EXPECT_EQ(expected_args_json, actual_args_json); - EXPECT_EQ(expected_ends_sentence, actual_ends_sentence); -} - -void ExpectNextOperationToFail(JtlParser* parser, - size_t expected_line_number, - const char* expected_context_prefix) { - std::string actual_name; - base::ListValue actual_args; - bool actual_ends_sentence; - - EXPECT_FALSE(parser->HasFinished()); - EXPECT_FALSE(parser->ParseNextOperation( - &actual_name, &actual_args, &actual_ends_sentence)); - EXPECT_THAT(parser->GetLastContext(), - testing::base::StartsWith(expected_context_prefix)); - EXPECT_EQ(expected_line_number, parser->GetLastLineNumber()); -} - -JtlParser* CreateParserFromVerboseText(const std::string& verbose_text) { - std::string compacted_source_code; - std::vector<size_t> newline_indices; - EXPECT_TRUE(JtlParser::RemoveCommentsAndAllWhitespace( - verbose_text, &compacted_source_code, &newline_indices, NULL)); - return new JtlParser(compacted_source_code, newline_indices); -} - -// Tests --------------------------------------------------------------------- - -TEST(JtlParser, CompactingEmpty) { - const char kSourceCode[] = ""; - const char kCompactedSourceCode[] = ""; - - scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode)); - EXPECT_EQ(kCompactedSourceCode, parser->compacted_source()); -} - -TEST(JtlParser, CompactingTrivial) { - const char kSourceCode[] = "foo"; - const char kCompactedSourceCode[] = "foo"; - - scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode)); - EXPECT_EQ(kCompactedSourceCode, parser->compacted_source()); -} - -TEST(JtlParser, CompactingOneLine) { - const char kSourceCode[] = " \r f\to o ( true ) "; - const char kCompactedSourceCode[] = "foo(true)"; - - scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode)); - EXPECT_EQ(kCompactedSourceCode, parser->compacted_source()); - for (size_t i = 0; i < arraysize(kCompactedSourceCode) - 1; ++i) { - SCOPED_TRACE(testing::Message("Position ") << i); - EXPECT_EQ(0u, parser->GetOriginalLineNumber(i)); - } -} - -TEST(JtlParser, CompactingMultipleLines) { - const char kSourceCode[] = "a\nbb\n \nccc \n\n d( \n e \n )"; - const char kCompactedSourceCode[] = "abbcccd(e)"; - const size_t kLineNumbers[] = {0u, 1u, 1u, 3u, 3u, 3u, 5u, 5u, 6u, 7u}; - static_assert(arraysize(kCompactedSourceCode) == arraysize(kLineNumbers) + 1, - "mismatched test data"); - - scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode)); - EXPECT_EQ(kCompactedSourceCode, parser->compacted_source()); - for (size_t i = 0; i < arraysize(kLineNumbers); ++i) { - SCOPED_TRACE(testing::Message("Position ") << i); - EXPECT_EQ(kLineNumbers[i], parser->GetOriginalLineNumber(i)); - } -} - -TEST(JtlParser, CompactingMultipleLinesWithComments) { - const char kSourceCode[] = - "a/ /b//Comment \n" - "//\n" - "// Full line comment\n" - " cd //"; - const char kCompactedSourceCode[] = "a//bcd"; - const size_t kLineNumbers[] = {0u, 0u, 0u, 0u, 3u, 3u}; - static_assert(arraysize(kCompactedSourceCode) == arraysize(kLineNumbers) + 1, - "mismatched test data"); - - scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode)); - EXPECT_EQ(kCompactedSourceCode, parser->compacted_source()); - for (size_t i = 0; i < arraysize(kLineNumbers); ++i) { - SCOPED_TRACE(testing::Message("Position ") << i); - EXPECT_EQ(kLineNumbers[i], parser->GetOriginalLineNumber(i)); - } -} - -TEST(JtlParser, HandlingCommentsAndStringLiterals) { - struct TestCase { - const char* source_code; - const char* compacted_source_code; - } cases[] = { - {"//", ""}, - {"//comment", ""}, - {"foo // comment", "foo"}, - {"foo // // comment", "foo"}, - {"foo //", "foo"}, - {"\"literal\"", "\"literal\""}, - {"\"literal with space\"", "\"literal with space\""}, - {"\"\"", "\"\""}, - {"\"\"\"\"", "\"\"\"\""}, - {"\"\" // comment", "\"\""}, - {"\"literal\" // comment", "\"literal\""}, - {"\"literal\" \"literal\" // comment", "\"literal\"\"literal\""}, - {"foo // \"not a literal\"", "foo"}, - {"foo // \"not even matched", "foo"}, - {"foo // \"not a literal\" \"not even matched", "foo"}, - {"\"literal\" // \"not a literal\"", "\"literal\""}, - {"\"literal\" // \"not even matched", "\"literal\""}, - {"\"//not a comment//\"", "\"//not a comment//\""}, - {"\"//not a comment//\" // comment", "\"//not a comment//\""}, - {"// \"//not a literal//\" // comment", ""}, - {"\"literal\" // \"//not a literal//\" // comment", "\"literal\""}, - {"\"//not a comment//\" // \"//not a literal//\" // comment", - "\"//not a comment//\""}, - {"\"literal // \"not a literal nor a comment", - "\"literal // \"notaliteralnoracomment"}, - {"\"literal // \"not a literal nor a comment//\"", - "\"literal // \"notaliteralnoracomment"} - }; - - for (size_t i = 0; i < arraysize(cases); ++i) { - SCOPED_TRACE(cases[i].source_code); - scoped_ptr<JtlParser> parser( - CreateParserFromVerboseText(cases[i].source_code)); - EXPECT_EQ(cases[i].compacted_source_code, parser->compacted_source()); - } -} - -TEST(JtlParser, MismatchedDoubleQuotesBeforeEndOfLine) { - struct TestCase { - const char* source_code; - size_t error_line_number; - } cases[] = { - {"\"", 0}, - {"\"mismatched literal", 0}, - {"\n\"", 1}, - {"\"\n\"", 0}, - {"\"\"\"", 0}, - {"\"\"\n\"", 1}, - {"\"\"\n\"\n\"", 1}, - {"\" // not a comment", 0}, - {"\" // not a comment\n\"", 0}, - {"\"\" // comment\n\"", 1}, - {"\"\"\" // not a comment\n\"", 0}, - {"\"\"\" // \" neither a literal nor a comment\"\n\"", 0}, - {"\"\" // comment\n\"// not a comment", 1}, - {"\" // not a comment\"\n\"// not a comment", 1}, - {"foo(\"bar\");\nfoo(\"mismatched);", 1}, - {"foo(\n\"bar\", \"mismatched);", 1}, - {"foo(\n\"bar\", \"mismatched); //comment", 1}, - {"foo(\n\"bar\", \"mismatched);\ngood(\"bar\")", 1} - }; - - for (size_t i = 0; i < arraysize(cases); ++i) { - SCOPED_TRACE(cases[i].source_code); - std::string compacted_source_code; - std::vector<size_t> newline_indices; - size_t error_line_number; - EXPECT_FALSE(JtlParser::RemoveCommentsAndAllWhitespace( - cases[i].source_code, - &compacted_source_code, - &newline_indices, - &error_line_number)); - EXPECT_EQ(cases[i].error_line_number, error_line_number); - } -} - -TEST(JtlParser, ParsingEmpty) { - const char kSourceCode[] = ""; - - scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode)); - EXPECT_TRUE(parser->HasFinished()); -} - -TEST(JtlParser, ParsingOneWellFormedOperation) { - struct TestCase { - const char* source_code; - const char* expected_name; - const char* expected_args; - const bool expected_ends_sentence; - } cases[] = { - {"foo1;", "foo1", "[]", true}, - {"foo2().", "foo2", "[]", false}, - {"foo3(true);", "foo3", "[true]", true}, - {"foo4(false).", "foo4", "[false]", false}, - {"foo5(\"bar\").", "foo5", "[\"bar\"]", false}, - {"foo6(\" b a r \").", "foo6", "[\" b a r \"]", false}, - {"foo7(true, \"bar\").", "foo7", "[true,\"bar\"]", false}, - {"foo8(\"bar\", false, true);", "foo8", "[\"bar\",false,true]", true}, - {"foo9(\"bar\", \" b a r \");", "foo9", "[\"bar\",\" b a r \"]", true} - }; - - for (size_t i = 0; i < arraysize(cases); ++i) { - SCOPED_TRACE(cases[i].expected_name); - scoped_ptr<JtlParser> parser( - CreateParserFromVerboseText(cases[i].source_code)); - ExpectNextOperation(parser.get(), - cases[i].expected_name, - cases[i].expected_args, - cases[i].expected_ends_sentence); - EXPECT_TRUE(parser->HasFinished()); - } -} - -TEST(JtlParser, ParsingMultipleWellFormedOperations) { - const char kSourceCode[] = - "foo1(true).foo2.foo3(\"bar\");" - "foo4(\"bar\", false);"; - - scoped_ptr<JtlParser> parser(CreateParserFromVerboseText(kSourceCode)); - ExpectNextOperation(parser.get(), "foo1", "[true]", false); - ExpectNextOperation(parser.get(), "foo2", "[]", false); - ExpectNextOperation(parser.get(), "foo3", "[\"bar\"]", true); - ExpectNextOperation(parser.get(), "foo4", "[\"bar\",false]", true); - EXPECT_TRUE(parser->HasFinished()); -} - -TEST(JtlParser, ParsingTrickyStringLiterals) { - struct TestCase { - const char* source_code; - const char* expected_name; - const char* expected_args; - const bool expected_ends_sentence; - } cases[] = { - {"prev().foo1(\"\");next(true);", "foo1", "[\"\"]", true}, - {"prev().foo2(\" \");next(true);", "foo2", "[\" \"]", true}, - {"prev().foo3(\",\",true);next(true);", "foo3", "[\",\",true]", true}, - {"prev().foo4(\")\",true);next(true);", "foo4", "[\")\",true]", true}, - {"prev().foo5(\";\",true);next(true);", "foo5", "[\";\",true]", true}, - {"prev().foo6(\"/\",true).next(true);", "foo6", "[\"/\",true]", false}, - {"prev().foo7(\"//\",true).next(true);", "foo7", "[\"//\",true]", false}, - {"prev().foo8(\".\",true).next(true);", "foo8", "[\".\",true]", false}, - }; - - for (size_t i = 0; i < arraysize(cases); ++i) { - SCOPED_TRACE(cases[i].expected_name); - scoped_ptr<JtlParser> parser( - CreateParserFromVerboseText(cases[i].source_code)); - ExpectNextOperation(parser.get(), "prev", "[]", false); - ExpectNextOperation(parser.get(), - cases[i].expected_name, - cases[i].expected_args, - cases[i].expected_ends_sentence); - ExpectNextOperation(parser.get(), "next", "[true]", true); - EXPECT_TRUE(parser->HasFinished()); - } -} - -TEST(JtlParser, FirstOperationIsIllFormed) { - struct TestCase { - const char* source_code; - const char* operation_name; - } cases[] = { - {";;", ";"}, - {"bad_args1(not a boolean value);", "bad_args1"}, - {"bad_args2(,);", "bad_args2"}, - {"bad_args3(...);", "bad_args3"}, - {"bad_args4(1);", "bad_args4"}, - {"bad_args5(1.2);", "bad_args5"}, - {"bad_args6([\"bar\"]);", "bad_args6"}, - {"bad_args7(False);", "bad_args7"}, - {"bad_args8(True);", "bad_args8"}, - {"bad_quotes1(missing both, true).good();", "bad_quotes1"}, - {"bad_quotes2(true, \"missing one).good(); //\"", "bad_quotes2"}, - {"bad_quotes3(\"too\" \"much\", true).good();", "bad_quotes3"}, - {"bad_missing_separator1", "bad_missing_separator1"}, - {"bad_missing_separator2()good();", "bad_missing_separator2"}, - {"bad_parenthesis1(true.good();", "bad_parenthesis1"}, - {"bad_parenthesis2(true.good());", "bad_parenthesis2"}, - {"bad_parenthesis3).good();", "bad_parenthesis3"} - }; - - for (size_t i = 0; i < arraysize(cases); ++i) { - SCOPED_TRACE(cases[i].operation_name); - scoped_ptr<JtlParser> parser( - CreateParserFromVerboseText(cases[i].source_code)); - ExpectNextOperationToFail(parser.get(), 0, cases[i].operation_name); - } -} - -TEST(JtlParser, SecondOperationIsIllFormed) { - struct TestCase { - const char* source_code; - const char* bad_operation_name; - } cases[] = { - {"\ngood(true,false)\n.bad_args(,);", "bad_args"}, - {"\ngood(true,false)\n.bad_quotes1(missing both, true).good();", - "bad_quotes1"}, - {"\ngood(true,false)\n.bad_quotes2(\"missing one, true).good(); //\"", - "bad_quotes2"}, - {"\ngood(true,false)\n.bad_quotes3(\"too\" \"many\", true).good();", - "bad_quotes3"}, - {"\ngood(true,false)\n.bad_separator1()/good();", "bad_separator1"}, - {"\ngood(true,false)\n.missing_separator1", "missing_separator1"}, - {"\ngood(true,false)\n.missing_separator2()good();", - "missing_separator2"}, - {"\ngood(true,false)\n.bad_parens1(true.good();", "bad_parens1"}, - {"\ngood(true,false)\n.bad_parens2(true.good());", "bad_parens2"}, - {"\ngood(true,false)\n.bad_parens3).good();", "bad_parens3"} - }; - - for (size_t i = 0; i < arraysize(cases); ++i) { - SCOPED_TRACE(cases[i].bad_operation_name); - scoped_ptr<JtlParser> parser( - CreateParserFromVerboseText(cases[i].source_code)); - ExpectNextOperation(parser.get(), "good", "[true,false]", false); - ExpectNextOperationToFail(parser.get(), 2, cases[i].bad_operation_name); - } -} - -} // namespace
diff --git a/chromeos/network/client_cert_resolver.cc b/chromeos/network/client_cert_resolver.cc index a0545c989..3d438d88 100644 --- a/chromeos/network/client_cert_resolver.cc +++ b/chromeos/network/client_cert_resolver.cc
@@ -16,6 +16,7 @@ #include "base/stl_util.h" #include "base/task_runner.h" #include "base/threading/worker_pool.h" +#include "base/time/clock.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/shill_service_client.h" #include "chromeos/network/managed_network_configuration_handler.h" @@ -62,7 +63,8 @@ // Returns true if a private key for certificate |cert| is installed. bool HasPrivateKey(const net::X509Certificate& cert) { - PK11SlotInfo* slot = PK11_KeyForCertExists(cert.os_cert_handle(), NULL, NULL); + PK11SlotInfo* slot = + PK11_KeyForCertExists(cert.os_cert_handle(), nullptr, nullptr); if (!slot) return false; @@ -156,14 +158,15 @@ } std::vector<CertAndIssuer> CreateSortedCertAndIssuerList( - const net::CertificateList& certs) { + const net::CertificateList& certs, + base::Time now) { // Filter all client certs and determines each certificate's issuer, which is // required for the pattern matching. std::vector<CertAndIssuer> client_certs; for (net::CertificateList::const_iterator it = certs.begin(); it != certs.end(); ++it) { const net::X509Certificate& cert = **it; - if (cert.valid_expiry().is_null() || cert.HasExpired() || + if (cert.valid_expiry().is_null() || now > cert.valid_expiry() || !HasPrivateKey(cert) || !CertLoader::IsCertificateHardwareBacked(&cert)) { continue; @@ -180,8 +183,10 @@ // be run on a worker thread. void FindCertificateMatches(const net::CertificateList& certs, std::vector<NetworkAndCertPattern>* networks, + base::Time now, NetworkCertMatches* matches) { - std::vector<CertAndIssuer> client_certs(CreateSortedCertAndIssuerList(certs)); + std::vector<CertAndIssuer> client_certs( + CreateSortedCertAndIssuerList(certs, now)); for (std::vector<NetworkAndCertPattern>::const_iterator it = networks->begin(); @@ -236,10 +241,10 @@ ClientCertResolver::ClientCertResolver() : resolve_task_running_(false), network_properties_changed_(false), - network_state_handler_(NULL), - managed_network_config_handler_(NULL), - weak_ptr_factory_(this) { -} + network_state_handler_(nullptr), + managed_network_config_handler_(nullptr), + testing_clock_(nullptr), + weak_ptr_factory_(this) {} ClientCertResolver::~ClientCertResolver() { if (network_state_handler_) @@ -287,8 +292,8 @@ const CertificatePattern& pattern, base::DictionaryValue* shill_properties) { // Prepare and sort the list of known client certs. - std::vector<CertAndIssuer> client_certs( - CreateSortedCertAndIssuerList(CertLoader::Get()->cert_list())); + std::vector<CertAndIssuer> client_certs(CreateSortedCertAndIssuerList( + CertLoader::Get()->cert_list(), base::Time::Now())); // Search for a certificate matching the pattern. std::vector<CertAndIssuer>::iterator cert_it = std::find_if( @@ -314,6 +319,10 @@ return true; } +void ClientCertResolver::SetClockForTesting(base::Clock* clock) { + testing_clock_ = clock; +} + void ClientCertResolver::NetworkListChanged() { VLOG(2) << "NetworkListChanged."; if (!ClientCertificatesLoaded()) @@ -346,6 +355,14 @@ ResolveNetworks(networks_to_check); } +void ClientCertResolver::NetworkConnectionStateChanged( + const NetworkState* network) { + if (!ClientCertificatesLoaded()) + return; + if (!network->IsConnectedState() && !network->IsConnectingState()) + ResolveNetworks(NetworkStateHandler::NetworkStateList(1, network)); +} + void ClientCertResolver::OnCertificatesLoaded( const net::CertificateList& cert_list, bool initial_load) { @@ -448,13 +465,10 @@ NetworkCertMatches* matches = new NetworkCertMatches; task_runner->PostTaskAndReply( FROM_HERE, - base::Bind(&FindCertificateMatches, - CertLoader::Get()->cert_list(), - base::Owned(networks_to_resolve.release()), - matches), + base::Bind(&FindCertificateMatches, CertLoader::Get()->cert_list(), + base::Owned(networks_to_resolve.release()), Now(), matches), base::Bind(&ClientCertResolver::ConfigureCertificates, - weak_ptr_factory_.GetWeakPtr(), - base::Owned(matches))); + weak_ptr_factory_.GetWeakPtr(), base::Owned(matches))); } void ClientCertResolver::ResolvePendingNetworks() { @@ -512,4 +526,10 @@ FOR_EACH_OBSERVER(Observer, observers_, ResolveRequestCompleted(changed)); } +base::Time ClientCertResolver::Now() const { + if (testing_clock_) + return testing_clock_->Now(); + return base::Time::Now(); +} + } // namespace chromeos
diff --git a/chromeos/network/client_cert_resolver.h b/chromeos/network/client_cert_resolver.h index d94873f..931012b 100644 --- a/chromeos/network/client_cert_resolver.h +++ b/chromeos/network/client_cert_resolver.h
@@ -12,9 +12,9 @@ #include "base/basictypes.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" +#include "base/time/time.h" #include "chromeos/cert_loader.h" #include "chromeos/chromeos_export.h" #include "chromeos/network/client_cert_util.h" @@ -23,6 +23,7 @@ #include "chromeos/network/network_state_handler_observer.h" namespace base { +class Clock; class TaskRunner; } @@ -74,10 +75,16 @@ // |Observer|. bool IsAnyResolveTaskRunning() const; + // Sets the clock for testing. This clock is used when checking the + // certificates for expiration. + void SetClockForTesting(base::Clock* clock); + // Returns true and sets the Shill properties that have to be configured in // |shill_properties| if the certificate pattern |pattern| could be resolved. // Returns false otherwise and sets empty Shill properties to clear the // certificate configuration. + // Note that it uses the global clock when checking the certificates for + // expiration. static bool ResolveCertificatePatternSync( const client_cert::ConfigType client_cert_type, const CertificatePattern& pattern, @@ -86,6 +93,7 @@ private: // NetworkStateHandlerObserver overrides void NetworkListChanged() override; + void NetworkConnectionStateChanged(const NetworkState* network) override; // CertLoader::Observer overrides void OnCertificatesLoaded(const net::CertificateList& cert_list, @@ -110,6 +118,11 @@ // Trigger a ResolveRequestCompleted event on all observers. void NotifyResolveRequestCompleted(); + // Returns Time::Now() unless a mock clock has been installed with + // SetClockForTesting, in which case the time according to that clock is used + // instead. + base::Time Now() const; + base::ObserverList<Observer> observers_; // The set of networks that were checked/resolved in previous passes. These @@ -135,6 +148,9 @@ // TaskRunner for slow tasks. scoped_refptr<base::TaskRunner> slow_task_runner_for_test_; + // Can be set for testing. + base::Clock* testing_clock_; + base::WeakPtrFactory<ClientCertResolver> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(ClientCertResolver);
diff --git a/chromeos/network/client_cert_resolver_unittest.cc b/chromeos/network/client_cert_resolver_unittest.cc index 7f2035b..4006072 100644 --- a/chromeos/network/client_cert_resolver_unittest.cc +++ b/chromeos/network/client_cert_resolver_unittest.cc
@@ -11,8 +11,10 @@ #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/json/json_reader.h" +#include "base/memory/scoped_ptr.h" #include "base/run_loop.h" #include "base/strings/stringprintf.h" +#include "base/test/simple_test_clock.h" #include "base/values.h" #include "chromeos/cert_loader.h" #include "chromeos/dbus/dbus_thread_manager.h" @@ -50,9 +52,9 @@ public: ClientCertResolverTest() : network_properties_changed_count_(0), - service_test_(NULL), - profile_test_(NULL), - cert_loader_(NULL) {} + service_test_(nullptr), + profile_test_(nullptr), + cert_loader_(nullptr) {} ~ClientCertResolverTest() override {} void SetUp() override { @@ -82,6 +84,7 @@ void TearDown() override { client_cert_resolver_->RemoveObserver(this); client_cert_resolver_.reset(); + test_clock_.reset(); managed_config_handler_.reset(); network_config_handler_.reset(); network_profile_handler_.reset(); @@ -138,6 +141,10 @@ managed_config_handler_.reset(new ManagedNetworkConfigurationHandlerImpl()); client_cert_resolver_.reset(new ClientCertResolver()); + test_clock_.reset(new base::SimpleTestClock); + test_clock_->SetNow(base::Time::Now()); + client_cert_resolver_->SetClockForTesting(test_clock_.get()); + network_profile_handler_->Init(); network_config_handler_->Init(network_state_handler_.get(), nullptr /* network_device_handler */); @@ -198,10 +205,10 @@ std::string error; scoped_ptr<base::Value> policy_value = base::JSONReader::ReadAndReturnError( - kTestPolicy, base::JSON_ALLOW_TRAILING_COMMAS, NULL, &error); + kTestPolicy, base::JSON_ALLOW_TRAILING_COMMAS, nullptr, &error); ASSERT_TRUE(policy_value) << error; - base::ListValue* policy = NULL; + base::ListValue* policy = nullptr; ASSERT_TRUE(policy_value->GetAsList(&policy)); managed_config_handler_->SetPolicy( @@ -234,10 +241,10 @@ std::string error; scoped_ptr<base::Value> policy_value = base::JSONReader::ReadAndReturnError( - policy_json, base::JSON_ALLOW_TRAILING_COMMAS, NULL, &error); + policy_json, base::JSON_ALLOW_TRAILING_COMMAS, nullptr, &error); ASSERT_TRUE(policy_value) << error; - base::ListValue* policy = NULL; + base::ListValue* policy = nullptr; ASSERT_TRUE(policy_value->GetAsList(&policy)); managed_config_handler_->SetPolicy( @@ -247,6 +254,11 @@ base::DictionaryValue() /* no global network config */); } + void SetWifiState(const std::string& state) { + ASSERT_TRUE(service_test_->SetServiceProperty( + kWifiStub, shill::kStateProperty, base::StringValue(state))); + } + void GetClientCertProperties(std::string* pkcs11_id) { pkcs11_id->clear(); const base::DictionaryValue* properties = @@ -259,6 +271,7 @@ int network_properties_changed_count_; std::string test_cert_id_; + scoped_ptr<base::SimpleTestClock> test_clock_; scoped_ptr<ClientCertResolver> client_cert_resolver_; private: @@ -365,4 +378,34 @@ EXPECT_EQ(1, network_properties_changed_count_); } +TEST_F(ClientCertResolverTest, ExpiringCertificate) { + SetupTestCerts(true /* import issuer */); + SetupWifi(); + base::RunLoop().RunUntilIdle(); + + SetupNetworkHandlers(); + SetupPolicyMatchingIssuerPEM(); + base::RunLoop().RunUntilIdle(); + + StartCertLoader(); + base::RunLoop().RunUntilIdle(); + + SetWifiState(shill::kStateOnline); + base::RunLoop().RunUntilIdle(); + + // Verify that the resolver positively matched the pattern in the policy with + // the test client cert and configured the network. + std::string pkcs11_id; + GetClientCertProperties(&pkcs11_id); + EXPECT_EQ(test_cert_id_, pkcs11_id); + + // Verify that, after the certificate expired and the network disconnection + // happens, no client certificate was configured. + test_clock_->SetNow(base::Time::Max()); + SetWifiState(shill::kStateOffline); + base::RunLoop().RunUntilIdle(); + GetClientCertProperties(&pkcs11_id); + EXPECT_EQ(std::string(), pkcs11_id); +} + } // namespace chromeos
diff --git a/chromeos/settings/cros_settings_names.cc b/chromeos/settings/cros_settings_names.cc index d9be0eb..f6de5ca 100644 --- a/chromeos/settings/cros_settings_names.cc +++ b/chromeos/settings/cros_settings_names.cc
@@ -175,4 +175,12 @@ // size in bytes. const char kExtensionCacheSize[] = "cros.device.extension_cache_size"; +// An integer pref that sets the display rotation at startup to a certain +// value, overriding the user value: +// 0 = 0 degrees rotation +// 1 = 90 degrees clockwise rotation +// 2 = 180 degrees rotation +// 3 = 270 degrees clockwise rotation +const char kDisplayRotationDefault[] = "cros.display_rotation_default"; + } // namespace chromeos
diff --git a/chromeos/settings/cros_settings_names.h b/chromeos/settings/cros_settings_names.h index c2411518..2045b9e 100644 --- a/chromeos/settings/cros_settings_names.h +++ b/chromeos/settings/cros_settings_names.h
@@ -92,6 +92,8 @@ CHROMEOS_EXPORT extern const char kExtensionCacheSize[]; +CHROMEOS_EXPORT extern const char kDisplayRotationDefault[]; + } // namespace chromeos #endif // CHROMEOS_SETTINGS_CROS_SETTINGS_NAMES_H_
diff --git a/components/BUILD.gn b/components/BUILD.gn index 8da3a158..79e21283 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn
@@ -36,6 +36,9 @@ "//components/device_event_log", "//components/dom_distiller/core", "//components/google/core/browser", + "//components/history/core/browser", + "//components/history/core/common", + "//components/history/core/test", "//components/keyed_service/core", "//components/password_manager/core/browser", "//components/password_manager/core/common", @@ -50,6 +53,8 @@ "//components/pref_registry", "//components/omnibox/browser", "//components/infobars/core", + "//components/translate/core/browser", + "//components/translate/core/common", "//components/version_ui", "//components/os_crypt", ] @@ -92,9 +97,6 @@ "//components/gcm_driver/crypto", "//components/gcm_driver/instance_id", "//components/history/content/browser", - "//components/history/core/browser", - "//components/history/core/common", - "//components/history/core/test", "//components/invalidation/impl", "//components/json_schema", "//components/keyed_service/content", @@ -142,8 +144,6 @@ "//components/translate/content/browser", "//components/translate/content/common", "//components/translate/content/renderer", - "//components/translate/core/browser", - "//components/translate/core/common", "//components/ui/zoom", "//components/update_client", "//components/upload_list", @@ -226,7 +226,9 @@ deps += [ "//components/autofill/ios/browser", "//components/dom_distiller/ios", + "//components/history/ios/browser", "//components/keyed_service/ios", + "//components/translate/ios/browser", "//components/webp_transcode", ] } @@ -337,6 +339,8 @@ "//components/data_usage/core:unit_tests", "//components/dom_distiller/core:unit_tests", "//components/google/core/browser:unit_tests", + "//components/history/core/browser:unit_tests", + "//components/history/core/common:unit_tests", "//components/keyed_service/core:unit_tests", "//components/net_log:unit_tests", "//components/password_manager/core/browser:unit_tests", @@ -353,6 +357,9 @@ "//components/undo:unit_tests", "//components/leveldb_proto:unit_tests", "//components/suggestions:unit_tests", + "//components/translate/core/browser:unit_tests", + "//components/translate/core/common:unit_tests", + "//components/translate/core/language_detection:unit_tests", "//components/omnibox/browser:unit_tests", "//components/os_crypt:unit_tests", ] @@ -400,8 +407,6 @@ "//components/gcm_driver/instance_id:unit_tests", "//components/gcm_driver:unit_tests", "//components/history/content/browser:unit_tests", - "//components/history/core/browser:unit_tests", - "//components/history/core/common:unit_tests", "//components/invalidation/impl:unit_tests", "//components/json_schema:unit_tests", "//components/keyed_service/content:unit_tests", @@ -429,9 +434,6 @@ "//components/sync_bookmarks:unit_tests", "//components/sync_driver:unit_tests", "//components/sync_sessions:unit_tests", - "//components/translate/core/browser:unit_tests", - "//components/translate/core/common:unit_tests", - "//components/translate/core/language_detection:unit_tests", "//components/url_formatter:unit_tests", "//components/url_matcher:unit_tests", "//components/update_client:unit_tests", @@ -504,7 +506,10 @@ ] } } else { - deps += [ "//components/webp_transcode:unit_tests" ] + deps += [ + "//components/translate/ios/browser:unit_tests", + "//components/webp_transcode:unit_tests", + ] } if (toolkit_views) {
diff --git a/components/autofill.gypi b/components/autofill.gypi index 2eb1617..e494a094 100644 --- a/components/autofill.gypi +++ b/components/autofill.gypi
@@ -80,6 +80,7 @@ '../third_party/libjingle/libjingle.gyp:libjingle', '../third_party/libaddressinput/libaddressinput.gyp:libaddressinput_util', '../third_party/libphonenumber/libphonenumber.gyp:libphonenumber', + '../third_party/re2/re2.gyp:re2', '../ui/base/ui_base.gyp:ui_base', '../ui/gfx/gfx.gyp:gfx', '../ui/gfx/gfx.gyp:gfx_geometry',
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc index 845e52c..4247b5f1 100644 --- a/components/autofill/content/renderer/password_autofill_agent.cc +++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -1348,7 +1348,7 @@ void PasswordAutofillAgent::OnAutofillUsernameAndPasswordDataReceived( const FormsPredictionsMap& predictions) { - form_predictions_ = predictions; + form_predictions_.insert(predictions.begin(), predictions.end()); } void PasswordAutofillAgent::OnFindFocusedPasswordForm() {
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn index d946f1e..73c5cb3 100644 --- a/components/autofill/core/browser/BUILD.gn +++ b/components/autofill/core/browser/BUILD.gn
@@ -157,6 +157,7 @@ "//base", "//base:i18n", "//base:prefs", + "//third_party/re2", "//components/autofill/core/common", "//components/compression", "//components/data_use_measurement/core",
diff --git a/components/autofill/core/browser/DEPS b/components/autofill/core/browser/DEPS index 1aaa249..164b1d9a 100644 --- a/components/autofill/core/browser/DEPS +++ b/components/autofill/core/browser/DEPS
@@ -19,6 +19,7 @@ "+third_party/webrtc/libjingle", "+third_party/libaddressinput", # For address i18n. "+third_party/libphonenumber", # For phone number i18n. + "+third_party/re2", "+ui/base", "+ui/gfx", ]
diff --git a/components/autofill/core/browser/autofill_download_manager.cc b/components/autofill/core/browser/autofill_download_manager.cc index 4f2a391..7676d1e 100644 --- a/components/autofill/core/browser/autofill_download_manager.cc +++ b/components/autofill/core/browser/autofill_download_manager.cc
@@ -65,6 +65,7 @@ struct AutofillDownloadManager::FormRequestData { std::vector<std::string> form_signatures; + std::vector<FormStructure*> queried_forms; RequestType request_type; }; @@ -107,6 +108,7 @@ std::string form_xml; FormRequestData request_data; if (!FormStructure::EncodeQueryRequest(forms, &request_data.form_signatures, + &request_data.queried_forms, &form_xml)) { return false; } @@ -119,7 +121,8 @@ VLOG(1) << "AutofillDownloadManager: query request has been retrieved " << "from the cache, form signatures: " << GetCombinedSignature(request_data.form_signatures); - observer_->OnLoadedServerPredictions(query_data); + observer_->OnLoadedServerPredictions(query_data, + request_data.queried_forms); return true; } @@ -341,7 +344,8 @@ << " request has succeeded with response body: " << response_body; if (it->second.request_type == AutofillDownloadManager::REQUEST_QUERY) { CacheQueryRequest(it->second.form_signatures, response_body); - observer_->OnLoadedServerPredictions(response_body); + observer_->OnLoadedServerPredictions(response_body, + it->second.queried_forms); } else { double new_positive_upload_rate = 0; double new_negative_upload_rate = 0;
diff --git a/components/autofill/core/browser/autofill_download_manager.h b/components/autofill/core/browser/autofill_download_manager.h index e1c8b9ff..86d9a55 100644 --- a/components/autofill/core/browser/autofill_download_manager.h +++ b/components/autofill/core/browser/autofill_download_manager.h
@@ -38,8 +38,11 @@ class Observer { public: // Called when field type predictions are successfully received from the - // server. |response_xml| contains the server response. - virtual void OnLoadedServerPredictions(const std::string& response_xml) = 0; + // server. |response_xml| contains the server response for the + // |queried_forms|. + virtual void OnLoadedServerPredictions( + const std::string& response_xml, + const std::vector<FormStructure*>& queried_forms) = 0; // These notifications are used to help with testing. // Called when heuristic either successfully considered for upload and
diff --git a/components/autofill/core/browser/autofill_download_manager_unittest.cc b/components/autofill/core/browser/autofill_download_manager_unittest.cc index 042aba1..8562863c 100644 --- a/components/autofill/core/browser/autofill_download_manager_unittest.cc +++ b/components/autofill/core/browser/autofill_download_manager_unittest.cc
@@ -80,7 +80,9 @@ } // AutofillDownloadManager::Observer implementation. - void OnLoadedServerPredictions(const std::string& response_xml) override { + void OnLoadedServerPredictions( + const std::string& response_xml, + const std::vector<FormStructure*>& queried_forms) override { ResponseData response; response.response = response_xml; response.type_of_response = QUERY_SUCCESSFULL;
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc index 3dd5d07f..031691e 100644 --- a/components/autofill/core/browser/autofill_manager.cc +++ b/components/autofill/core/browser/autofill_manager.cc
@@ -741,17 +741,18 @@ } void AutofillManager::OnLoadedServerPredictions( - const std::string& response_xml) { + const std::string& response_xml, + const std::vector<FormStructure*>& queried_forms) { // Parse and store the server predictions. - FormStructure::ParseQueryResponse(response_xml, form_structures_.get(), + FormStructure::ParseQueryResponse(response_xml, queried_forms, client_->GetRapporService()); // Forward form structures to the password generation manager to detect // account creation forms. - driver_->PropagateAutofillPredictions(form_structures_.get()); + driver_->PropagateAutofillPredictions(queried_forms); // If the corresponding flag is set, annotate forms with the predicted types. - driver_->SendAutofillTypePredictionsToRenderer(form_structures_.get()); + driver_->SendAutofillTypePredictionsToRenderer(queried_forms); } void AutofillManager::OnUnmaskResponse(const UnmaskResponse& response) {
diff --git a/components/autofill/core/browser/autofill_manager.h b/components/autofill/core/browser/autofill_manager.h index 56dfad4..f1ab96d89 100644 --- a/components/autofill/core/browser/autofill_manager.h +++ b/components/autofill/core/browser/autofill_manager.h
@@ -246,7 +246,9 @@ private: // AutofillDownloadManager::Observer: - void OnLoadedServerPredictions(const std::string& response_xml) override; + void OnLoadedServerPredictions( + const std::string& response_xml, + const std::vector<FormStructure*>& queried_forms) override; // CardUnmaskDelegate: void OnUnmaskResponse(const UnmaskResponse& response) override;
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc index 590abf4..16a6c34 100644 --- a/components/autofill/core/browser/form_structure.cc +++ b/components/autofill/core/browser/form_structure.cc
@@ -31,7 +31,7 @@ #include "components/autofill/core/common/form_field_data_predictions.h" #include "components/rappor/rappor_service.h" #include "components/rappor/rappor_utils.h" -#include "third_party/icu/source/i18n/unicode/regex.h" +#include "third_party/re2/re2/re2.h" #include "third_party/webrtc/libjingle/xmllite/xmlelement.h" namespace autofill { @@ -65,7 +65,7 @@ const char kShippingMode[] = "shipping"; // Strip away >= 5 consecutive digits. -const char kIgnorePatternInFieldName[] = "\\d{5,}+"; +const char kIgnorePatternInFieldName[] = "\\d{5,}"; // A form is considered to have a high prediction mismatch rate if the number of // mismatches exceeds this threshold. @@ -356,28 +356,10 @@ } std::string StripDigitsIfRequired(const base::string16& input) { - UErrorCode status = U_ZERO_ERROR; - CR_DEFINE_STATIC_LOCAL(icu::UnicodeString, icu_pattern, - (kIgnorePatternInFieldName)); - CR_DEFINE_STATIC_LOCAL(icu::RegexMatcher, matcher, - (icu_pattern, UREGEX_CASE_INSENSITIVE, status)); - DCHECK_EQ(status, U_ZERO_ERROR); + std::string return_string = base::UTF16ToUTF8(input); - icu::UnicodeString icu_input(input.data(), input.length()); - matcher.reset(icu_input); - - icu::UnicodeString replaced_string = matcher.replaceAll("", status); - - std::string return_string; - status = U_ZERO_ERROR; - base::UTF16ToUTF8(replaced_string.getBuffer(), - static_cast<size_t>(replaced_string.length()), - &return_string); - if (status != U_ZERO_ERROR) { - DVLOG(1) << "Couldn't strip digits in " << base::UTF16ToUTF8(input); - return base::UTF16ToUTF8(input); - } - + re2::RE2::GlobalReplace(&return_string, re2::RE2(kIgnorePatternInFieldName), + std::string()); return return_string; } @@ -535,12 +517,15 @@ bool FormStructure::EncodeQueryRequest( const std::vector<FormStructure*>& forms, std::vector<std::string>* encoded_signatures, + std::vector<FormStructure*>* queried_forms, std::string* encoded_xml) { DCHECK(encoded_signatures); DCHECK(encoded_xml); encoded_xml->clear(); encoded_signatures->clear(); encoded_signatures->reserve(forms.size()); + queried_forms->clear(); + queried_forms->reserve(forms.size()); // Set up the <autofillquery> element and attributes. buzz::XmlElement autofill_request_xml( @@ -568,6 +553,7 @@ autofill_request_xml.AddElement(encompassing_xml_element.release()); encoded_signatures->push_back(signature); + queried_forms->push_back(it); } if (!encoded_signatures->size())
diff --git a/components/autofill/core/browser/form_structure.h b/components/autofill/core/browser/form_structure.h index 786485e..14cdd1da 100644 --- a/components/autofill/core/browser/form_structure.h +++ b/components/autofill/core/browser/form_structure.h
@@ -69,13 +69,17 @@ bool EncodeFieldAssignments(const ServerFieldTypeSet& available_field_types, std::string* encoded_xml) const; - // Encodes the XML query request for the set of forms. - // All fields are returned in one XML. For example, there are three forms, + // Encodes the XML query request for the set of |forms| that are valid (see + // implementation for details on which forms are not included in the query). + // The forms and form signatures used in the Query request are output in + // |queried_forms| and |encoded_signatures|, respectively. All valid fields + // are encoded in |encoded_xml|. For example, there are three valid forms, // with 2, 4, and 3 fields. The returned XML would have type info for 9 // fields, first two of which would be for the first form, next 4 for the // second, and the rest is for the third. static bool EncodeQueryRequest(const std::vector<FormStructure*>& forms, std::vector<std::string>* encoded_signatures, + std::vector<FormStructure*>* queried_forms, std::string* encoded_xml); // Parses the field types from the server query response. |forms| must be the
diff --git a/components/autofill/core/browser/form_structure_unittest.cc b/components/autofill/core/browser/form_structure_unittest.cc index 5a0cb53..2b63178d 100644 --- a/components/autofill/core/browser/form_structure_unittest.cc +++ b/components/autofill/core/browser/form_structure_unittest.cc
@@ -1483,6 +1483,7 @@ ScopedVector<FormStructure> forms; forms.push_back(new FormStructure(form)); std::vector<std::string> encoded_signatures; + std::vector<FormStructure*> queried_forms; std::string encoded_xml; const char kSignature1[] = "11337937696949187602"; const char kResponse1[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" @@ -1496,21 +1497,22 @@ " name=\"expiration_month\" type=\"text\" label=\"Expiration Date\"/>" "<field signature=\"4108155786\" name=\"expiration_year\" type=\"text\"" " label=\"Expiration Year\"/></form></autofillquery>"; - ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(), - &encoded_signatures, - &encoded_xml)); + ASSERT_TRUE(FormStructure::EncodeQueryRequest( + forms.get(), &encoded_signatures, &queried_forms, &encoded_xml)); ASSERT_EQ(1U, encoded_signatures.size()); EXPECT_EQ(kSignature1, encoded_signatures[0]); + EXPECT_EQ(forms[0], queried_forms[0]); EXPECT_EQ(kResponse1, encoded_xml); // Add the same form, only one will be encoded, so EncodeQueryRequest() should // return the same data. forms.push_back(new FormStructure(form)); - ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(), - &encoded_signatures, - &encoded_xml)); + ASSERT_TRUE(FormStructure::EncodeQueryRequest( + forms.get(), &encoded_signatures, &queried_forms, &encoded_xml)); ASSERT_EQ(1U, encoded_signatures.size()); EXPECT_EQ(kSignature1, encoded_signatures[0]); + ASSERT_EQ(1U, queried_forms.size()); + EXPECT_EQ(forms[0], queried_forms[0]); EXPECT_EQ(kResponse1, encoded_xml); // Add 5 address fields - this should be still a valid form. for (size_t i = 0; i < 5; ++i) { @@ -1520,9 +1522,8 @@ } forms.push_back(new FormStructure(form)); - ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(), - &encoded_signatures, - &encoded_xml)); + ASSERT_TRUE(FormStructure::EncodeQueryRequest( + forms.get(), &encoded_signatures, &queried_forms, &encoded_xml)); ASSERT_EQ(2U, encoded_signatures.size()); EXPECT_EQ(kSignature1, encoded_signatures[0]); const char kSignature2[] = "8308881815906226214"; @@ -1565,21 +1566,23 @@ } forms.push_back(new FormStructure(malformed_form)); - ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(), - &encoded_signatures, - &encoded_xml)); + ASSERT_TRUE(FormStructure::EncodeQueryRequest( + forms.get(), &encoded_signatures, &queried_forms, &encoded_xml)); ASSERT_EQ(2U, encoded_signatures.size()); EXPECT_EQ(kSignature1, encoded_signatures[0]); EXPECT_EQ(kSignature2, encoded_signatures[1]); + ASSERT_EQ(2U, queried_forms.size()); + EXPECT_EQ(forms[0], queried_forms[0]); + EXPECT_EQ(forms[2], queried_forms[1]); EXPECT_EQ(kResponse2, encoded_xml); // Check that we fail if there are only bad form(s). ScopedVector<FormStructure> bad_forms; bad_forms.push_back(new FormStructure(malformed_form)); - EXPECT_FALSE(FormStructure::EncodeQueryRequest(bad_forms.get(), - &encoded_signatures, - &encoded_xml)); + EXPECT_FALSE(FormStructure::EncodeQueryRequest( + bad_forms.get(), &encoded_signatures, &queried_forms, &encoded_xml)); EXPECT_EQ(0U, encoded_signatures.size()); + EXPECT_EQ(0U, queried_forms.size()); EXPECT_EQ("", encoded_xml); } @@ -2766,6 +2769,7 @@ ScopedVector<FormStructure> forms; forms.push_back(new FormStructure(form)); std::vector<std::string> encoded_signatures; + std::vector<FormStructure*> queried_forms; std::string encoded_xml; const char kSignature[] = "18006745212084723782"; @@ -2776,11 +2780,11 @@ " label=\"username\"/>" "<field signature=\"420638584\" name=\"email\" type=\"text\"/>" "</form></autofillquery>"; - ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(), - &encoded_signatures, - &encoded_xml)); + ASSERT_TRUE(FormStructure::EncodeQueryRequest( + forms.get(), &encoded_signatures, &queried_forms, &encoded_xml)); ASSERT_EQ(1U, encoded_signatures.size()); EXPECT_EQ(kSignature, encoded_signatures[0]); + EXPECT_EQ(forms[0], queried_forms[0]); EXPECT_EQ(kResponse, encoded_xml); } @@ -2809,6 +2813,7 @@ ScopedVector<FormStructure> forms; forms.push_back(new FormStructure(form)); std::vector<std::string> encoded_signatures; + std::vector<FormStructure*> queried_forms; std::string encoded_xml; const char kRequest[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" @@ -2819,9 +2824,8 @@ " label=\"Enter your Email address\"/>" "<field signature=\"2051817934\" name=\"password\" type=\"password\"" " label=\"Enter your Password\"/></form></autofillquery>"; - EXPECT_TRUE(FormStructure::EncodeQueryRequest(forms.get(), - &encoded_signatures, - &encoded_xml)); + EXPECT_TRUE(FormStructure::EncodeQueryRequest( + forms.get(), &encoded_signatures, &queried_forms, &encoded_xml)); EXPECT_EQ(kRequest, encoded_xml); } @@ -2855,6 +2859,7 @@ ScopedVector<FormStructure> forms; forms.push_back(new FormStructure(form)); std::vector<std::string> encoded_signatures; + std::vector<FormStructure*> queried_forms; std::string encoded_xml; const char kRequest[] = @@ -2870,7 +2875,7 @@ "<field signature=\"2051817934\" name=\"password\" type=\"password\"" " label=\"Enter your Password\"/></form></autofillquery>"; EXPECT_TRUE(FormStructure::EncodeQueryRequest( - forms.get(), &encoded_signatures, &encoded_xml)); + forms.get(), &encoded_signatures, &queried_forms, &encoded_xml)); EXPECT_EQ(kRequest, encoded_xml); } @@ -2897,6 +2902,7 @@ ScopedVector<FormStructure> forms; forms.push_back(new FormStructure(form)); std::vector<std::string> encoded_signatures; + std::vector<FormStructure*> queried_forms; std::string encoded_xml; const char kSignature[] = "16416961345885087496"; @@ -2906,11 +2912,11 @@ "<field signature=\"239111655\" name=\"username\" type=\"text\"" " label=\"username\"/><field signature=\"1318412689\" type=\"text\"/>" "</form></autofillquery>"; - ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(), - &encoded_signatures, - &encoded_xml)); + ASSERT_TRUE(FormStructure::EncodeQueryRequest( + forms.get(), &encoded_signatures, &queried_forms, &encoded_xml)); ASSERT_EQ(1U, encoded_signatures.size()); EXPECT_EQ(kSignature, encoded_signatures[0]); + EXPECT_EQ(forms[0], queried_forms[0]); EXPECT_EQ(kResponse, encoded_xml); } @@ -2938,6 +2944,7 @@ ScopedVector<FormStructure> forms; forms.push_back(new FormStructure(form)); std::vector<std::string> encoded_signatures; + std::vector<FormStructure*> queried_forms; std::string encoded_xml; const char kSignature[] = "7635954436925888745"; @@ -2947,11 +2954,11 @@ "<field signature=\"239111655\"/>" "<field signature=\"3654076265\"/>" "</form></autofillquery>"; - ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(), - &encoded_signatures, - &encoded_xml)); + ASSERT_TRUE(FormStructure::EncodeQueryRequest( + forms.get(), &encoded_signatures, &queried_forms, &encoded_xml)); ASSERT_EQ(1U, encoded_signatures.size()); EXPECT_EQ(kSignature, encoded_signatures[0]); + EXPECT_EQ(forms[0], queried_forms[0]); EXPECT_EQ(kResponse, encoded_xml); }
diff --git a/components/components_tests.gyp b/components/components_tests.gyp index c93831b..fd49988 100644 --- a/components/components_tests.gyp +++ b/components/components_tests.gyp
@@ -732,7 +732,6 @@ 'translate/core/common/translate_metrics_unittest.cc', 'translate/core/common/translate_util_unittest.cc', 'translate/core/language_detection/language_detection_util_unittest.cc', - # TODO(GYP) bug 523060: these translate tests on iOS. 'translate/ios/browser/js_translate_manager_unittest.mm', 'translate/ios/browser/language_detection_controller_unittest.mm', 'translate/ios/browser/translate_controller_unittest.mm',
diff --git a/components/constrained_window/constrained_window_views.cc b/components/constrained_window/constrained_window_views.cc index 5ae6cd77..3bf1dfc3 100644 --- a/components/constrained_window/constrained_window_views.cc +++ b/components/constrained_window/constrained_window_views.cc
@@ -6,6 +6,7 @@ #include <algorithm> +#include "base/debug/alias.h" #include "components/constrained_window/constrained_window_views_client.h" #include "components/guest_view/browser/guest_view_base.h" #include "components/web_modal/web_contents_modal_dialog_host.h" @@ -146,6 +147,12 @@ views::Widget* CreateWebModalDialogViews(views::WidgetDelegate* dialog, content::WebContents* web_contents) { + // Temporary to track down http://crbug.com/538612 + content::WebContentsDelegate* delegate = web_contents->GetDelegate(); + base::debug::Alias(delegate); + CHECK( + web_modal::WebContentsModalDialogManager::FromWebContents(web_contents)); + DCHECK_EQ(ui::MODAL_TYPE_CHILD, dialog->GetModalType()); return views::DialogDelegate::CreateDialogWidget( dialog, nullptr,
diff --git a/components/history.gypi b/components/history.gypi index 16f1029..1252f59 100644 --- a/components/history.gypi +++ b/components/history.gypi
@@ -243,6 +243,7 @@ ['OS=="ios"', { 'targets': [ { + # GN version: //components/history/ios/browser 'target_name': 'history_ios_browser', 'type': 'static_library', 'include_dirs': [
diff --git a/components/history/ios/browser/BUILD.gn b/components/history/ios/browser/BUILD.gn new file mode 100644 index 0000000..960d778 --- /dev/null +++ b/components/history/ios/browser/BUILD.gn
@@ -0,0 +1,19 @@ +# Copyright 2015 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. + +source_set("browser") { + sources = [ + "history_database_helper.cc", + "history_database_helper.h", + "web_state_top_sites_observer.cc", + "web_state_top_sites_observer.h", + ] + + deps = [ + "//base", + "//components/history/core/browser", + "//ios/web", + "//url", + ] +}
diff --git a/components/nacl/renderer/progress_event.cc b/components/nacl/renderer/progress_event.cc index ae30755..6bd5571 100644 --- a/components/nacl/renderer/progress_event.cc +++ b/components/nacl/renderer/progress_event.cc
@@ -6,88 +6,63 @@ #include "base/bind.h" #include "base/location.h" -#include "base/logging.h" #include "components/nacl/renderer/ppb_nacl_private.h" #include "content/public/renderer/pepper_plugin_instance.h" #include "ppapi/shared_impl/ppapi_globals.h" #include "third_party/WebKit/public/platform/WebString.h" -#include "third_party/WebKit/public/web/WebDOMResourceProgressEvent.h" -#include "third_party/WebKit/public/web/WebDocument.h" -#include "third_party/WebKit/public/web/WebElement.h" -#include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebPluginContainer.h" -#include "v8/include/v8.h" + +using blink::WebString; +using blink::WebPluginContainer; namespace nacl { namespace { -blink::WebString EventTypeToString(PP_NaClEventType event_type) { +const char* EventTypeToName(PP_NaClEventType event_type) { switch (event_type) { case PP_NACL_EVENT_LOADSTART: - return blink::WebString::fromUTF8("loadstart"); + return "loadstart"; case PP_NACL_EVENT_PROGRESS: - return blink::WebString::fromUTF8("progress"); + return "progress"; case PP_NACL_EVENT_ERROR: - return blink::WebString::fromUTF8("error"); + return "error"; case PP_NACL_EVENT_ABORT: - return blink::WebString::fromUTF8("abort"); + return "abort"; case PP_NACL_EVENT_LOAD: - return blink::WebString::fromUTF8("load"); + return "load"; case PP_NACL_EVENT_LOADEND: - return blink::WebString::fromUTF8("loadend"); + return "loadend"; case PP_NACL_EVENT_CRASH: - return blink::WebString::fromUTF8("crash"); + return "crash"; } - NOTIMPLEMENTED(); - return blink::WebString(); + NOTREACHED(); + return ""; } void DispatchProgressEventOnMainThread(PP_Instance instance, - const ProgressEvent &event) { + const ProgressEvent& event) { content::PepperPluginInstance* plugin_instance = content::PepperPluginInstance::Get(instance); if (!plugin_instance) return; - blink::WebPluginContainer* container = plugin_instance->GetContainer(); + WebPluginContainer* container = plugin_instance->GetContainer(); // It's possible that container() is NULL if the plugin has been removed from // the DOM (but the PluginInstance is not destroyed yet). if (!container) return; - blink::WebLocalFrame* frame = container->element().document().frame(); - if (!frame) - return; - v8::HandleScope handle_scope(plugin_instance->GetIsolate()); - v8::Local<v8::Context> context( - plugin_instance->GetIsolate()->GetCurrentContext()); - if (context.IsEmpty()) { - // If there's no JavaScript on the stack, we have to make a new Context. - context = v8::Context::New(plugin_instance->GetIsolate()); - } - v8::Context::Scope context_scope(context); - if (!event.resource_url.empty()) { - blink::WebString url_string = blink::WebString::fromUTF8( - event.resource_url.data(), event.resource_url.size()); - blink::WebDOMResourceProgressEvent blink_event( - EventTypeToString(event.event_type), - event.length_is_computable, - event.loaded_bytes, - event.total_bytes, - url_string); - container->element().dispatchEvent(blink_event); - } else { - blink::WebDOMProgressEvent blink_event(EventTypeToString(event.event_type), - event.length_is_computable, - event.loaded_bytes, - event.total_bytes); - container->element().dispatchEvent(blink_event); - } + container->dispatchProgressEvent( + WebString::fromUTF8(EventTypeToName(event.event_type)), + event.length_is_computable, + event.loaded_bytes, + event.total_bytes, + WebString::fromUTF8(event.resource_url)); } } // namespace -void DispatchProgressEvent(PP_Instance instance, const ProgressEvent &event) { +void DispatchProgressEvent(PP_Instance instance, const ProgressEvent& event) { ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( FROM_HERE, base::Bind(&DispatchProgressEventOnMainThread, instance, event));
diff --git a/components/page_load_metrics/browser/metrics_web_contents_observer.cc b/components/page_load_metrics/browser/metrics_web_contents_observer.cc index 6e2feb75..ffda133 100644 --- a/components/page_load_metrics/browser/metrics_web_contents_observer.cc +++ b/components/page_load_metrics/browser/metrics_web_contents_observer.cc
@@ -77,11 +77,6 @@ return true; } -base::Time WallTimeFromTimeTicks(const base::TimeTicks& time) { - return base::Time::FromDoubleT( - (time - base::TimeTicks::UnixEpoch()).InSecondsF()); -} - void RecordInternalError(InternalErrorLoadEvent event) { UMA_HISTOGRAM_ENUMERATION(kErrorEvents, event, ERR_LAST_ENTRY); } @@ -122,8 +117,10 @@ PageLoadTracker::PageLoadTracker( bool in_foreground, PageLoadMetricsEmbedderInterface* embedder_interface, + content::NavigationHandle* navigation_handle, base::ObserverList<PageLoadMetricsObserver, true>* observers) : has_commit_(false), + navigation_start_(navigation_handle->NavigationStart()), started_in_foreground_(in_foreground), embedder_interface_(embedder_interface), observers_(observers) {} @@ -187,14 +184,10 @@ PageLoadExtraInfo PageLoadTracker::GetPageLoadMetricsInfo() { base::TimeDelta first_background_time; base::TimeDelta first_foreground_time; - if (!background_time_.is_null() && started_in_foreground_) { - first_background_time = - WallTimeFromTimeTicks(background_time_) - timing_.navigation_start; - } - if (!foreground_time_.is_null() && !started_in_foreground_) { - first_foreground_time = - WallTimeFromTimeTicks(foreground_time_) - timing_.navigation_start; - } + if (!background_time_.is_null() && started_in_foreground_) + first_background_time = background_time_ - navigation_start_; + if (!foreground_time_.is_null() && !started_in_foreground_) + first_foreground_time = foreground_time_ - navigation_start_; return PageLoadExtraInfo(first_background_time, first_foreground_time, started_in_foreground_); } @@ -218,9 +211,8 @@ // backgrounded. base::TimeDelta PageLoadTracker::GetBackgroundDelta() { if (started_in_foreground_) { - if (background_time_.is_null()) - return base::TimeDelta::Max(); - return WallTimeFromTimeTicks(background_time_) - timing_.navigation_start; + return background_time_.is_null() ? base::TimeDelta::Max() + : background_time_ - navigation_start_; } return base::TimeDelta(); } @@ -306,9 +298,8 @@ if (!background_time_.is_null()) { PAGE_LOAD_HISTOGRAM(kHistogramFirstBackground, background_delta); } else if (!foreground_time_.is_null()) { - PAGE_LOAD_HISTOGRAM( - kHistogramFirstForeground, - WallTimeFromTimeTicks(foreground_time_) - timing_.navigation_start); + PAGE_LOAD_HISTOGRAM(kHistogramFirstForeground, + foreground_time_ - navigation_start_); } } @@ -427,10 +418,10 @@ // Passing raw pointers to observers_ and embedder_interface_ is safe because // the MetricsWebContentsObserver owns them both list and they are torn down // after the PageLoadTracker. - provisional_loads_.insert( - navigation_handle, - make_scoped_ptr(new PageLoadTracker( - in_foreground_, embedder_interface_.get(), &observers_))); + provisional_loads_.insert(navigation_handle, + make_scoped_ptr(new PageLoadTracker( + in_foreground_, embedder_interface_.get(), + navigation_handle, &observers_))); } void MetricsWebContentsObserver::DidFinishNavigation(
diff --git a/components/page_load_metrics/browser/metrics_web_contents_observer.h b/components/page_load_metrics/browser/metrics_web_contents_observer.h index c9685b6..1c8a4e5 100644 --- a/components/page_load_metrics/browser/metrics_web_contents_observer.h +++ b/components/page_load_metrics/browser/metrics_web_contents_observer.h
@@ -195,6 +195,7 @@ // outlives this class. PageLoadTracker(bool in_foreground, PageLoadMetricsEmbedderInterface* embedder_interface, + content::NavigationHandle* navigation_handle, base::ObserverList<PageLoadMetricsObserver, true>* observers); ~PageLoadTracker(); void Redirect(content::NavigationHandle* navigation_handle); @@ -219,6 +220,9 @@ bool has_commit_; + // The navigation start in TimeTicks, not the wall time reported by Blink. + const base::TimeTicks navigation_start_; + // We record separate metrics for events that occur after a background, // because metrics like layout/paint are delayed artificially // when they occur in the background.
diff --git a/components/page_load_metrics/browser/metrics_web_contents_observer_unittest.cc b/components/page_load_metrics/browser/metrics_web_contents_observer_unittest.cc index 769c237..b1f3228f 100644 --- a/components/page_load_metrics/browser/metrics_web_contents_observer_unittest.cc +++ b/components/page_load_metrics/browser/metrics_web_contents_observer_unittest.cc
@@ -302,8 +302,7 @@ base::TimeDelta first_layout = base::TimeDelta::FromSeconds(2); PageLoadTiming timing; - timing.navigation_start = base::Time::FromDoubleT( - (base::TimeTicks::Now() - base::TimeTicks::UnixEpoch()).InSecondsF()); + timing.navigation_start = base::Time::FromDoubleT(1); timing.first_layout = first_layout; content::WebContentsTester* web_contents_tester = @@ -356,11 +355,11 @@ TEST_F(MetricsWebContentsObserverTest, OnlyBackgroundLaterEvents) { PageLoadTiming timing; - timing.navigation_start = base::Time::FromDoubleT( - (base::TimeTicks::Now() - base::TimeTicks::UnixEpoch()).InSecondsF() - 1); - - timing.response_start = base::TimeDelta::FromMilliseconds(1); - timing.dom_content_loaded_event_start = base::TimeDelta::FromMilliseconds(1); + timing.navigation_start = base::Time::FromDoubleT(1); + // Set these events at 1 microsecond so they are definitely occur before we + // background the tab later in the test. + timing.response_start = base::TimeDelta::FromMicroseconds(1); + timing.dom_content_loaded_event_start = base::TimeDelta::FromMicroseconds(1); content::WebContentsTester* web_contents_tester = content::WebContentsTester::For(web_contents()); @@ -402,7 +401,9 @@ } TEST_F(MetricsWebContentsObserverTest, DontBackgroundQuickerLoad) { - base::TimeDelta first_layout = base::TimeDelta::FromMilliseconds(1); + // Set this event at 1 microsecond so it occurs before we foreground later in + // the test. + base::TimeDelta first_layout = base::TimeDelta::FromMicroseconds(1); PageLoadTiming timing; timing.navigation_start = base::Time::FromDoubleT(1); @@ -430,7 +431,7 @@ main_rfh()); rfh_tester->SimulateNavigationStop(); - // Navigate again to see if the timing updated for a subframe message. + // Navigate again to see if the timing updated for the foregrounded load. web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); histogram_tester_.ExpectTotalCount(kHistogramDomContentLoaded, 0); @@ -578,9 +579,7 @@ TEST_F(MetricsWebContentsObserverTest, SuccessfulFirstLayoutInBackgroundEvent) { PageLoadTiming timing; - timing.navigation_start = base::Time::FromDoubleT( - (base::TimeTicks::Now() - base::TimeTicks::UnixEpoch()).InSecondsF() - 1); - + timing.navigation_start = base::Time::FromDoubleT(1); timing.first_layout = base::TimeDelta::FromSeconds(30); content::WebContentsTester* web_contents_tester =
diff --git a/components/password_manager.gypi b/components/password_manager.gypi index 6e941e5..15bcbf9 100644 --- a/components/password_manager.gypi +++ b/components/password_manager.gypi
@@ -106,8 +106,6 @@ 'password_manager/core/browser/password_store_default.h', 'password_manager/core/browser/password_store_factory_util.cc', 'password_manager/core/browser/password_store_factory_util.h', - 'password_manager/core/browser/password_store_service.cc', - 'password_manager/core/browser/password_store_service.h', 'password_manager/core/browser/password_store_sync.cc', 'password_manager/core/browser/password_store_sync.h', 'password_manager/core/browser/password_syncable_service.cc',
diff --git a/components/password_manager/content/browser/credential_manager_dispatcher_unittest.cc b/components/password_manager/content/browser/credential_manager_dispatcher_unittest.cc index 7052a6f..00111fb1 100644 --- a/components/password_manager/content/browser/credential_manager_dispatcher_unittest.cc +++ b/components/password_manager/content/browser/credential_manager_dispatcher_unittest.cc
@@ -224,7 +224,7 @@ } void TearDown() override { - store_->Shutdown(); + store_->ShutdownOnUIThread(); content::RenderViewHostTestHarness::TearDown(); }
diff --git a/components/password_manager/core/browser/BUILD.gn b/components/password_manager/core/browser/BUILD.gn index a560e12c..35207d2 100644 --- a/components/password_manager/core/browser/BUILD.gn +++ b/components/password_manager/core/browser/BUILD.gn
@@ -86,8 +86,6 @@ "password_store_default.h", "password_store_factory_util.cc", "password_store_factory_util.h", - "password_store_service.cc", - "password_store_service.h", "password_store_sync.cc", "password_store_sync.h", "password_syncable_service.cc",
diff --git a/components/password_manager/core/browser/affiliated_match_helper_unittest.cc b/components/password_manager/core/browser/affiliated_match_helper_unittest.cc index 633924f..946678df 100644 --- a/components/password_manager/core/browser/affiliated_match_helper_unittest.cc +++ b/components/password_manager/core/browser/affiliated_match_helper_unittest.cc
@@ -296,7 +296,7 @@ void TearDown() override { match_helper_.reset(); - password_store_->Shutdown(); + password_store_->ShutdownOnUIThread(); password_store_ = nullptr; }
diff --git a/components/password_manager/core/browser/password_form_manager_unittest.cc b/components/password_manager/core/browser/password_form_manager_unittest.cc index f2eb36b9..4c24a13 100644 --- a/components/password_manager/core/browser/password_form_manager_unittest.cc +++ b/components/password_manager/core/browser/password_form_manager_unittest.cc
@@ -313,7 +313,7 @@ void TearDown() override { if (mock_store_.get()) - mock_store_->Shutdown(); + mock_store_->ShutdownOnUIThread(); } MockPasswordStore* mock_store() const { return mock_store_.get(); }
diff --git a/components/password_manager/core/browser/password_generation_manager_unittest.cc b/components/password_manager/core/browser/password_generation_manager_unittest.cc index c687748d..fcc2683 100644 --- a/components/password_manager/core/browser/password_generation_manager_unittest.cc +++ b/components/password_manager/core/browser/password_generation_manager_unittest.cc
@@ -74,7 +74,7 @@ explicit MockPasswordManagerClient(scoped_ptr<PrefService> prefs) : prefs_(prefs.Pass()), store_(new TestPasswordStore), driver_(this) {} - ~MockPasswordManagerClient() override { store_->Shutdown(); } + ~MockPasswordManagerClient() override { store_->ShutdownOnUIThread(); } PasswordStore* GetPasswordStore() const override { return store_.get(); } PrefService* GetPrefs() override { return prefs_.get(); }
diff --git a/components/password_manager/core/browser/password_manager_test_utils.h b/components/password_manager/core/browser/password_manager_test_utils.h index aeb212f..c6e7c6a3 100644 --- a/components/password_manager/core/browser/password_manager_test_utils.h +++ b/components/password_manager/core/browser/password_manager_test_utils.h
@@ -8,9 +8,9 @@ #include <iosfwd> #include <vector> -#include "base/memory/scoped_ptr.h" +#include "base/memory/ref_counted.h" #include "components/autofill/core/common/password_form.h" -#include "components/password_manager/core/browser/password_store_service.h" +#include "components/password_manager/core/browser/password_store.h" #include "testing/gmock/include/gmock/gmock.h" // TODO(sync): The PasswordFormData code must eventually be refactored away -- @@ -18,17 +18,17 @@ namespace password_manager { -// This templates allows creating methods with signature conforming to +// This template allows creating methods with signature conforming to // TestingFactoryFunction of the appropriate platform instance of // KeyedServiceFactory. Context is the browser context prescribed by // TestingFactoryFunction. Store is the PasswordStore version needed in the // tests which use this method. template <class Context, class Store> -scoped_ptr<KeyedService> BuildPasswordStoreService(Context* context) { +scoped_refptr<RefcountedKeyedService> BuildPasswordStore(Context* context) { scoped_refptr<password_manager::PasswordStore> store(new Store); if (!store->Init(syncer::SyncableService::StartSyncFlare())) return nullptr; - return scoped_ptr<KeyedService>(new PasswordStoreService(store)); + return store; } // These constants are used by CreatePasswordFormFromDataForTesting to supply
diff --git a/components/password_manager/core/browser/password_manager_unittest.cc b/components/password_manager/core/browser/password_manager_unittest.cc index 6fb28b50..2978f56 100644 --- a/components/password_manager/core/browser/password_manager_unittest.cc +++ b/components/password_manager/core/browser/password_manager_unittest.cc
@@ -135,7 +135,7 @@ } void TearDown() override { - store_->Shutdown(); + store_->ShutdownOnUIThread(); store_ = nullptr; }
diff --git a/components/password_manager/core/browser/password_store.cc b/components/password_manager/core/browser/password_store.cc index 560a2928..b960bf5 100644 --- a/components/password_manager/core/browser/password_store.cc +++ b/components/password_manager/core/browser/password_store.cc
@@ -235,7 +235,7 @@ return false; } -void PasswordStore::Shutdown() { +void PasswordStore::ShutdownOnUIThread() { ScheduleTask(base::Bind(&PasswordStore::DestroySyncableService, this)); // The AffiliationService must be destroyed from the main thread. affiliated_match_helper_.reset();
diff --git a/components/password_manager/core/browser/password_store.h b/components/password_manager/core/browser/password_store.h index ceeaece5..aedccbc 100644 --- a/components/password_manager/core/browser/password_store.h +++ b/components/password_manager/core/browser/password_store.h
@@ -10,12 +10,12 @@ #include "base/callback.h" #include "base/gtest_prod_util.h" -#include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/memory/scoped_vector.h" #include "base/observer_list_threadsafe.h" #include "base/single_thread_task_runner.h" #include "base/time/time.h" +#include "components/keyed_service/core/refcounted_keyed_service.h" #include "components/password_manager/core/browser/password_store_change.h" #include "components/password_manager/core/browser/password_store_sync.h" #include "sync/api/syncable_service.h" @@ -52,7 +52,7 @@ // PasswordStoreSync is a hidden base class because only PasswordSyncableService // needs to access these methods. class PasswordStore : protected PasswordStoreSync, - public base::RefCountedThreadSafe<PasswordStore> { + public RefcountedKeyedService { public: // Whether or not it's acceptable for Chrome to request access to locked // passwords, which requires prompting the user for permission. @@ -77,6 +77,9 @@ // Reimplement this to add custom initialization. Always call this too. virtual bool Init(const syncer::SyncableService::StartSyncFlare& flare); + // RefcountedKeyedService: + void ShutdownOnUIThread() override; + // Sets the affiliation-based match |helper| that will be used by subsequent // GetLogins() calls to return credentials stored not only for the requested // sign-on realm, but also for affiliated Android applications. If |helper| is @@ -191,10 +194,6 @@ // Schedules the given |task| to be run on the PasswordStore's TaskRunner. bool ScheduleTask(const base::Closure& task); - // Before you destruct the store, call Shutdown to indicate that the store - // needs to shut itself down. - virtual void Shutdown(); - base::WeakPtr<syncer::SyncableService> GetPasswordSyncableService(); protected:
diff --git a/components/password_manager/core/browser/password_store_default.cc b/components/password_manager/core/browser/password_store_default.cc index ad65039..dab5c29 100644 --- a/components/password_manager/core/browser/password_store_default.cc +++ b/components/password_manager/core/browser/password_store_default.cc
@@ -33,8 +33,8 @@ return PasswordStore::Init(flare); } -void PasswordStoreDefault::Shutdown() { - PasswordStore::Shutdown(); +void PasswordStoreDefault::ShutdownOnUIThread() { + PasswordStore::ShutdownOnUIThread(); ScheduleTask(base::Bind(&PasswordStoreDefault::ResetLoginDB, this)); }
diff --git a/components/password_manager/core/browser/password_store_default.h b/components/password_manager/core/browser/password_store_default.h index af5bdc6..3d714bd 100644 --- a/components/password_manager/core/browser/password_store_default.h +++ b/components/password_manager/core/browser/password_store_default.h
@@ -27,7 +27,7 @@ bool Init(const syncer::SyncableService::StartSyncFlare& flare) override; - void Shutdown() override; + void ShutdownOnUIThread() override; // To be used only for testing. LoginDatabase* login_db() const { return login_db_.get(); }
diff --git a/components/password_manager/core/browser/password_store_default_unittest.cc b/components/password_manager/core/browser/password_store_default_unittest.cc index 53080d9..b9e9c581 100644 --- a/components/password_manager/core/browser/password_store_default_unittest.cc +++ b/components/password_manager/core/browser/password_store_default_unittest.cc
@@ -172,7 +172,7 @@ base::MessageLoop::current()->RunUntilIdle(); - store->Shutdown(); + store->ShutdownOnUIThread(); } TEST_F(PasswordStoreDefaultTest, Notifications) { @@ -221,7 +221,7 @@ base::MessageLoop::current()->RunUntilIdle(); store->RemoveObserver(&observer); - store->Shutdown(); + store->ShutdownOnUIThread(); } // Verify that operations on a PasswordStore with a bad database cause no @@ -285,7 +285,7 @@ // Ensure no notifications and no explosions during shutdown either. bad_store->RemoveObserver(&mock_observer); - bad_store->Shutdown(); + bad_store->ShutdownOnUIThread(); } TEST_F(PasswordStoreDefaultTest, @@ -311,7 +311,7 @@ run_loop.Run(); store->RemoveObserver(&observer); - store->Shutdown(); + store->ShutdownOnUIThread(); } TEST_F(PasswordStoreDefaultTest, @@ -336,7 +336,7 @@ run_loop.Run(); store->RemoveObserver(&observer); - store->Shutdown(); + store->ShutdownOnUIThread(); } TEST_F(PasswordStoreDefaultTest, @@ -363,7 +363,7 @@ run_loop.Run(); store->RemoveObserver(&observer); - store->Shutdown(); + store->ShutdownOnUIThread(); } } // namespace password_manager
diff --git a/components/password_manager/core/browser/password_store_factory_util.cc b/components/password_manager/core/browser/password_store_factory_util.cc index e6c8580..eaf114b 100644 --- a/components/password_manager/core/browser/password_store_factory_util.cc +++ b/components/password_manager/core/browser/password_store_factory_util.cc
@@ -88,34 +88,10 @@ } } -scoped_refptr<PasswordStore> GetPasswordStoreFromService( - password_manager::PasswordStoreService* service, - ServiceAccessType access_type, - bool is_off_the_record) { - if (access_type == ServiceAccessType::IMPLICIT_ACCESS && is_off_the_record) { - NOTREACHED() << "Incognito state does not have a password store associated"; - return nullptr; - } - - return service ? service->GetPasswordStore() : nullptr; -} - scoped_ptr<LoginDatabase> CreateLoginDatabase( const base::FilePath& profile_path) { base::FilePath login_db_file_path = profile_path.Append(kLoginDataFileName); return make_scoped_ptr(new LoginDatabase(login_db_file_path)); } -scoped_ptr<KeyedService> BuildServiceInstanceFromStore( - scoped_refptr<PasswordStore> store, - syncer::SyncableService::StartSyncFlare sync_flare) { - DCHECK(store); - if (!store->Init(sync_flare)) { - NOTREACHED() << "Could not initialize password store."; - return nullptr; - } - - return make_scoped_ptr(new PasswordStoreService(store)); -} - } // namespace password_manager
diff --git a/components/password_manager/core/browser/password_store_factory_util.h b/components/password_manager/core/browser/password_store_factory_util.h index 83a73b6..2626618 100644 --- a/components/password_manager/core/browser/password_store_factory_util.h +++ b/components/password_manager/core/browser/password_store_factory_util.h
@@ -13,7 +13,6 @@ #include "components/keyed_service/core/service_access_type.h" #include "components/password_manager/core/browser/login_database.h" #include "components/password_manager/core/browser/password_store.h" -#include "components/password_manager/core/browser/password_store_service.h" #include "components/sync_driver/sync_service.h" #include "net/url_request/url_request_context_getter.h" #include "sync/api/syncable_service.h" @@ -42,27 +41,12 @@ const base::FilePath& profile_path, scoped_refptr<base::SingleThreadTaskRunner> db_thread_runner); -// Extracts the PasswordStore from |service|, taking into account the -// |access_type|, and whether the corresponding browsing session -// |is_off_the_record|. -scoped_refptr<PasswordStore> GetPasswordStoreFromService( - PasswordStoreService* service, - ServiceAccessType access_type, - bool is_off_the_record); - // Creates a LoginDatabase. Looks in |profile_path| for the database file. // Does not call LoginDatabase::Init() -- to avoid UI jank, that needs to be // called by PasswordStore::Init() on the background thread. scoped_ptr<LoginDatabase> CreateLoginDatabase( const base::FilePath& profile_path); -// Initializes the |store|, passing |sync_flare| into it, then returns the -// |store| wrapped in a PasswordStoreService on success. Returns nullptr on -// failure. -scoped_ptr<KeyedService> BuildServiceInstanceFromStore( - scoped_refptr<PasswordStore> store, - syncer::SyncableService::StartSyncFlare sync_flare); - } // namespace password_manager #endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_STORE_FACTORY_UTIL_H_
diff --git a/components/password_manager/core/browser/password_store_service.cc b/components/password_manager/core/browser/password_store_service.cc deleted file mode 100644 index d66629d8..0000000 --- a/components/password_manager/core/browser/password_store_service.cc +++ /dev/null
@@ -1,24 +0,0 @@ -// Copyright 2015 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 "components/password_manager/core/browser/password_store_service.h" - -namespace password_manager { - -PasswordStoreService::PasswordStoreService( - scoped_refptr<PasswordStore> password_store) - : password_store_(password_store) {} - -PasswordStoreService::~PasswordStoreService() {} - -scoped_refptr<PasswordStore> PasswordStoreService::GetPasswordStore() { - return password_store_; -} - -void PasswordStoreService::Shutdown() { - if (password_store_) - password_store_->Shutdown(); -} - -} // namespace password_manager
diff --git a/components/password_manager/core/browser/password_store_service.h b/components/password_manager/core/browser/password_store_service.h deleted file mode 100644 index 0e57011..0000000 --- a/components/password_manager/core/browser/password_store_service.h +++ /dev/null
@@ -1,37 +0,0 @@ -// Copyright 2015 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 COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_STORE_SERVICE_H_ -#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_STORE_SERVICE_H_ - -#include "base/memory/ref_counted.h" -#include "components/keyed_service/core/keyed_service.h" -#include "components/password_manager/core/browser/password_store.h" - -namespace password_manager { - -// A wrapper of PasswordStore so we can use it as a profiled keyed service. This -// is necessary, because while the service has a signle owner (its factory), the -// store is refcounted. -class PasswordStoreService : public KeyedService { - public: - // |password_store| needs to be not-NULL, and the constructor expects that - // Init() was already called successfully on it. - explicit PasswordStoreService(scoped_refptr<PasswordStore> password_store); - ~PasswordStoreService() override; - - scoped_refptr<PasswordStore> GetPasswordStore(); - - // KeyedService implementation. - void Shutdown() override; - - private: - scoped_refptr<PasswordStore> password_store_; - - DISALLOW_COPY_AND_ASSIGN(PasswordStoreService); -}; - -} // namespace password_manager - -#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_STORE_SERVICE_H_
diff --git a/components/password_manager/core/browser/password_store_unittest.cc b/components/password_manager/core/browser/password_store_unittest.cc index 619c38fe..bff9d6d 100644 --- a/components/password_manager/core/browser/password_store_unittest.cc +++ b/components/password_manager/core/browser/password_store_unittest.cc
@@ -225,7 +225,7 @@ base::MessageLoop::current()->RunUntilIdle(); - store->Shutdown(); + store->ShutdownOnUIThread(); base::MessageLoop::current()->RunUntilIdle(); } @@ -244,7 +244,7 @@ store->AddLogin(form); base::MessageLoop::current()->RunUntilIdle(); } - store->Shutdown(); + store->ShutdownOnUIThread(); base::MessageLoop::current()->RunUntilIdle(); } @@ -294,7 +294,7 @@ ASSERT_TRUE(returned_form); EXPECT_EQ(*test_form, *returned_form); - store->Shutdown(); + store->ShutdownOnUIThread(); base::MessageLoop::current()->RunUntilIdle(); } @@ -352,7 +352,7 @@ base::MessageLoop::current()->RunUntilIdle(); store->RemoveObserver(&mock_observer); - store->Shutdown(); + store->ShutdownOnUIThread(); base::MessageLoop::current()->RunUntilIdle(); } @@ -391,7 +391,7 @@ testing::Mock::VerifyAndClearExpectations(&mock_observer); store->RemoveObserver(&mock_observer); - store->Shutdown(); + store->ShutdownOnUIThread(); base::MessageLoop::current()->RunUntilIdle(); } @@ -462,7 +462,7 @@ OnGetPasswordStoreResultsConstRef( UnorderedPasswordFormElementsAre(expected_results.get()))); store->GetLogins(observed_form, PasswordStore::ALLOW_PROMPT, &mock_consumer); - store->Shutdown(); + store->ShutdownOnUIThread(); base::MessageLoop::current()->RunUntilIdle(); } @@ -580,7 +580,7 @@ UnorderedPasswordFormElementsAre(expected_results.get()))); store->GetLogins(observed_form, PasswordStore::ALLOW_PROMPT, &mock_consumer); - store->Shutdown(); + store->ShutdownOnUIThread(); base::MessageLoop::current()->RunUntilIdle(); } @@ -797,7 +797,7 @@ OnGetPasswordStoreResultsConstRef(UnorderedPasswordFormElementsAre( expected_credentials_after_update.get()))); store->GetAutofillableLogins(&mock_consumer); - store->Shutdown(); + store->ShutdownOnUIThread(); base::MessageLoop::current()->RunUntilIdle(); } }
diff --git a/components/password_manager/core/browser/password_syncable_service_unittest.cc b/components/password_manager/core/browser/password_syncable_service_unittest.cc index abd13a8..7cbf476 100644 --- a/components/password_manager/core/browser/password_syncable_service_unittest.cc +++ b/components/password_manager/core/browser/password_syncable_service_unittest.cc
@@ -195,7 +195,7 @@ EXPECT_CALL(*password_store(), NotifyLoginsChanged(_)).Times(AnyNumber()); } - ~PasswordSyncableServiceWrapper() { password_store_->Shutdown(); } + ~PasswordSyncableServiceWrapper() { password_store_->ShutdownOnUIThread(); } MockPasswordStore* password_store() { return password_store_.get(); }
diff --git a/components/policy/core/common/cloud/cloud_policy_constants.h b/components/policy/core/common/cloud/cloud_policy_constants.h index a173275..e1a9134 100644 --- a/components/policy/core/common/cloud/cloud_policy_constants.h +++ b/components/policy/core/common/cloud/cloud_policy_constants.h
@@ -65,16 +65,6 @@ POLICY_EXPORT std::string GetPolicyVerificationKey(); POLICY_EXPORT extern const char kPolicyVerificationKeyHash[]; -// TODO(peletskyi): Remove this enum after affiliation code is moved -// to components/user_manager. -// Describes the affiliation of a user w.r.t. the device owner. -enum UserAffiliation { - // User is on the same domain the device was registered with. - USER_AFFILIATION_MANAGED, - // No affiliation between device and user. - USER_AFFILIATION_NONE, -}; - // Status codes for communication errors with the device management service. // This enum is used to define the buckets for an enumerated UMA histogram. // Hence,
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index ef935c11..046a437 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -134,7 +134,7 @@ # persistent IDs for all fields (but not for groups!) are needed. These are # specified by the 'id' keys of each policy. NEVER CHANGE EXISTING IDs, # because doing so would break the deployed wire format! -# For your editing convenience: highest ID currently used: 310 +# For your editing convenience: highest ID currently used: 311 # # Placeholders: # The following placeholder strings are automatically substituted: @@ -8002,6 +8002,58 @@ If this policy is set to false or unset, Unified Desktop will be disabled. In this case, the user cannot enable the feature.''', }, + { + 'name': 'DisplayRotationDefault', + 'type': 'int-enum', + 'schema': { + 'type': 'integer', + 'enum': [ 0, 1, 2, 3 ], + }, + 'items': [ + { + 'name': 'ROTATE_0', + 'value': 0, + 'caption': '''Rotate screen by 0 degrees''', + }, + { + 'name': 'ROTATE_90', + 'value': 1, + 'caption': '''Rotate screen clockwise by 90 degrees''', + }, + { + 'name': 'ROTATE_180', + 'value': 2, + 'caption': '''Rotate screen by 180 degrees''', + }, + { + 'name': 'ROTATE_270', + 'value': 3, + 'caption': '''Rotate screen clockwise by 270 degrees''', + }, + ], + 'supported_on': ['chrome_os:48-'], + 'device_only': True, + 'features': { + 'can_be_recommended': False, + 'dynamic_refresh': True, + 'per_profile': False, + }, + 'example_value': 1, + 'id': 311, + 'caption': '''Set default display rotation, reapplied on every reboot''', + 'tags': [], + 'desc': '''If this policy is set, each display is rotated to the + specified orientation on every reboot, and the first time it is connected + after the policy value has changed. Users may change the display + rotation via the settings page after logging in, but their + setting will be overridden by the policy value at the next reboot. + + This policy applies to both the primary and all secondary displays. + + If the policy is not set, the default value is 0 degrees and the user is + free to change it. In this case, the default value is not reapplied at + restart.''', + }, ], 'messages': { # Messages that are not associated to any policies.
diff --git a/components/translate.gypi b/components/translate.gypi index 2b0e48f..be9317b 100644 --- a/components/translate.gypi +++ b/components/translate.gypi
@@ -233,6 +233,7 @@ ['OS == "ios"', { 'targets': [ { + # GN version: //components/translate/ios/browser 'target_name': 'translate_ios_browser', 'type': 'static_library', 'include_dirs': [ @@ -261,6 +262,7 @@ ], }, { + # GN version: //components/translate/ios/browser:injected_js 'target_name': 'translate_ios_injected_js', 'type': 'none', 'sources': [
diff --git a/components/translate/ios/browser/BUILD.gn b/components/translate/ios/browser/BUILD.gn new file mode 100644 index 0000000..420954a --- /dev/null +++ b/components/translate/ios/browser/BUILD.gn
@@ -0,0 +1,59 @@ +# Copyright 2015 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. + +import("//ios/web/js_compile.gni") + +source_set("browser") { + sources = [ + "ios_translate_driver.h", + "ios_translate_driver.mm", + "js_language_detection_manager.h", + "js_language_detection_manager.mm", + "js_translate_manager.h", + "js_translate_manager.mm", + "language_detection_controller.h", + "language_detection_controller.mm", + "translate_controller.h", + "translate_controller.mm", + ] + + deps = [ + "//base", + "//components/translate/core/browser", + "//components/translate/core/common", + "//components/translate/core/language_detection", + "//ios/web", + "//url", + ":injected_js", + ] +} + +js_compile_checked("injected_js") { + visibility = [ ":browser" ] + sources = [ + "resources/language_detection.js", + "resources/translate_ios.js", + ] +} + +source_set("unit_tests") { + testonly = true + sources = [ + "js_translate_manager_unittest.mm", + "language_detection_controller_unittest.mm", + "translate_controller_unittest.mm", + ] + + deps = [ + "//base", + "//components/resources", + "//components/translate/core/common", + "//ios/web:test_support", + "//testing/gtest", + "//third_party/ocmock", + "//ui/base", + "//url", + ":browser", + ] +}
diff --git a/content/browser/background_sync/background_sync_browsertest.cc b/content/browser/background_sync/background_sync_browsertest.cc index e3f8dc0..6e30cc5 100644 --- a/content/browser/background_sync/background_sync_browsertest.cc +++ b/content/browser/background_sync/background_sync_browsertest.cc
@@ -182,8 +182,6 @@ bool RegisterServiceWorker(); bool RegisterOneShot(const std::string& tag); bool RegisterOneShotFromServiceWorker(const std::string& tag); - bool UnregisterOneShot(const std::string& tag); - bool UnregisterOneShotTwice(const std::string& tag); bool GetRegistrationOneShot(const std::string& tag); bool GetRegistrationOneShotFromServiceWorker(const std::string& tag); bool MatchRegistrations(const std::string& script_result, @@ -193,9 +191,6 @@ const std::vector<std::string>& expected_tags); bool CompleteDelayedOneShot(); bool RejectDelayedOneShot(); - bool NotifyWhenFinishedOneShot(const std::string& tag); - bool NotifyWhenFinishedImmediateOneShot(const std::string& expected_msg); - bool StoreRegistrationOneShot(const std::string& tag); private: scoped_ptr<net::EmbeddedTestServer> https_server_; @@ -323,21 +318,6 @@ return script_result == BuildExpectedResult(tag, "register sent to SW"); } -bool BackgroundSyncBrowserTest::UnregisterOneShot(const std::string& tag) { - std::string script_result; - EXPECT_TRUE( - RunScript(BuildScriptString("unregisterOneShot", tag), &script_result)); - return script_result == BuildExpectedResult(tag, "unregistered"); -} - -bool BackgroundSyncBrowserTest::UnregisterOneShotTwice(const std::string& tag) { - std::string script_result; - EXPECT_TRUE(RunScript(BuildScriptString("unregisterOneShotTwice", tag), - &script_result)); - return script_result == - BuildExpectedResult(tag, "failed to unregister twice"); -} - bool BackgroundSyncBrowserTest::GetRegistrationOneShot(const std::string& tag) { std::string script_result; EXPECT_TRUE(RunScript(BuildScriptString("getRegistrationOneShot", tag), @@ -400,30 +380,6 @@ return script_result == BuildExpectedResult("delay", "rejecting"); } -bool BackgroundSyncBrowserTest::NotifyWhenFinishedOneShot( - const std::string& tag) { - EXPECT_TRUE(content::ExecuteScript( - shell_->web_contents(), - BuildScriptString("notifyWhenFinishedOneShot", tag))); - return PopConsole(BuildExpectedResult(tag, "finished")); -} - -bool BackgroundSyncBrowserTest::NotifyWhenFinishedImmediateOneShot( - const std::string& expected_msg) { - std::string script_result; - EXPECT_TRUE( - RunScript("notifyWhenFinishedImmediateOneShot()", &script_result)); - return script_result == expected_msg; -} - -bool BackgroundSyncBrowserTest::StoreRegistrationOneShot( - const std::string& tag) { - std::string script_result; - EXPECT_TRUE( - RunScript(BuildScriptString("storeRegistration", tag), &script_result)); - return script_result == BuildExpectedResult(tag, "stored"); -} - IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, OneShotFires) { EXPECT_TRUE(RegisterServiceWorker()); EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page. @@ -477,8 +433,6 @@ EXPECT_TRUE(PopConsole("ok - delay completed")); // Verify that it finished firing. - // TODO(jkarlin): Use registration.finished to verify that the event actually - // completed successfully. EXPECT_FALSE(GetRegistrationOneShot("delay")); } @@ -586,108 +540,6 @@ EXPECT_TRUE(GetRegistrationOneShotFromServiceWorker("foo_sw")); } -IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, Unregister) { - EXPECT_TRUE(RegisterServiceWorker()); - EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page. - - SetOnline(false); - EXPECT_TRUE(RegisterOneShot("foo")); - EXPECT_TRUE(UnregisterOneShot("foo")); - EXPECT_FALSE(GetRegistrationOneShot("foo")); -} - -IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, UnregisterTwice) { - EXPECT_TRUE(RegisterServiceWorker()); - EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page. - - SetOnline(false); - EXPECT_TRUE(RegisterOneShot("foo")); - EXPECT_TRUE(UnregisterOneShotTwice("foo")); - EXPECT_FALSE(GetRegistrationOneShot("foo")); -} - -IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, UnregisterMidSync) { - EXPECT_TRUE(RegisterServiceWorker()); - EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page. - - EXPECT_TRUE(RegisterOneShot("unregister")); - EXPECT_TRUE(PopConsole("ok - unregister completed")); -} - -IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, - CallFinishedBeforeSyncSucceeds) { - EXPECT_TRUE(RegisterServiceWorker()); - EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page. - - SetOnline(false); - EXPECT_TRUE(RegisterOneShot("foo")); - EXPECT_TRUE(NotifyWhenFinishedOneShot("foo")); - - SetOnline(true); - // The ordering of PopConsole messages tells us that the event fired - // before finished resolved. - EXPECT_TRUE(PopConsole("foo fired")); - EXPECT_TRUE(PopConsole("foo finished result: true")); -} - -IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, CallFinishedBeforeSyncFails) { - EXPECT_TRUE(RegisterServiceWorker()); - EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page. - - SetOnline(true); - EXPECT_TRUE(RegisterOneShot("delay")); - EXPECT_FALSE(OneShotPending("delay")); - EXPECT_TRUE(NotifyWhenFinishedOneShot("delay")); - - EXPECT_TRUE(RejectDelayedOneShot()); - // The ordering of PopConsole messages tells us that the event fired - // before finished resolved. - EXPECT_TRUE(PopConsole("ok - delay rejected")); - EXPECT_TRUE(PopConsole("delay finished result: false")); -} - -IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, - CallFinishedAfterSyncSucceeds) { - EXPECT_TRUE(RegisterServiceWorker()); - EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page. - - SetOnline(false); - EXPECT_TRUE(RegisterOneShot("foo")); - EXPECT_TRUE(StoreRegistrationOneShot("foo")); - - SetOnline(true); - EXPECT_TRUE(PopConsole("foo fired")); - EXPECT_FALSE(GetRegistrationOneShot("foo")); - EXPECT_TRUE(NotifyWhenFinishedImmediateOneShot("ok - foo result: true")); -} - -IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, - CallFinishedAfterSyncUnregistered) { - EXPECT_TRUE(RegisterServiceWorker()); - EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page. - - SetOnline(false); - EXPECT_TRUE(RegisterOneShot("foo")); - EXPECT_TRUE(StoreRegistrationOneShot("foo")); - EXPECT_TRUE(UnregisterOneShot("foo")); - EXPECT_FALSE(GetRegistrationOneShot("foo")); - EXPECT_TRUE(NotifyWhenFinishedImmediateOneShot("ok - foo result: false")); -} - -IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, CallFinishedAfterSyncFails) { - EXPECT_TRUE(RegisterServiceWorker()); - EXPECT_TRUE(LoadTestPage(kDefaultTestURL)); // Control the page. - - SetOnline(true); - EXPECT_TRUE(RegisterOneShot("delay")); - EXPECT_FALSE(OneShotPending("delay")); - EXPECT_TRUE(StoreRegistrationOneShot("delay")); - - EXPECT_TRUE(RejectDelayedOneShot()); - EXPECT_TRUE(PopConsole("ok - delay rejected")); - EXPECT_TRUE(NotifyWhenFinishedImmediateOneShot("ok - delay result: false")); -} - // Verify that a background sync registration is deleted when site data is // cleared. IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest,
diff --git a/content/browser/bluetooth/bluetooth_dispatcher_host.cc b/content/browser/bluetooth/bluetooth_dispatcher_host.cc index d310f111..dfeeaa6 100644 --- a/content/browser/bluetooth/bluetooth_dispatcher_host.cc +++ b/content/browser/bluetooth/bluetooth_dispatcher_host.cc
@@ -1219,8 +1219,8 @@ // compilers may evaluate arguments in any order. const std::string characteristic_instance_id = notify_session->GetCharacteristicIdentifier(); - characteristic_id_to_notify_session_.insert(characteristic_instance_id, - notify_session.Pass()); + characteristic_id_to_notify_session_.insert( + std::make_pair(characteristic_instance_id, notify_session.Pass())); Send(new BluetoothMsg_StartNotificationsSuccess(thread_id, request_id)); }
diff --git a/content/browser/bluetooth/bluetooth_dispatcher_host.h b/content/browser/bluetooth/bluetooth_dispatcher_host.h index 5fe1f90..a7f06bae 100644 --- a/content/browser/bluetooth/bluetooth_dispatcher_host.h +++ b/content/browser/bluetooth/bluetooth_dispatcher_host.h
@@ -5,8 +5,9 @@ #ifndef CONTENT_BROWSER_BLUETOOTH_BLUETOOTH_DISPATCHER_HOST_H_ #define CONTENT_BROWSER_BLUETOOTH_BLUETOOTH_DISPATCHER_HOST_H_ +#include <map> + #include "base/basictypes.h" -#include "base/containers/scoped_ptr_map.h" #include "base/id_map.h" #include "base/memory/scoped_vector.h" #include "base/memory/weak_ptr.h" @@ -257,8 +258,7 @@ // Map that matches characteristic_instance_id to notify session. // TODO(ortuno): Also key by thread_id once support for web workers, // is added: http://crbug.com/537372 - base::ScopedPtrMap<std::string, - scoped_ptr<device::BluetoothGattNotifySession>> + std::map<std::string, scoped_ptr<device::BluetoothGattNotifySession>> characteristic_id_to_notify_session_; // Map of characteristic_instance_id to a set of thread ids.
diff --git a/content/browser/frame_host/navigation_handle_impl.cc b/content/browser/frame_host/navigation_handle_impl.cc index 7ffc6b4..1330c8e6 100644 --- a/content/browser/frame_host/navigation_handle_impl.cc +++ b/content/browser/frame_host/navigation_handle_impl.cc
@@ -99,6 +99,10 @@ return frame_tree_node_->IsMainFrame(); } +const base::TimeTicks& NavigationHandleImpl::NavigationStart() { + return navigation_start_; +} + bool NavigationHandleImpl::IsPost() { CHECK_NE(INITIAL, state_) << "This accessor should not be called before the request is started.";
diff --git a/content/browser/frame_host/navigation_handle_impl.h b/content/browser/frame_host/navigation_handle_impl.h index b0a7b9a..004cf82 100644 --- a/content/browser/frame_host/navigation_handle_impl.h +++ b/content/browser/frame_host/navigation_handle_impl.h
@@ -70,6 +70,7 @@ // NavigationHandle implementation: const GURL& GetURL() override; bool IsInMainFrame() override; + const base::TimeTicks& NavigationStart() override; bool IsPost() override; const Referrer& GetReferrer() override; bool HasUserGesture() override; @@ -95,11 +96,6 @@ const GURL& new_referrer_url, bool new_is_external_protocol) override; - // The time the navigation started, recorded either in the renderer or browser - // process. Corresponds to Navigation Timing API. - // TODO(csharrison): Add this to the public class and mark this override. - const base::TimeTicks& navigation_start() { return navigation_start_; } - NavigatorDelegate* GetDelegate() const; void set_net_error_code(net::Error net_error_code) {
diff --git a/content/browser/presentation/presentation_service_impl.cc b/content/browser/presentation/presentation_service_impl.cc index 5d20a31..82abc8b 100644 --- a/content/browser/presentation/presentation_service_impl.cc +++ b/content/browser/presentation/presentation_service_impl.cc
@@ -200,7 +200,7 @@ render_process_id_, render_frame_id_, listener.get())) { - screen_availability_listeners_.set(availability_url, listener.Pass()); + screen_availability_listeners_[availability_url] = listener.Pass(); } else { DVLOG(1) << "AddScreenAvailabilityListener failed. Ignoring request."; } @@ -218,9 +218,7 @@ return; delegate_->RemoveScreenAvailabilityListener( - render_process_id_, - render_frame_id_, - listener_it->second); + render_process_id_, render_frame_id_, listener_it->second.get()); screen_availability_listeners_.erase(listener_it); }
diff --git a/content/browser/presentation/presentation_service_impl.h b/content/browser/presentation/presentation_service_impl.h index 6d48b7a..bbbfb58 100644 --- a/content/browser/presentation/presentation_service_impl.h +++ b/content/browser/presentation/presentation_service_impl.h
@@ -12,7 +12,6 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/containers/hash_tables.h" -#include "base/containers/scoped_ptr_map.h" #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/memory/linked_ptr.h" @@ -252,7 +251,7 @@ std::string default_presentation_url_; using ScreenAvailabilityListenerMap = - base::ScopedPtrMap<std::string, scoped_ptr<ScreenAvailabilityListenerImpl>>; + std::map<std::string, scoped_ptr<ScreenAvailabilityListenerImpl>>; ScreenAvailabilityListenerMap screen_availability_listeners_; // For StartSession requests.
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index 950d1cde..3f2ee640 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -229,6 +229,7 @@ CompositorImpl::CompositorImpl(CompositorClient* client, gfx::NativeWindow root_window) : root_layer_(cc::Layer::Create(Compositor::LayerSettings())), + resource_manager_(root_window), surface_id_allocator_(GetSurfaceManager() ? CreateSurfaceIdAllocator() : nullptr), has_transparent_background_(false),
diff --git a/content/child/blob_storage/blob_transport_controller.cc b/content/child/blob_storage/blob_transport_controller.cc index 42a4263..602860b 100644 --- a/content/child/blob_storage/blob_transport_controller.cc +++ b/content/child/blob_storage/blob_transport_controller.cc
@@ -49,7 +49,7 @@ scoped_ptr<BlobConsolidation> consolidation, IPC::Sender* sender) { BlobConsolidation* consolidation_ptr = consolidation.get(); - blob_storage_.insert(uuid, consolidation.Pass()); + blob_storage_.insert(std::make_pair(uuid, consolidation.Pass())); std::vector<storage::DataElement> descriptions; GetDescriptions(consolidation_ptr, kLargeThresholdBytes, &descriptions); // TODO(dmurph): Uncomment when IPC messages are added. @@ -188,7 +188,7 @@ if (it == blob_storage_.end()) return ResponsesStatus::BLOB_NOT_FOUND; - BlobConsolidation* consolidation = it->second; + BlobConsolidation* consolidation = it->second.get(); const auto& consolidated_items = consolidation->consolidated_items(); // Since we can be writing to the same shared memory handle from multiple
diff --git a/content/child/blob_storage/blob_transport_controller.h b/content/child/blob_storage/blob_transport_controller.h index 7b5714f..d594c53 100644 --- a/content/child/blob_storage/blob_transport_controller.h +++ b/content/child/blob_storage/blob_transport_controller.h
@@ -5,10 +5,10 @@ #ifndef CONTENT_CHILD_BLOB_STORAGE_BLOB_TRANSPORT_CONTROLLER_H_ #define CONTENT_CHILD_BLOB_STORAGE_BLOB_TRANSPORT_CONTROLLER_H_ +#include <map> #include <string> #include <vector> -#include "base/containers/scoped_ptr_map.h" #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/memory/ref_counted.h" @@ -114,7 +114,7 @@ void ReleaseBlobConsolidation(const std::string& uuid); - base::ScopedPtrMap<std::string, scoped_ptr<BlobConsolidation>> blob_storage_; + std::map<std::string, scoped_ptr<BlobConsolidation>> blob_storage_; DISALLOW_COPY_AND_ASSIGN(BlobTransportController); };
diff --git a/content/child/blob_storage/blob_transport_controller_unittest.cc b/content/child/blob_storage/blob_transport_controller_unittest.cc index 0ba23dd..6c5d48f5 100644 --- a/content/child/blob_storage/blob_transport_controller_unittest.cc +++ b/content/child/blob_storage/blob_transport_controller_unittest.cc
@@ -100,7 +100,8 @@ consolidation->AddDataItem(CreateData("Hello3")); // See the above test for the expected descriptions layout. - holder->blob_storage_.insert(kBlobUUID, make_scoped_ptr(consolidation)); + holder->blob_storage_.insert( + std::make_pair(kBlobUUID, make_scoped_ptr(consolidation))); std::vector<BlobItemBytesRequest> requests; std::vector<base::SharedMemoryHandle> memory_handles; @@ -158,7 +159,8 @@ consolidation->AddDataItem(CreateData("Hello3")); // See the above test for the expected descriptions layout. - holder->blob_storage_.insert(kBlobUUID, make_scoped_ptr(consolidation)); + holder->blob_storage_.insert( + std::make_pair(kBlobUUID, make_scoped_ptr(consolidation))); std::vector<BlobItemBytesRequest> requests; std::vector<base::SharedMemoryHandle> memory_handles; @@ -224,7 +226,8 @@ BlobConsolidation* consolidation = new BlobConsolidation(); consolidation->AddBlobItem(KRefBlobUUID, 10, 10); - holder->blob_storage_.insert(kBlobUUID, make_scoped_ptr(consolidation)); + holder->blob_storage_.insert( + std::make_pair(kBlobUUID, make_scoped_ptr(consolidation))); std::vector<BlobItemBytesRequest> requests; std::vector<base::SharedMemoryHandle> memory_handles;
diff --git a/content/child/resource_scheduling_filter.cc b/content/child/resource_scheduling_filter.cc index 6445c00..cad2f7d 100644 --- a/content/child/resource_scheduling_filter.cc +++ b/content/child/resource_scheduling_filter.cc
@@ -77,7 +77,8 @@ void ResourceSchedulingFilter::SetRequestIdTaskRunner( int id, scoped_ptr<blink::WebTaskRunner> web_task_runner) { base::AutoLock lock(request_id_to_task_runner_map_lock_); - request_id_to_task_runner_map_.insert(id, web_task_runner.Pass()); + request_id_to_task_runner_map_.insert( + std::make_pair(id, web_task_runner.Pass())); } void ResourceSchedulingFilter::ClearRequestIdTaskRunner(int id) {
diff --git a/content/child/resource_scheduling_filter.h b/content/child/resource_scheduling_filter.h index fd245592..99526fc 100644 --- a/content/child/resource_scheduling_filter.h +++ b/content/child/resource_scheduling_filter.h
@@ -8,7 +8,6 @@ #include <map> #include "base/containers/hash_tables.h" -#include "base/containers/scoped_ptr_map.h" #include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" #include "content/common/content_export.h" @@ -47,8 +46,8 @@ private: ~ResourceSchedulingFilter() override; - typedef base::ScopedPtrMap<int, scoped_ptr<blink::WebTaskRunner>> - RequestIdToTaskRunnerMap; + using RequestIdToTaskRunnerMap = + std::map<int, scoped_ptr<blink::WebTaskRunner>>; // This lock guards |request_id_to_task_runner_map_| base::Lock request_id_to_task_runner_map_lock_;
diff --git a/content/common/gpu/media/vt_video_decode_accelerator.cc b/content/common/gpu/media/vt_video_decode_accelerator.cc index 2947fe1..35e2753 100644 --- a/content/common/gpu/media/vt_video_decode_accelerator.cc +++ b/content/common/gpu/media/vt_video_decode_accelerator.cc
@@ -829,9 +829,10 @@ DCHECK(!picture_info_map_.count(picture.id())); assigned_picture_ids_.insert(picture.id()); available_picture_ids_.push_back(picture.id()); - picture_info_map_.insert(picture.id(), make_scoped_ptr(new PictureInfo( - picture.internal_texture_id(), - picture.texture_id()))); + picture_info_map_.insert(std::make_pair( + picture.id(), + make_scoped_ptr(new PictureInfo(picture.internal_texture_id(), + picture.texture_id())))); } // Pictures are not marked as uncleared until after this method returns, and @@ -844,7 +845,7 @@ void VTVideoDecodeAccelerator::ReusePictureBuffer(int32_t picture_id) { DCHECK(gpu_thread_checker_.CalledOnValidThread()); DCHECK(picture_info_map_.count(picture_id)); - PictureInfo* picture_info = picture_info_map_.find(picture_id)->second; + PictureInfo* picture_info = picture_info_map_.find(picture_id)->second.get(); DCHECK_EQ(CFGetRetainCount(picture_info->cv_image), 1); picture_info->cv_image.reset(); picture_info->gl_image->Destroy(false); @@ -1009,7 +1010,7 @@ int32_t picture_id = available_picture_ids_.back(); DCHECK(picture_info_map_.count(picture_id)); - PictureInfo* picture_info = picture_info_map_.find(picture_id)->second; + PictureInfo* picture_info = picture_info_map_.find(picture_id)->second.get(); DCHECK(!picture_info->cv_image); DCHECK(!picture_info->gl_image);
diff --git a/content/common/gpu/media/vt_video_decode_accelerator.h b/content/common/gpu/media/vt_video_decode_accelerator.h index c728968..9f55327 100644 --- a/content/common/gpu/media/vt_video_decode_accelerator.h +++ b/content/common/gpu/media/vt_video_decode_accelerator.h
@@ -10,7 +10,6 @@ #include <map> #include <queue> -#include "base/containers/scoped_ptr_map.h" #include "base/mac/scoped_cftyperef.h" #include "base/memory/linked_ptr.h" #include "base/memory/weak_ptr.h" @@ -226,7 +225,7 @@ std::set<int32_t> assigned_picture_ids_; // Texture IDs and image buffers of assigned pictures. - base::ScopedPtrMap<int32_t, scoped_ptr<PictureInfo>> picture_info_map_; + std::map<int32_t, scoped_ptr<PictureInfo>> picture_info_map_; // Pictures ready to be rendered to. std::vector<int32_t> available_picture_ids_;
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index 6fc80be..adc6ba0 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi
@@ -628,6 +628,8 @@ 'private_renderer_webrtc_sources': [ 'renderer/media/audio_repetition_detector.cc', 'renderer/media/audio_repetition_detector.h', + 'renderer/media/audio_track_recorder.cc', + 'renderer/media/audio_track_recorder.h', 'renderer/media/media_recorder_handler.cc', 'renderer/media/media_recorder_handler.h', 'renderer/media/media_stream.cc', @@ -800,6 +802,8 @@ ['OS=="android"', { 'sources!': [ 'renderer/media/audio_decoder.cc', + 'renderer/media/audio_track_recorder.cc', + 'renderer/media/audio_track_recorder.h', 'renderer/media/media_recorder_handler.cc', 'renderer/media/media_recorder_handler.h', 'renderer/media/video_track_recorder.cc',
diff --git a/content/content_tests.gypi b/content/content_tests.gypi index 64d2110..7895b59e 100644 --- a/content/content_tests.gypi +++ b/content/content_tests.gypi
@@ -749,6 +749,7 @@ 'browser/renderer_host/p2p/socket_host_udp_unittest.cc', 'browser/renderer_host/p2p/socket_host_unittest.cc', 'renderer/media/audio_repetition_detector_unittest.cc', + 'renderer/media/audio_track_recorder_unittest.cc', 'renderer/media/media_recorder_handler_unittest.cc', 'renderer/media/media_stream_audio_processor_unittest.cc', 'renderer/media/media_stream_constraints_util_unittest.cc', @@ -1249,6 +1250,7 @@ 'browser/power_usage_monitor_impl_unittest.cc', 'browser/renderer_host/begin_frame_observer_proxy_unittest.cc', 'browser/webui/url_data_manager_backend_unittest.cc', + 'renderer/media/audio_track_recorder_unittest.cc', 'renderer/media/media_recorder_handler_unittest.cc', 'renderer/media/video_track_recorder_unittest.cc', ],
diff --git a/content/public/browser/navigation_handle.h b/content/public/browser/navigation_handle.h index 3b2bbadd..cc96381 100644 --- a/content/public/browser/navigation_handle.h +++ b/content/public/browser/navigation_handle.h
@@ -39,6 +39,10 @@ // The WebContents the navigation is taking place in. WebContents* GetWebContents(); + // The time the navigation started, recorded either in the renderer or in the + // browser process. Corresponds to Navigation Timing API. + virtual const base::TimeTicks& NavigationStart() = 0; + // Parameters available at network request start time ------------------------ // // The following parameters are only available when the network request is
diff --git a/content/renderer/media/DEPS b/content/renderer/media/DEPS index 19fad4be..c7f6f64 100644 --- a/content/renderer/media/DEPS +++ b/content/renderer/media/DEPS
@@ -3,5 +3,6 @@ # For video copying, cropping and scaling. # TODO(wuchengli): remove this when RTCVideoEncoder supports zero copy. "+third_party/libyuv", + '+third_party/opus', '+third_party/webrtc_overrides', ]
diff --git a/content/renderer/media/audio_track_recorder.cc b/content/renderer/media/audio_track_recorder.cc new file mode 100644 index 0000000..006bcf3 --- /dev/null +++ b/content/renderer/media/audio_track_recorder.cc
@@ -0,0 +1,312 @@ +// Copyright 2015 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 "content/renderer/media/audio_track_recorder.h" + +#include "base/bind.h" +#include "base/stl_util.h" +#include "media/audio/audio_parameters.h" +#include "media/base/audio_bus.h" +#include "media/base/bind_to_current_loop.h" +#include "third_party/opus/src/include/opus.h" + +// Note that this code follows the Chrome media convention of defining a "frame" +// as "one multi-channel sample" as opposed to another common definition +// meaning "a chunk of samples". Here this second definition of "frame" is +// called a "buffer"; so what might be called "frame duration" is instead +// "buffer duration", and so on. + +namespace content { + +namespace { + +enum { + // This is the recommended value, according to documentation in + // third_party/opus/src/include/opus.h, so that the Opus encoder does not + // degrade the audio due to memory constraints. + OPUS_MAX_PAYLOAD_SIZE = 4000, + + // Support for max sampling rate of 48KHz, 2 channels, 60 ms duration. + MAX_SAMPLES_PER_BUFFER = 48 * 2 * 60, +}; + +} // anonymous namespace + +// Nested class encapsulating opus-related encoding details. +// AudioEncoder is created and destroyed on ATR's main thread (usually the +// main render thread) but otherwise should operate entirely on +// |encoder_thread_|, which is owned by AudioTrackRecorder. Be sure to delete +// |encoder_thread_| before deleting the AudioEncoder using it. +class AudioTrackRecorder::AudioEncoder + : public base::RefCountedThreadSafe<AudioEncoder> { + public: + explicit AudioEncoder(const OnEncodedAudioCB& on_encoded_audio_cb) + : on_encoded_audio_cb_(on_encoded_audio_cb), opus_encoder_(nullptr) { + // AudioEncoder is constructed on the thread that ATR lives on, but should + // operate only on the encoder thread after that. Reset + // |encoder_thread_checker_| here, as the next call to CalledOnValidThread() + // will be from the encoder thread. + encoder_thread_checker_.DetachFromThread(); + } + + void OnSetFormat(const media::AudioParameters& params); + + void EncodeAudio(scoped_ptr<media::AudioBus> audio_bus, + const base::TimeTicks& capture_time); + + private: + friend class base::RefCountedThreadSafe<AudioEncoder>; + + ~AudioEncoder(); + + bool is_initialized() const { return !!opus_encoder_; } + + void DestroyExistingOpusEncoder(); + + void TransferSamplesIntoBuffer(const media::AudioBus* audio_bus, + int source_offset, + int buffer_fill_offset, + int num_samples); + bool EncodeFromFilledBuffer(std::string* out); + + const OnEncodedAudioCB on_encoded_audio_cb_; + + base::ThreadChecker encoder_thread_checker_; + + // In the case where a call to EncodeAudio() cannot completely fill the + // buffer, this points to the position at which to populate data in a later + // call. + int buffer_fill_end_; + + int frames_per_buffer_; + + // The duration of one set of frames of encoded audio samples. + base::TimeDelta buffer_duration_; + + media::AudioParameters audio_params_; + + // Buffer for passing AudioBus data to OpusEncoder. + scoped_ptr<float[]> buffer_; + + OpusEncoder* opus_encoder_; + + DISALLOW_COPY_AND_ASSIGN(AudioEncoder); +}; + +AudioTrackRecorder::AudioEncoder::~AudioEncoder() { + // We don't DCHECK that we're on the encoder thread here, as it should have + // already been deleted at this point. + DestroyExistingOpusEncoder(); +} + +void AudioTrackRecorder::AudioEncoder::OnSetFormat( + const media::AudioParameters& params) { + DCHECK(encoder_thread_checker_.CalledOnValidThread()); + if (audio_params_.Equals(params)) + return; + + DestroyExistingOpusEncoder(); + + if (!params.IsValid()) { + DLOG(ERROR) << "Invalid audio params: " << params.AsHumanReadableString(); + return; + } + + buffer_duration_ = base::TimeDelta::FromMilliseconds( + AudioTrackRecorder::GetOpusBufferDuration(params.sample_rate())); + if (buffer_duration_ == base::TimeDelta()) { + DLOG(ERROR) << "Could not find a valid |buffer_duration| for the given " + << "sample rate: " << params.sample_rate(); + return; + } + + frames_per_buffer_ = + params.sample_rate() * buffer_duration_.InMilliseconds() / 1000; + if (frames_per_buffer_ * params.channels() > MAX_SAMPLES_PER_BUFFER) { + DLOG(ERROR) << "Invalid |frames_per_buffer_|: " << frames_per_buffer_; + return; + } + + // Initialize AudioBus buffer for OpusEncoder. + buffer_fill_end_ = 0; + buffer_.reset(new float[params.channels() * frames_per_buffer_]); + + // Initialize OpusEncoder. + int opus_result; + opus_encoder_ = opus_encoder_create(params.sample_rate(), params.channels(), + OPUS_APPLICATION_AUDIO, &opus_result); + if (opus_result < 0) { + DLOG(ERROR) << "Couldn't init opus encoder: " << opus_strerror(opus_result); + return; + } + + // Note: As of 2013-10-31, the encoder in "auto bitrate" mode would use a + // variable bitrate up to 102kbps for 2-channel, 48 kHz audio and a 10 ms + // buffer duration. The opus library authors may, of course, adjust this in + // later versions. + if (opus_encoder_ctl(opus_encoder_, OPUS_SET_BITRATE(OPUS_AUTO)) != OPUS_OK) { + DLOG(ERROR) << "Failed to set opus bitrate."; + return; + } + + audio_params_ = params; +} + +void AudioTrackRecorder::AudioEncoder::EncodeAudio( + scoped_ptr<media::AudioBus> audio_bus, + const base::TimeTicks& capture_time) { + DCHECK(encoder_thread_checker_.CalledOnValidThread()); + DCHECK_EQ(audio_bus->channels(), audio_params_.channels()); + + if (!is_initialized()) + return; + + base::TimeDelta buffer_fill_duration = + buffer_fill_end_ * buffer_duration_ / frames_per_buffer_; + base::TimeTicks buffer_capture_time = capture_time - buffer_fill_duration; + + // Encode all audio in |audio_bus| into zero or more packets. + int src_pos = 0; + while (src_pos < audio_bus->frames()) { + const int num_samples_to_xfer = std::min( + frames_per_buffer_ - buffer_fill_end_, audio_bus->frames() - src_pos); + TransferSamplesIntoBuffer(audio_bus.get(), src_pos, buffer_fill_end_, + num_samples_to_xfer); + src_pos += num_samples_to_xfer; + buffer_fill_end_ += num_samples_to_xfer; + + if (buffer_fill_end_ < frames_per_buffer_) + break; + + scoped_ptr<std::string> encoded_data(new std::string()); + if (EncodeFromFilledBuffer(encoded_data.get())) { + on_encoded_audio_cb_.Run(audio_params_, encoded_data.Pass(), + buffer_capture_time); + } + + // Reset the capture timestamp and internal buffer for next set of frames. + buffer_capture_time += buffer_duration_; + buffer_fill_end_ = 0; + } +} + +void AudioTrackRecorder::AudioEncoder::DestroyExistingOpusEncoder() { + // We don't DCHECK that we're on the encoder thread here, as this could be + // called from the dtor (main thread) or from OnSetForamt() (render thread); + if (opus_encoder_) { + opus_encoder_destroy(opus_encoder_); + opus_encoder_ = nullptr; + } +} + +void AudioTrackRecorder::AudioEncoder::TransferSamplesIntoBuffer( + const media::AudioBus* audio_bus, + int source_offset, + int buffer_fill_offset, + int num_samples) { + // TODO(ajose): Consider replacing with AudioBus::ToInterleaved(). + // http://crbug.com/547918 + DCHECK(encoder_thread_checker_.CalledOnValidThread()); + DCHECK(is_initialized()); + // Opus requires channel-interleaved samples in a single array. + for (int ch = 0; ch < audio_bus->channels(); ++ch) { + const float* src = audio_bus->channel(ch) + source_offset; + const float* const src_end = src + num_samples; + float* dest = + buffer_.get() + buffer_fill_offset * audio_params_.channels() + ch; + for (; src < src_end; ++src, dest += audio_params_.channels()) + *dest = *src; + } +} + +bool AudioTrackRecorder::AudioEncoder::EncodeFromFilledBuffer( + std::string* out) { + DCHECK(encoder_thread_checker_.CalledOnValidThread()); + DCHECK(is_initialized()); + + out->resize(OPUS_MAX_PAYLOAD_SIZE); + const opus_int32 result = opus_encode_float( + opus_encoder_, buffer_.get(), frames_per_buffer_, + reinterpret_cast<uint8*>(string_as_array(out)), OPUS_MAX_PAYLOAD_SIZE); + if (result > 1) { + // TODO(ajose): Investigate improving this. http://crbug.com/547918 + out->resize(result); + return true; + } + // If |result| in {0,1}, do nothing; the documentation says that a return + // value of zero or one means the packet does not need to be transmitted. + // Otherwise, we have an error. + DLOG_IF(ERROR, result < 0) << __FUNCTION__ + << " failed: " << opus_strerror(result); + return false; +} + +AudioTrackRecorder::AudioTrackRecorder( + const blink::WebMediaStreamTrack& track, + const OnEncodedAudioCB& on_encoded_audio_cb) + : track_(track), + encoder_(new AudioEncoder(media::BindToCurrentLoop(on_encoded_audio_cb))), + encoder_thread_("AudioEncoderThread") { + DCHECK(main_render_thread_checker_.CalledOnValidThread()); + DCHECK(!track_.isNull()); + DCHECK(track_.extraData()); + + // Start the |encoder_thread_|. From this point on, |encoder_| should work + // only on |encoder_thread_|, as enforced by DCHECKs. + DCHECK(!encoder_thread_.IsRunning()); + encoder_thread_.Start(); + + // Connect the source provider to the track as a sink. + MediaStreamAudioSink::AddToAudioTrack(this, track_); +} + +AudioTrackRecorder::~AudioTrackRecorder() { + DCHECK(main_render_thread_checker_.CalledOnValidThread()); + MediaStreamAudioSink::RemoveFromAudioTrack(this, track_); +} + +void AudioTrackRecorder::OnSetFormat(const media::AudioParameters& params) { + DCHECK(encoder_thread_.IsRunning()); + // If the source is restarted, might have changed to another capture thread. + capture_thread_checker_.DetachFromThread(); + DCHECK(capture_thread_checker_.CalledOnValidThread()); + + encoder_thread_.task_runner()->PostTask( + FROM_HERE, base::Bind(&AudioEncoder::OnSetFormat, encoder_, params)); +} + +void AudioTrackRecorder::OnData(const media::AudioBus& audio_bus, + base::TimeTicks capture_time) { + DCHECK(encoder_thread_.IsRunning()); + DCHECK(capture_thread_checker_.CalledOnValidThread()); + DCHECK(!capture_time.is_null()); + + scoped_ptr<media::AudioBus> audio_data = + media::AudioBus::Create(audio_bus.channels(), audio_bus.frames()); + audio_bus.CopyTo(audio_data.get()); + + encoder_thread_.task_runner()->PostTask( + FROM_HERE, base::Bind(&AudioEncoder::EncodeAudio, encoder_, + base::Passed(&audio_data), capture_time)); +} + +int AudioTrackRecorder::GetOpusBufferDuration(int sample_rate) { + // Valid buffer durations in millseconds. Note there are other valid + // durations for Opus, see https://tools.ietf.org/html/rfc6716#section-2.1.4 + // Descending order as longer durations can increase compression performance. + const std::vector<int> opus_valid_buffer_durations_ms = {60, 40, 20, 10}; + + // Search for a duration such that |sample_rate| % |buffers_per_second| == 0, + // where |buffers_per_second| = 1000ms / |possible_duration|. + for (auto possible_duration : opus_valid_buffer_durations_ms) { + if (sample_rate * possible_duration % 1000 == 0) { + return possible_duration; + } + } + + // Otherwise, couldn't find a good duration. + return 0; +} + +} // namespace content
diff --git a/content/renderer/media/audio_track_recorder.h b/content/renderer/media/audio_track_recorder.h new file mode 100644 index 0000000..353331c --- /dev/null +++ b/content/renderer/media/audio_track_recorder.h
@@ -0,0 +1,85 @@ +// Copyright 2015 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 CONTENT_RENDERER_MEDIA_AUDIO_TRACK_RECORDER_H_ +#define CONTENT_RENDERER_MEDIA_AUDIO_TRACK_RECORDER_H_ + +#include "base/callback.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "base/threading/thread.h" +#include "base/threading/thread_checker.h" +#include "base/time/time.h" +#include "content/public/renderer/media_stream_audio_sink.h" +#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" + +namespace media { +class AudioBus; +} // namespace media + +namespace content { + +// AudioTrackRecorder is a MediaStreamAudioSink that encodes the audio buses +// received from a Stream Audio Track. The class is constructed on a +// single thread (the main Render thread) but can recieve MediaStreamAudioSink- +// related calls on a different "live audio" thread (referred to internally as +// the "capture thread"). It owns an internal thread to use for encoding, on +// which lives an AudioEncoder (a private nested class of ATR) with its own +// threading subtleties, see the implementation file. +class CONTENT_EXPORT AudioTrackRecorder + : NON_EXPORTED_BASE(public MediaStreamAudioSink) { + public: + using OnEncodedAudioCB = + base::Callback<void(const media::AudioParameters& params, + scoped_ptr<std::string> encoded_data, + base::TimeTicks capture_time)>; + + AudioTrackRecorder(const blink::WebMediaStreamTrack& track, + const OnEncodedAudioCB& on_encoded_audio_cb); + ~AudioTrackRecorder() override; + + // Implement MediaStreamAudioSink. + void OnSetFormat(const media::AudioParameters& params) override; + void OnData(const media::AudioBus& audio_bus, + base::TimeTicks capture_time) override; + + private: + friend class AudioTrackRecorderTest; + class AudioParameters; + + // Forward declaration of nested class for handling encoding. + // See the implementation file for details. + class AudioEncoder; + + // Returns the Opus buffer duration in milliseconds, or zero if none will work + // for the given |sample_rate|. + static int GetOpusBufferDuration(int sample_rate); + + // Used to check that we are destroyed on the same thread we were created on. + base::ThreadChecker main_render_thread_checker_; + + // Used to check that MediaStreamAudioSink's methods are called on the + // capture audio thread. + base::ThreadChecker capture_thread_checker_; + + // We need to hold on to the Blink track to remove ourselves on destruction. + const blink::WebMediaStreamTrack track_; + + // Thin wrapper around OpusEncoder. + // |encoder_| should be initialized before |encoder_thread_| such that + // |encoder_thread_| is destructed first. This, combined with all + // AudioEncoder work (aside from construction and destruction) happening on + // |encoder_thread_|, should allow us to be sure that all AudioEncoder work is + // done by the time we destroy it on ATR's thread. + const scoped_refptr<AudioEncoder> encoder_; + // The thread on which |encoder_| works. + base::Thread encoder_thread_; + + DISALLOW_COPY_AND_ASSIGN(AudioTrackRecorder); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_MEDIA_AUDIO_TRACK_RECORDER_H_
diff --git a/content/renderer/media/audio_track_recorder_unittest.cc b/content/renderer/media/audio_track_recorder_unittest.cc new file mode 100644 index 0000000..1966464 --- /dev/null +++ b/content/renderer/media/audio_track_recorder_unittest.cc
@@ -0,0 +1,253 @@ +// Copyright 2015 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 "content/renderer/media/audio_track_recorder.h" + +#include "base/run_loop.h" +#include "base/stl_util.h" +#include "base/strings/utf_string_conversions.h" +#include "content/renderer/media/media_stream_audio_source.h" +#include "content/renderer/media/mock_media_constraint_factory.h" +#include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h" +#include "content/renderer/media/webrtc_local_audio_track.h" +#include "media/audio/simple_sources.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/WebKit/public/web/WebHeap.h" +#include "third_party/opus/src/include/opus.h" + +using ::testing::_; +using ::testing::DoAll; +using ::testing::InSequence; +using ::testing::Mock; +using ::testing::Return; +using ::testing::SaveArg; +using ::testing::TestWithParam; +using ::testing::ValuesIn; + +namespace { + +// Input audio format. +const media::AudioParameters::Format kDefaultInputFormat = + media::AudioParameters::AUDIO_PCM_LOW_LATENCY; +const int kDefaultBitsPerSample = 16; +const int kDefaultSampleRate = 48000; +// The |frames_per_buffer| field of AudioParameters is not used by ATR. +const int kIgnoreFramesPerBuffer = 1; +const int kOpusMaxBufferDurationMS = 120; + +} // namespace + +namespace content { + +ACTION_P(RunClosure, closure) { + closure.Run(); +} + +struct ATRTestParams { + const media::AudioParameters::Format input_format; + const media::ChannelLayout channel_layout; + const int sample_rate; + const int bits_per_sample; +}; + +const ATRTestParams kATRTestParams[] = { + // Equivalent to default settings: + {media::AudioParameters::AUDIO_PCM_LOW_LATENCY, /* input format */ + media::CHANNEL_LAYOUT_STEREO, /* channel layout */ + kDefaultSampleRate, /* sample rate */ + kDefaultBitsPerSample}, /* bits per sample */ + // Change to mono: + {media::AudioParameters::AUDIO_PCM_LOW_LATENCY, media::CHANNEL_LAYOUT_MONO, + kDefaultSampleRate, kDefaultBitsPerSample}, + // Different sampling rate as well: + {media::AudioParameters::AUDIO_PCM_LOW_LATENCY, media::CHANNEL_LAYOUT_MONO, + 24000, kDefaultBitsPerSample}, + {media::AudioParameters::AUDIO_PCM_LOW_LATENCY, + media::CHANNEL_LAYOUT_STEREO, 8000, kDefaultBitsPerSample}, +}; + +class AudioTrackRecorderTest : public TestWithParam<ATRTestParams> { + public: + // Initialize |first_params_| based on test parameters, and |second_params_| + // to always be the same thing. + AudioTrackRecorderTest() + : first_params_(GetParam().input_format, + GetParam().channel_layout, + GetParam().sample_rate, + GetParam().bits_per_sample, + kIgnoreFramesPerBuffer), + second_params_(kDefaultInputFormat, + media::CHANNEL_LAYOUT_STEREO, + kDefaultSampleRate, + kDefaultBitsPerSample, + kIgnoreFramesPerBuffer), + first_source_(first_params_.channels(), /* # channels */ + 440, /* frequency */ + first_params_.sample_rate()), /* sample rate */ + second_source_(second_params_.channels(), + 440, + second_params_.sample_rate()), + opus_decoder_(nullptr) { + ResetDecoder(first_params_); + PrepareBlinkTrack(); + audio_track_recorder_.reset(new AudioTrackRecorder( + blink_track_, base::Bind(&AudioTrackRecorderTest::OnEncodedAudio, + base::Unretained(this)))); + } + + ~AudioTrackRecorderTest() { + opus_decoder_destroy(opus_decoder_); + opus_decoder_ = nullptr; + audio_track_recorder_.reset(); + blink_track_.reset(); + blink::WebHeap::collectAllGarbageForTesting(); + } + + void ResetDecoder(const media::AudioParameters& params) { + if (opus_decoder_) { + opus_decoder_destroy(opus_decoder_); + opus_decoder_ = nullptr; + } + + int error; + opus_decoder_ = + opus_decoder_create(params.sample_rate(), params.channels(), &error); + EXPECT_TRUE(error == OPUS_OK && opus_decoder_); + + max_frames_per_buffer_ = + kOpusMaxBufferDurationMS * params.sample_rate() / 1000; + buffer_.reset(new float[max_frames_per_buffer_ * params.channels()]); + } + + scoped_ptr<media::AudioBus> GetFirstSourceAudioBus() { + scoped_ptr<media::AudioBus> bus(media::AudioBus::Create( + first_params_.channels(), + first_params_.sample_rate() * + audio_track_recorder_->GetOpusBufferDuration( + first_params_.sample_rate()) / + 1000)); + first_source_.OnMoreData(bus.get(), 0); + return bus.Pass(); + } + scoped_ptr<media::AudioBus> GetSecondSourceAudioBus() { + scoped_ptr<media::AudioBus> bus(media::AudioBus::Create( + second_params_.channels(), + second_params_.sample_rate() * + audio_track_recorder_->GetOpusBufferDuration( + second_params_.sample_rate()) / + 1000)); + second_source_.OnMoreData(bus.get(), 0); + return bus.Pass(); + } + + MOCK_METHOD3(DoOnEncodedAudio, + void(const media::AudioParameters& params, + std::string encoded_data, + base::TimeTicks timestamp)); + + void OnEncodedAudio(const media::AudioParameters& params, + scoped_ptr<std::string> encoded_data, + base::TimeTicks timestamp) { + EXPECT_TRUE(!encoded_data->empty()); + + // Decode |encoded_data| and check we get the expected number of frames + // per buffer. + EXPECT_EQ( + params.sample_rate() * + audio_track_recorder_->GetOpusBufferDuration(params.sample_rate()) / + 1000, + opus_decode_float( + opus_decoder_, + reinterpret_cast<uint8*>(string_as_array(encoded_data.get())), + encoded_data->size(), buffer_.get(), max_frames_per_buffer_, 0)); + + DoOnEncodedAudio(params, *encoded_data, timestamp); + } + + const base::MessageLoop message_loop_; + + // ATR and WebMediaStreamTrack for fooling it. + scoped_ptr<AudioTrackRecorder> audio_track_recorder_; + blink::WebMediaStreamTrack blink_track_; + + // Two different sets of AudioParameters for testing re-init of ATR. + const media::AudioParameters first_params_; + const media::AudioParameters second_params_; + + // AudioSources for creating AudioBuses. + media::SineWaveAudioSource first_source_; + media::SineWaveAudioSource second_source_; + + // Decoder for verifying data was properly encoded. + OpusDecoder* opus_decoder_; + int max_frames_per_buffer_; + scoped_ptr<float[]> buffer_; + + private: + // Prepares a blink track of a given MediaStreamType and attaches the native + // track, which can be used to capture audio data and pass it to the producer. + // Adapted from media::WebRTCLocalAudioSourceProviderTest. + void PrepareBlinkTrack() { + MockMediaConstraintFactory constraint_factory; + scoped_refptr<WebRtcAudioCapturer> capturer( + WebRtcAudioCapturer::CreateCapturer( + -1, StreamDeviceInfo(), + constraint_factory.CreateWebMediaConstraints(), NULL, NULL)); + scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter( + WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL)); + scoped_ptr<WebRtcLocalAudioTrack> native_track( + new WebRtcLocalAudioTrack(adapter.get(), capturer, NULL)); + blink::WebMediaStreamSource audio_source; + audio_source.initialize(base::UTF8ToUTF16("dummy_source_id"), + blink::WebMediaStreamSource::TypeAudio, + base::UTF8ToUTF16("dummy_source_name"), + false /* remote */, true /* readonly */); + blink_track_.initialize(blink::WebString::fromUTF8("audio_track"), + audio_source); + blink_track_.setExtraData(native_track.release()); + } + + DISALLOW_COPY_AND_ASSIGN(AudioTrackRecorderTest); +}; + +TEST_P(AudioTrackRecorderTest, OnData) { + InSequence s; + base::RunLoop run_loop; + base::Closure quit_closure = run_loop.QuitClosure(); + + // Give ATR initial audio parameters. + audio_track_recorder_->OnSetFormat(first_params_); + // TODO(ajose): consider adding WillOnce(SaveArg...) and inspecting, as done + // in VTR unittests. http://crbug.com/548856 + const base::TimeTicks time1 = base::TimeTicks::Now(); + EXPECT_CALL(*this, DoOnEncodedAudio(_, _, time1)).Times(1); + audio_track_recorder_->OnData(*GetFirstSourceAudioBus(), time1); + + // Send more audio. + const base::TimeTicks time2 = base::TimeTicks::Now(); + EXPECT_CALL(*this, DoOnEncodedAudio(_, _, _)) + .Times(1) + // Only reset the decoder once we've heard back: + .WillOnce(RunClosure(base::Bind(&AudioTrackRecorderTest::ResetDecoder, + base::Unretained(this), second_params_))); + audio_track_recorder_->OnData(*GetFirstSourceAudioBus(), time2); + + // Give ATR new audio parameters. + audio_track_recorder_->OnSetFormat(second_params_); + + // Send audio with different params. + const base::TimeTicks time3 = base::TimeTicks::Now(); + EXPECT_CALL(*this, DoOnEncodedAudio(_, _, _)) + .Times(1) + .WillOnce(RunClosure(quit_closure)); + audio_track_recorder_->OnData(*GetSecondSourceAudioBus(), time3); + + run_loop.Run(); + Mock::VerifyAndClearExpectations(this); +} + +INSTANTIATE_TEST_CASE_P(, AudioTrackRecorderTest, ValuesIn(kATRTestParams)); + +} // namespace content
diff --git a/content/renderer/presentation/presentation_dispatcher.cc b/content/renderer/presentation/presentation_dispatcher.cc index bcb33fa..4826e5a 100644 --- a/content/renderer/presentation/presentation_dispatcher.cc +++ b/content/renderer/presentation/presentation_dispatcher.cc
@@ -223,9 +223,9 @@ auto status_it = availability_status_.find(availability_url); if (status_it == availability_status_.end()) { status = new AvailabilityStatus(availability_url); - availability_status_.set(availability_url, make_scoped_ptr(status)); + availability_status_[availability_url] = make_scoped_ptr(status); } else { - status = status_it->second; + status = status_it->second.get(); } DCHECK(status); @@ -249,7 +249,7 @@ return; } status_it->second->availability_observers.insert(observer); - UpdateListeningState(status_it->second); + UpdateListeningState(status_it->second.get()); } void PresentationDispatcher::stopListening( @@ -262,7 +262,7 @@ return; } status_it->second->availability_observers.erase(observer); - UpdateListeningState(status_it->second); + UpdateListeningState(status_it->second.get()); } void PresentationDispatcher::setDefaultPresentationUrl( @@ -290,7 +290,7 @@ auto status_it = availability_status_.find(availability_url); if (status_it == availability_status_.end()) return; - AvailabilityStatus* status = status_it->second; + AvailabilityStatus* status = status_it->second.get(); DCHECK(status); if (status->listening_state == ListeningState::WAITING) @@ -314,7 +314,7 @@ auto status_it = availability_status_.find(availability_url); if (status_it == availability_status_.end()) return; - AvailabilityStatus* status = status_it->second; + AvailabilityStatus* status = status_it->second.get(); DCHECK(status); DCHECK(status->listening_state == ListeningState::WAITING);
diff --git a/content/renderer/presentation/presentation_dispatcher.h b/content/renderer/presentation/presentation_dispatcher.h index c96789c..1bf5559 100644 --- a/content/renderer/presentation/presentation_dispatcher.h +++ b/content/renderer/presentation/presentation_dispatcher.h
@@ -5,10 +5,10 @@ #ifndef CONTENT_RENDERER_PRESENTATION_PRESENTATION_DISPATCHER_H_ #define CONTENT_RENDERER_PRESENTATION_PRESENTATION_DISPATCHER_H_ +#include <map> #include <queue> #include "base/compiler_specific.h" -#include "base/containers/scoped_ptr_map.h" #include "base/id_map.h" #include "base/memory/linked_ptr.h" #include "base/memory/scoped_ptr.h" @@ -151,9 +151,7 @@ AvailabilityObserversSet availability_observers; }; - using AvailabilityStatusMap = - base::ScopedPtrMap<std::string, scoped_ptr<AvailabilityStatus>>; - AvailabilityStatusMap availability_status_; + std::map<std::string, scoped_ptr<AvailabilityStatus>> availability_status_; // Updates the listening state of availability for |status| and notifies the // client.
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 503aee2d..c9f5fa0 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -658,6 +658,7 @@ if (is_android) { sources -= [ + "../renderer/media/audio_track_recorder_unittest.cc", "../renderer/media/media_recorder_handler_unittest.cc", "../renderer/media/video_track_recorder_unittest.cc", ]
diff --git a/content/test/data/background_sync/background_sync_test_helpers.js b/content/test/data/background_sync/background_sync_test_helpers.js index b4cd8b6..7900526 100644 --- a/content/test/data/background_sync/background_sync_test_helpers.js +++ b/content/test/data/background_sync/background_sync_test_helpers.js
@@ -5,7 +5,6 @@ 'use strict'; var resultQueue = new ResultQueue(); -var registrationReference = null; // Sends data back to the test. This must be in response to an earlier // request, but it's ok to respond asynchronously. The request blocks until @@ -35,9 +34,9 @@ function registerOneShot(tag) { navigator.serviceWorker.ready .then(function(swRegistration) { - return swRegistration.sync.register({'tag': tag}); + return swRegistration.sync.register(tag); }) - .then(function(syncRegistration) { + .then(function() { sendResultToTest('ok - ' + tag + ' registered'); }) .catch(sendErrorToTest); @@ -52,56 +51,18 @@ .catch(sendErrorToTest); } -function unregisterOneShot(tag) { - navigator.serviceWorker.ready - .then(function(swRegistration) { - return swRegistration.sync.getRegistration(tag); - }) - .then(function(syncRegistration) { - if (!syncRegistration) { - sendResultToTest('error - ' + tag + ' not found'); - return; - } - return syncRegistration.unregister(); - }) - .then(function() { - sendResultToTest('ok - ' + tag + ' unregistered'); - }) - .catch(sendErrorToTest); -} - -function unregisterOneShotTwice(tag) { - navigator.serviceWorker.ready - .then(function(swRegistration) { - return swRegistration.sync.getRegistration(tag); - }) - .then(function(syncRegistration) { - if (!syncRegistration) { - sendResultToTest('error - ' + tag + ' not found'); - return; - } - return syncRegistration.unregister(); - }) - .then(function() { - return syncRegistration.unregister(); - }) - .then(sendErrorToTest, function() { - sendResultToTest('ok - ' + tag + ' failed to unregister twice'); - }) - .catch(sendErrorToTest); -} - function getRegistrationOneShot(tag) { navigator.serviceWorker.ready .then(function(swRegistration) { - return swRegistration.sync.getRegistration(tag); + return swRegistration.sync.getTags(); }) - .then(function(syncRegistration) { - if (!syncRegistration) { + .then(function(tags) { + if (tags.indexOf(tag) >= 0) { + sendResultToTest('ok - ' + tag + ' found'); + } else { sendResultToTest('error - ' + tag + ' not found'); return; } - sendResultToTest('ok - ' + tag + ' found'); }) .catch(sendErrorToTest); } @@ -119,12 +80,9 @@ function getRegistrationsOneShot(tag) { navigator.serviceWorker.ready .then(function(swRegistration) { - return swRegistration.sync.getRegistrations(); + return swRegistration.sync.getTags(); }) - .then(function(syncRegistrations) { - var tags = syncRegistrations.map(function(syncRegistration) { - return syncRegistration.tag; - }); + .then(function(tags) { sendResultToTest('ok - ' + tags.toString()); }) .catch(sendErrorToTest); @@ -157,44 +115,6 @@ .catch(sendErrorToTest); } -function notifyWhenFinishedOneShot(tag) { - navigator.serviceWorker.ready - .then(function(swRegistration) { - swRegistration.active.postMessage( - {action: 'notifyWhenFinished', tag: tag}); - }) - .catch(sendErrorToTest); -} - -function notifyWhenFinishedImmediateOneShot(tag) { - if (registrationReference == null) { - sendResultToTest('error - must call storeRegistration first'); - return; - } - - registrationReference.finished - .then(function(success) { - sendResultToTest('ok - ' + registrationReference.tag + - ' result: true') - }, function(err) { - sendResultToTest('ok - ' + registrationReference.tag + - ' result: false') - }) - .catch(sendErrorToTest) -} - - -function storeRegistration(tag) { - navigator.serviceWorker.ready - .then(function(swRegistration) { - return swRegistration.sync.getRegistration(tag); - }) - .then(function(syncRegistration) { - registrationReference = syncRegistration; - sendResultToTest('ok - ' + tag + ' stored'); - }) - .catch(sendErrorToTest); -} // Queue storing asynchronous results received from the Service Worker. Results // are sent to the test when requested.
diff --git a/content/test/data/background_sync/service_worker.js b/content/test/data/background_sync/service_worker.js index 6fedae8..e04bf30d 100644 --- a/content/test/data/background_sync/service_worker.js +++ b/content/test/data/background_sync/service_worker.js
@@ -9,7 +9,6 @@ // "delay" - Delays finishing the sync event with event.waitUntil. // Send a postMessage of "completeDelayedOneShot" to finish the // event. -// "unregister" - Unregisters the sync registration from within the sync event. 'use strict'; @@ -38,25 +37,10 @@ sendMessageToClients('sync', 'ok - delay rejected'); } - if (event.data['action'] === 'notifyWhenFinished') { - var tag = event.data['tag']; - registration.sync.getRegistration(tag) - .then(function (syncRegistration) { - sendMessageToClients('sync', 'ok - ' + tag + ' finished'); - return syncRegistration.finished; - }) - .then(function() { - sendMessageToClients('sync', tag + " finished result: true"); - }, function(error) { - sendMessageToClients('sync', tag + " finished result: false"); - }) - .catch(sendSyncErrorToClients); - } - if (event.data['action'] === 'registerOneShot') { var tag = event.data['tag']; - registration.sync.register({'tag': tag}) - .then(function (syncRegistration) { + registration.sync.register(tag) + .then(function () { sendMessageToClients('register', 'ok - ' + tag + ' registered in SW'); }) .catch(sendSyncErrorToClients); @@ -64,23 +48,21 @@ if (event.data['action'] === 'getRegistrationOneShot') { var tag = event.data['tag']; - registration.sync.getRegistration(tag) - .then(function(syncRegistration) { - if (!syncRegistration) { + registration.sync.getTags(tag) + .then(function(tags) { + if (tags.indexOf(tag) >= 0) { + sendMessageToClients('register', 'ok - ' + tag + ' found'); + } else { sendMessageToClients('register', 'error - ' + tag + ' not found'); return; } - sendMessageToClients('register', 'ok - ' + tag + ' found'); }) .catch(sendSyncErrorToClients); } if (event.data['action'] === 'getRegistrationsOneShot') { - registration.sync.getRegistrations() - .then(function(syncRegistrations) { - var tags = syncRegistrations.map(function(syncRegistration) { - return syncRegistration.tag; - }); + registration.sync.getTags() + .then(function(tags) { sendMessageToClients('register', 'ok - ' + tags.toString()); }) .catch(sendSyncErrorToClients); @@ -103,17 +85,12 @@ sendMessageToClients('sync', 'error - wrong wait until type'); } - if (event.registration === undefined) { - sendMessageToClients('sync', 'error - event missing registration'); - return; - } - - if (event.registration.tag === undefined) { + if (event.tag === undefined) { sendMessageToClients('sync', 'error - registration missing tag'); return; } - var tag = event.registration.tag; + var tag = event.tag; if (tag === 'delay') { var syncPromise = new Promise(function(resolve, reject) { @@ -124,14 +101,6 @@ return; } - if (tag === 'unregister') { - event.waitUntil(event.registration.unregister() - .then(function() { - sendMessageToClients('sync', 'ok - unregister completed'); - })); - return; - } - sendMessageToClients('sync', tag + ' fired'); };
diff --git a/device/usb/BUILD.gn b/device/usb/BUILD.gn index c30ae56..8a9f47f7 100644 --- a/device/usb/BUILD.gn +++ b/device/usb/BUILD.gn
@@ -4,7 +4,7 @@ import("//build/config/features.gni") -assert(!is_android && !is_ios) +assert(!is_ios) source_ids = "//third_party/usb_ids/usb.ids" generated_ids = "$target_gen_dir/usb_ids_gen.cc" @@ -57,6 +57,11 @@ "//dbus", ] } + + # TODO(moshayedi): crbug.com/549257. Add USB support for Aura on Android. + if (is_android) { + deps -= [ "//third_party/libusb" ] + } } source_set("mocks") {
diff --git a/extensions/browser/api/serial/serial_api.cc b/extensions/browser/api/serial/serial_api.cc index de70d1a..9b8a89d 100644 --- a/extensions/browser/api/serial/serial_api.cc +++ b/extensions/browser/api/serial/serial_api.cc
@@ -85,11 +85,14 @@ void SerialGetDevicesFunction::Work() { DCHECK_CURRENTLY_ON(BrowserThread::FILE); +// TODO(moshayedi): crbug.com/549257. Add USB support for Aura on Android. +#if !defined(OS_ANDROID) scoped_ptr<device::SerialDeviceEnumerator> enumerator = device::SerialDeviceEnumerator::Create(); mojo::Array<device::serial::DeviceInfoPtr> devices = enumerator->GetDevices(); results_ = serial::GetDevices::Results::Create( devices.To<std::vector<linked_ptr<serial::DeviceInfo> > >()); +#endif } SerialConnectFunction::SerialConnectFunction() {
diff --git a/extensions/browser/guest_view/web_view/web_view_guest.cc b/extensions/browser/guest_view/web_view/web_view_guest.cc index 4dedeee8..1715b356 100644 --- a/extensions/browser/guest_view/web_view/web_view_guest.cc +++ b/extensions/browser/guest_view/web_view/web_view_guest.cc
@@ -129,6 +129,9 @@ #endif case base::TERMINATION_STATUS_PROCESS_WAS_KILLED: return "killed"; +#if defined(OS_ANDROID) + case base::TERMINATION_STATUS_OOM_PROTECTED: +#endif case base::TERMINATION_STATUS_PROCESS_CRASHED: return "crashed"; case base::TERMINATION_STATUS_LAUNCH_FAILED:
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 97427fe9..0b957479 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -9398,16 +9398,12 @@ Texture::ImageState image_state; gl::GLImage* image = ref->texture()->GetLevelImage(ref->texture()->target(), 0, &image_state); - if (!image) { + if (!image || image_state != Texture::BOUND) { LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glScheduleOverlayPlaneCHROMIUM", "unsupported texture format"); return error::kNoError; } - if (image_state != Texture::BOUND) { - // No-op case for pass-through overlays (such as on Chromecast). - return error::kNoError; - } gfx::OverlayTransform transform = GetGFXOverlayTransform(c.plane_transform); if (transform == gfx::OVERLAY_TRANSFORM_INVALID) { LOCAL_SET_GL_ERROR(GL_INVALID_ENUM,
diff --git a/headless/OWNERS b/headless/OWNERS new file mode 100644 index 0000000..f845aaa --- /dev/null +++ b/headless/OWNERS
@@ -0,0 +1,2 @@ +skyostil@chromium.org +alexclarke@chromium.org
diff --git a/ios/chrome/browser/passwords/ios_chrome_password_store_factory.cc b/ios/chrome/browser/passwords/ios_chrome_password_store_factory.cc index ecae3055..fe82ae7 100644 --- a/ios/chrome/browser/passwords/ios_chrome_password_store_factory.cc +++ b/ios/chrome/browser/passwords/ios_chrome_password_store_factory.cc
@@ -14,7 +14,6 @@ #include "components/password_manager/core/browser/login_database.h" #include "components/password_manager/core/browser/password_store_default.h" #include "components/password_manager/core/browser/password_store_factory_util.h" -#include "components/password_manager/core/browser/password_store_service.h" #include "components/sync_driver/sync_service.h" #include "ios/chrome/browser/browser_state/browser_state_otr_helper.h" #include "ios/chrome/browser/sync/glue/sync_start_util.h" @@ -28,12 +27,14 @@ IOSChromePasswordStoreFactory::GetForBrowserState( ios::ChromeBrowserState* browser_state, ServiceAccessType access_type) { - password_manager::PasswordStoreService* service = - static_cast<password_manager::PasswordStoreService*>( - GetInstance()->GetServiceForBrowserState(browser_state, true)); - - return password_manager::GetPasswordStoreFromService( - service, access_type, browser_state->IsOffTheRecord()); + // |profile| gets always redirected to a non-Incognito profile below, so + // Incognito & IMPLICIT_ACCESS means that incognito browsing session would + // result in traces in the normal profile without the user knowing it. + if (access_type == ServiceAccessType::IMPLICIT_ACCESS && + browser_state->IsOffTheRecord()) + return nullptr; + return make_scoped_refptr(static_cast<password_manager::PasswordStore*>( + GetInstance()->GetServiceForBrowserState(browser_state, true).get())); } // static @@ -58,7 +59,7 @@ } IOSChromePasswordStoreFactory::IOSChromePasswordStoreFactory() - : BrowserStateKeyedServiceFactory( + : RefcountedBrowserStateKeyedServiceFactory( "PasswordStore", BrowserStateDependencyManager::GetInstance()) { DependsOn(ios::WebDataServiceFactory::GetInstance()); @@ -66,7 +67,8 @@ IOSChromePasswordStoreFactory::~IOSChromePasswordStoreFactory() {} -scoped_ptr<KeyedService> IOSChromePasswordStoreFactory::BuildServiceInstanceFor( +scoped_refptr<RefcountedKeyedService> +IOSChromePasswordStoreFactory::BuildServiceInstanceFor( web::BrowserState* context) const { scoped_ptr<password_manager::LoginDatabase> login_db( password_manager::CreateLoginDatabase(context->GetStatePath())); @@ -79,9 +81,14 @@ scoped_refptr<password_manager::PasswordStore> store = new password_manager::PasswordStoreDefault( main_thread_runner, db_thread_runner, login_db.Pass()); - return password_manager::BuildServiceInstanceFromStore( - store, ios::sync_start_util::GetFlareForSyncableService( - context->GetStatePath())); + if (!store->Init(ios::sync_start_util::GetFlareForSyncableService( + context->GetStatePath()))) { + // TODO(crbug.com/479725): Remove the LOG once this error is visible in the + // UI. + LOG(WARNING) << "Could not initialize password store."; + return nullptr; + } + return store; } web::BrowserState* IOSChromePasswordStoreFactory::GetBrowserStateToUse(
diff --git a/ios/chrome/browser/passwords/ios_chrome_password_store_factory.h b/ios/chrome/browser/passwords/ios_chrome_password_store_factory.h index 506737c9..7fec1a2 100644 --- a/ios/chrome/browser/passwords/ios_chrome_password_store_factory.h +++ b/ios/chrome/browser/passwords/ios_chrome_password_store_factory.h
@@ -7,7 +7,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "components/keyed_service/ios/browser_state_keyed_service_factory.h" +#include "components/keyed_service/ios/refcounted_browser_state_keyed_service_factory.h" enum class ServiceAccessType; @@ -26,7 +26,8 @@ // Singleton that owns all PasswordStores and associates them with // ios::ChromeBrowserState. -class IOSChromePasswordStoreFactory : public BrowserStateKeyedServiceFactory { +class IOSChromePasswordStoreFactory + : public RefcountedBrowserStateKeyedServiceFactory { public: static scoped_refptr<password_manager::PasswordStore> GetForBrowserState( ios::ChromeBrowserState* browser_state, @@ -46,7 +47,7 @@ ~IOSChromePasswordStoreFactory() override; // BrowserStateKeyedServiceFactory: - scoped_ptr<KeyedService> BuildServiceInstanceFor( + scoped_refptr<RefcountedKeyedService> BuildServiceInstanceFor( web::BrowserState* context) const override; web::BrowserState* GetBrowserStateToUse( web::BrowserState* context) const override;
diff --git a/ios/chrome/browser/ui/uikit_ui_util.mm b/ios/chrome/browser/ui/uikit_ui_util.mm index 09fc391c..c510950 100644 --- a/ios/chrome/browser/ui/uikit_ui_util.mm +++ b/ios/chrome/browser/ui/uikit_ui_util.mm
@@ -13,6 +13,7 @@ #include "base/ios/ios_util.h" #include "base/logging.h" #include "base/mac/foundation_util.h" +#include "ios/chrome/browser/experimental_flags.h" #include "ios/chrome/browser/ui/ui_util.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util_mac.h" @@ -152,8 +153,12 @@ UIImage* CaptureView(UIView* view, CGFloat scale) { UIGraphicsBeginImageContextWithOptions(view.bounds.size, YES /* opaque */, scale); - CGContext* context = UIGraphicsGetCurrentContext(); - [view.layer renderInContext:context]; + if (experimental_flags::IsWKWebViewEnabled()) { + [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:NO]; + } else { + CGContext* context = UIGraphicsGetCurrentContext(); + [view.layer renderInContext:context]; + } UIImage* image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image;
diff --git a/ios/provider/ios_provider_chrome.gyp b/ios/provider/ios_provider_chrome.gyp index 2924b1b7..2a7cb38 100644 --- a/ios/provider/ios_provider_chrome.gyp +++ b/ios/provider/ios_provider_chrome.gyp
@@ -7,6 +7,7 @@ }, 'targets': [ { + # GN version: //ios/public/provider/chrome/browser 'target_name': 'ios_provider_chrome_browser', 'type': 'static_library', 'sources': [
diff --git a/ios/public/provider/chrome/browser/BUILD.gn b/ios/public/provider/chrome/browser/BUILD.gn new file mode 100644 index 0000000..f1cf17ec --- /dev/null +++ b/ios/public/provider/chrome/browser/BUILD.gn
@@ -0,0 +1,35 @@ +# Copyright 2015 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. + +source_set("browser") { + sources = [ + "browser_state/chrome_browser_state.cc", + "browser_state/chrome_browser_state.h", + "browser_state/chrome_browser_state_manager.h", + "chrome_browser_provider.cc", + "chrome_browser_provider.h", + "geolocation_updater_provider.h", + "geolocation_updater_provider.mm", + "keyed_service_provider.cc", + "keyed_service_provider.h", + "signin/chrome_identity.h", + "signin/chrome_identity.mm", + "signin/chrome_identity_service.h", + "signin/chrome_identity_service.mm", + "signin/signin_error_provider.h", + "signin/signin_error_provider.mm", + "string_provider.h", + "ui/infobar_view_delegate.h", + "ui/infobar_view_protocol.h", + "updatable_resource_provider.h", + "updatable_resource_provider.mm", + ] + + deps = [ + "//base", + "//components/autofill/core/browser", + "//ios/public/provider/web", + "//ios/web", + ] +}
diff --git a/ios/web/app/BUILD.gn b/ios/web/app/BUILD.gn new file mode 100644 index 0000000..7599a96 --- /dev/null +++ b/ios/web/app/BUILD.gn
@@ -0,0 +1,31 @@ +# Copyright 2015 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. + +source_set("app") { + visibility = [ "//ios/web/public/app" ] + + sources = [ + "web_main.mm", + "web_main_loop.h", + "web_main_loop.mm", + "web_main_runner.h", + "web_main_runner.mm", + ] + + deps = [ + "//base", + "//base:i18n", + "//crypto", + "//ios/web", + "//net", + "//ui/base", + "//ui/gfx", + "//ui/gfx/geometry", + ] + + libs = [ + "Foundation.framework", + "UIKit.framework", + ] +}
diff --git a/ios/web/ios_web.gyp b/ios/web/ios_web.gyp index 7d29a00..16e4018 100644 --- a/ios/web/ios_web.gyp +++ b/ios/web/ios_web.gyp
@@ -8,6 +8,7 @@ }, 'targets': [ { + # GN version: //ios/web/public/app 'target_name': 'ios_web_app', 'type': 'static_library', 'include_dirs': [
diff --git a/ios/web/ios_web_shell.gyp b/ios/web/ios_web_shell.gyp index 73601ec..67f5c8a4 100644 --- a/ios/web/ios_web_shell.gyp +++ b/ios/web/ios_web_shell.gyp
@@ -8,6 +8,7 @@ }, 'targets': [ { + # GN version: //ios/web/shell:ios_web_shell 'target_name': 'ios_web_shell', 'type': 'executable', 'mac_bundle': 1,
diff --git a/ios/web/public/app/BUILD.gn b/ios/web/public/app/BUILD.gn new file mode 100644 index 0000000..b2e21aa --- /dev/null +++ b/ios/web/public/app/BUILD.gn
@@ -0,0 +1,19 @@ +# Copyright 2015 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. + +source_set("app") { + sources = [ + "web_main.h", + "web_main_delegate.h", + "web_main_parts.h", + ] + + public_deps = [ + "//base", + ] + + deps = [ + "//ios/web/app", + ] +}
diff --git a/ios/web/shell/BUILD.gn b/ios/web/shell/BUILD.gn new file mode 100644 index 0000000..3d9e967 --- /dev/null +++ b/ios/web/shell/BUILD.gn
@@ -0,0 +1,70 @@ +# Copyright 2015 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. + +import("//build/config/ios/rules.gni") + +ios_app("ios_web_shell") { + info_plist = "Info.plist" + app_name = "ios_web_shell" + entitlements_path = "" + code_signing_identity = "" + + sources = [ + "app_delegate.h", + "app_delegate.mm", + "shell_browser_state.h", + "shell_browser_state.mm", + "shell_main_delegate.h", + "shell_main_delegate.mm", + "shell_network_delegate.cc", + "shell_network_delegate.h", + "shell_url_request_context_getter.cc", + "shell_url_request_context_getter.h", + "shell_web_client.h", + "shell_web_client.mm", + "shell_web_main_parts.h", + "shell_web_main_parts.mm", + "view_controller.h", + "view_controller.mm", + "web_exe_main.mm", + ] + + deps = [ + "//base", + "//ios/web", + "//ios/web/public/app", + "//net", + "//net:extras", + "//ui/base", + + # All shared libraries must have the sanitizer deps to properly link in + # asan mode (this target will be empty in other cases). + "//build/config/sanitizers:deps", + ] + + ldflags = [ + "-Xlinker", + "-objc_abi_version", + "-Xlinker", + "2", + ] + + libs = [ + "CoreGraphics.framework", + "CoreFoundation.framework", + "Foundation.framework", + "UIKit.framework", + ] + + # TODO(crbug.com/546283): once gn supports bundle resources, add support for + # the following gyp code: + # + # 'mac_bundle_resources': [ + # 'shell/Default.png', + # 'shell/MainView.xib', + # 'shell/textfield_background@2x.png', + # 'shell/toolbar_back@2x.png', + # 'shell/toolbar_forward@2x.png', + # ], +}
diff --git a/ios/web/web_state/ui/crw_web_controller_unittest.mm b/ios/web/web_state/ui/crw_web_controller_unittest.mm index 0f3e338..219ed09 100644 --- a/ios/web/web_state/ui/crw_web_controller_unittest.mm +++ b/ios/web/web_state/ui/crw_web_controller_unittest.mm
@@ -1293,9 +1293,7 @@ CR_TEST_REQUIRES_WK_WEB_VIEW(); [[[mockWebView_ stub] andReturn:[NSURL URLWithString:kTestURLString]] URL]; -#if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) [[[mockWebView_ stub] andReturnBool:NO] hasOnlySecureContent]; -#endif // Stub out the injection process. [[mockWebView_ stub] evaluateJavaScript:OCMOCK_ANY
diff --git a/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm b/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm index a3eaff3..a254291 100644 --- a/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm +++ b/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm
@@ -216,17 +216,11 @@ // changed. @property(nonatomic, readonly) NSDictionary* wkWebViewObservers; -// Returns the string to use as the request group ID in the user agent. Returns -// nil unless the network stack is enabled. -@property(nonatomic, readonly) NSString* requestGroupIDForUserAgent; - // Activity indicator group ID for this web controller. @property(nonatomic, readonly) NSString* activityIndicatorGroupID; -#if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) // Identifier used for storing and retrieving certificates. @property(nonatomic, readonly) int certGroupID; -#endif // #if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) // Returns the WKWebViewConfigurationProvider associated with the web // controller's BrowserState. @@ -291,10 +285,8 @@ // Convenience method to inform CWRWebDelegate about a blocked popup. - (void)didBlockPopupWithURL:(GURL)popupURL sourceURL:(GURL)sourceURL; -#if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) // Called when a load ends in an SSL error and certificate chain. - (void)handleSSLCertError:(NSError*)error; -#endif // Adds an activity indicator tasks for this web controller. - (void)addActivityIndicatorTask; @@ -302,8 +294,6 @@ // Clears all activity indicator tasks for this web controller. - (void)clearActivityIndicatorTasks; -#if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) - // Updates |security_style| and |cert_status| for the NavigationItem with ID // |navigationItemID|, if URL and certificate chain still match |host| and // |certChain|. @@ -322,7 +312,6 @@ // Updates SSL status for the current navigation item based on the information // provided by web view. - (void)updateSSLStatusForCurrentNavigationItem; -#endif // Used in webView:didReceiveAuthenticationChallenge:completionHandler: to reply // with NSURLSessionAuthChallengeDisposition and credentials. @@ -360,14 +349,12 @@ // NSURLErrorCancelled code should be cancelled. - (BOOL)shouldAbortLoadForCancelledError:(NSError*)error; -#if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) // Called when WKWebView estimatedProgress has been changed. - (void)webViewEstimatedProgressDidChange; // Called when WKWebView certificateChain or hasOnlySecureContent property has // changed. - (void)webViewSecurityFeaturesDidChange; -#endif // !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) // Called when WKWebView loading state has been changed. - (void)webViewLoadingStateDidChange; @@ -423,12 +410,10 @@ web::EvaluateJavaScript(_wkWebView, script, nil); } -#if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) - (void)terminateNetworkActivity { web::CertStore::GetInstance()->RemoveCertsForGroup(self.certGroupID); [super terminateNetworkActivity]; } -#endif // #if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) - (void)setPageDialogOpenPolicy:(web::PageDialogOpenPolicy)policy { // TODO(eugenebut): implement dialogs/windows suppression using @@ -499,8 +484,7 @@ // TODO(stuartmorgan): Remove this method and use the API for WKWebView, // making the reset-on-each-load behavior specific to the UIWebView subclass. - (void)registerUserAgent { - web::BuildAndRegisterUserAgentForUIWebView([self requestGroupIDForUserAgent], - [self useDesktopUserAgent]); + web::BuildAndRegisterUserAgentForUIWebView(nil, [self useDesktopUserAgent]); } - (BOOL)isCurrentNavigationItemPOST { @@ -693,38 +677,26 @@ - (NSDictionary*)wkWebViewObservers { return @{ -#if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) - @"estimatedProgress" : @"webViewEstimatedProgressDidChange", @"certificateChain" : @"webViewSecurityFeaturesDidChange", + @"estimatedProgress" : @"webViewEstimatedProgressDidChange", @"hasOnlySecureContent" : @"webViewSecurityFeaturesDidChange", -#endif @"loading" : @"webViewLoadingStateDidChange", @"title" : @"webViewTitleDidChange", @"URL" : @"webViewURLDidChange", }; } -- (NSString*)requestGroupIDForUserAgent { -#if defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) - return self.webStateImpl->GetRequestGroupID(); -#else - return nil; -#endif -} - - (NSString*)activityIndicatorGroupID { return [NSString stringWithFormat: @"WKWebViewWebController.NetworkActivityIndicatorKey.%@", self.webStateImpl->GetRequestGroupID()]; } -#if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) - (int)certGroupID { DCHECK(self.webStateImpl); // Request tracker IDs are used as certificate groups. return self.webStateImpl->GetRequestTracker()->identifier(); } -#endif - (web::WKWebViewConfigurationProvider&)webViewConfigurationProvider { DCHECK(self.webStateImpl); @@ -745,7 +717,6 @@ - (WKWebView*)createWebViewWithConfiguration:(WKWebViewConfiguration*)config { return [web::CreateWKWebView(CGRectZero, config, self.webStateImpl->GetBrowserState(), - [self requestGroupIDForUserAgent], [self useDesktopUserAgent]) autorelease]; } @@ -947,7 +918,6 @@ }); } -#if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) - (void)handleSSLCertError:(NSError*)error { DCHECK(web::IsWKWebViewSSLCertError(error)); @@ -1003,7 +973,6 @@ }]; [self loadCancelled]; } -#endif // #if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) - (void)addActivityIndicatorTask { [[CRWNetworkActivityIndicatorManager sharedInstance] @@ -1015,8 +984,6 @@ clearNetworkTasksForGroup:[self activityIndicatorGroupID]]; } -#if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) - - (void)updateSSLStatusForNavigationItemWithID:(int)navigationItemID certChain:(NSArray*)chain host:(NSString*)host @@ -1142,8 +1109,6 @@ } } -#endif // !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) - - (void)processAuthChallenge:(NSURLAuthenticationChallenge*)challenge forCertAcceptPolicy:(web::CertAcceptPolicy)policy certStatus:(net::CertStatus)certStatus @@ -1436,8 +1401,6 @@ [self performSelector:NSSelectorFromString(dispatcherSelectorName)]; } -#if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) -// TODO(eugenebut): use WKWebView progress even if Chrome net stack is enabled. - (void)webViewEstimatedProgressDidChange { if ([self.delegate respondsToSelector: @selector(webController:didUpdateProgress:)]) { @@ -1455,8 +1418,6 @@ [self updateSSLStatusForCurrentNavigationItem]; } -#endif // !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) - - (void)webViewLoadingStateDidChange { if ([_wkWebView isLoading]) { [self addActivityIndicatorTask]; @@ -1655,24 +1616,9 @@ if (![_pendingNavigationInfo cancelled]) { error = WKWebViewErrorWithSource(error, PROVISIONAL_LOAD); -#if defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) - // For WKWebViews, the underlying errors for errors reported by the net - // stack are not copied over when transferring the errors from the IO - // thread. For cancelled errors that trigger load abortions, translate the - // error early to trigger |-discardNonCommittedEntries| from - // |-handleLoadError:inMainFrame:|. - if (error.code == NSURLErrorCancelled && - [self shouldAbortLoadForCancelledError:error] && - !error.userInfo[NSUnderlyingErrorKey]) { - error = web::NetErrorFromError(error); - } -#endif // defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) - -#if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) if (web::IsWKWebViewSSLCertError(error)) [self handleSSLCertError:error]; else -#endif [self handleLoadError:error inMainFrame:YES]; } @@ -1699,9 +1645,7 @@ [self commitPendingNavigationInfo]; [self webPageChanged]; -#if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) [self updateSSLStatusForCurrentNavigationItem]; -#endif // Report cases where SSL cert is missing for a secure connection. if (_documentURL.SchemeIsCryptographic()) {
diff --git a/ios/web/web_state/web_view_internal_creation_util.h b/ios/web/web_state/web_view_internal_creation_util.h index c53fae80..ee2296b 100644 --- a/ios/web/web_state/web_view_internal_creation_util.h +++ b/ios/web/web_state/web_view_internal_creation_util.h
@@ -31,8 +31,8 @@ // TODO(shreyasv): Rename to CreateUIWebView. UIWebView* CreateWebView(CGRect frame); -// Creates and returns a WKWebView. The returned WKWebView will have a -// user agent string that includes the |request_group_id|. +// Creates a new WKWebView for displaying regular web content and registers a +// user agent for it. // // Preconditions for creation of a WKWebView: // 1) |browser_state|, |configuration| are not null. @@ -44,7 +44,6 @@ WKWebView* CreateWKWebView(CGRect frame, WKWebViewConfiguration* configuration, BrowserState* browser_state, - NSString* request_group_id, BOOL use_desktop_user_agent); // Creates and returns a new WKWebView for displaying regular web content.
diff --git a/ios/web/web_state/web_view_internal_creation_util.mm b/ios/web/web_state/web_view_internal_creation_util.mm index 3fdb1b15..a9a69ce 100644 --- a/ios/web/web_state/web_view_internal_creation_util.mm +++ b/ios/web/web_state/web_view_internal_creation_util.mm
@@ -163,10 +163,8 @@ WKWebView* CreateWKWebView(CGRect frame, WKWebViewConfiguration* configuration, BrowserState* browser_state, - NSString* request_group_id, BOOL use_desktop_user_agent) { - web::BuildAndRegisterUserAgentForUIWebView(request_group_id, - use_desktop_user_agent); + web::BuildAndRegisterUserAgentForUIWebView(nil, use_desktop_user_agent); return CreateWKWebView(frame, configuration, browser_state); }
diff --git a/ipc/brokerable_attachment.h b/ipc/brokerable_attachment.h index ce3082c..6761f22 100644 --- a/ipc/brokerable_attachment.h +++ b/ipc/brokerable_attachment.h
@@ -7,6 +7,8 @@ #include <stdint.h> +#include <algorithm> + #include "base/macros.h" #include "ipc/ipc_export.h" #include "ipc/ipc_message_attachment.h" @@ -37,21 +39,12 @@ void SerializeToBuffer(char* start_address, size_t size); bool operator==(const AttachmentId& rhs) const { - for (size_t i = 0; i < kNonceSize; ++i) { - if (nonce[i] != rhs.nonce[i]) - return false; - } - return true; + return std::equal(nonce, nonce + kNonceSize, rhs.nonce); } bool operator<(const AttachmentId& rhs) const { - for (size_t i = 0; i < kNonceSize; ++i) { - if (nonce[i] < rhs.nonce[i]) - return true; - if (nonce[i] > rhs.nonce[i]) - return false; - } - return false; + return std::lexicographical_compare(nonce, nonce + kNonceSize, rhs.nonce, + rhs.nonce + kNonceSize); } };
diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc index 3be20da..286ed438 100644 --- a/media/base/video_frame.cc +++ b/media/base/video_frame.cc
@@ -226,8 +226,8 @@ const gfx::Rect& visible_rect, const gfx::Size& natural_size, base::TimeDelta timestamp) { - if (format != PIXEL_FORMAT_ARGB && format != PIXEL_FORMAT_XRGB && - format != PIXEL_FORMAT_UYVY && format != PIXEL_FORMAT_NV12) { + if (format != PIXEL_FORMAT_ARGB && format != PIXEL_FORMAT_UYVY && + format != PIXEL_FORMAT_NV12) { DLOG(ERROR) << "Unsupported pixel format supported, got " << VideoPixelFormatToString(format); return nullptr;
diff --git a/media/test/data/test-25fps.h264.md5 b/media/test/data/test-25fps.h264.md5 index 1f6a6fa..ecf64a0 100644 --- a/media/test/data/test-25fps.h264.md5 +++ b/media/test/data/test-25fps.h264.md5
@@ -1,8 +1,6 @@ # --test_video_data="test-25fps.h264:320:240:250:258:35:150:1" -# Intel Haswell - EGL -92a0c14b4c1a13ca21317d2e75f17f76 -# Intel Ivy Bridge - EGL -75d2f70272df8687dbda32e2eddd0a00 +# Intel Ivy Bridge / Haswell / Broadwell - EGL +27ddce017b884f8bbfa159ad180a71d2 # Intel Sandy Brige - EGL 42e78b8ac231dc24e6db5fac2d26da7b # Intel - Haswell - X11 @@ -14,5 +12,12 @@ 04436cf1cf06b4bb6c1efd838e68257d # ARM - Tegra b55cda7d10c37104d8c49d27c2699e40 + +# TODO(llandwerlin): Remove the following hashes when the libva-intel-driver +# is updated. +# Intel Haswell - EGL +92a0c14b4c1a13ca21317d2e75f17f76 +# Intel Ivy Bridge - EGL +75d2f70272df8687dbda32e2eddd0a00 # Intel (various) libva-intel-driver 1.5.1 with VA_PROC_PIPELINE_FAST 8bbc743c7ac92c2442d09e8b3fb9f4f5
diff --git a/media/test/data/test-25fps.vp8.md5 b/media/test/data/test-25fps.vp8.md5 index 6ae8188..4692109 100644 --- a/media/test/data/test-25fps.vp8.md5 +++ b/media/test/data/test-25fps.vp8.md5
@@ -3,4 +3,9 @@ # ARM - Tegra cd355b553ce7660283c52675232e9227 # Intel - BDW +32a3c4257dac03df92a5c7593ee7e31f + +# TODO(llandwerlin): Remove the following hash when the libva-intel-driver +# is updated. +# Intel - BDW 4da7ec5484a99195c2c05b5e591940f9
diff --git a/net/cookies/canonical_cookie.cc b/net/cookies/canonical_cookie.cc index f57f642..ddf35e05 100644 --- a/net/cookies/canonical_cookie.cc +++ b/net/cookies/canonical_cookie.cc
@@ -116,6 +116,21 @@ return a.Path().compare(b.Path()); } +// Returns true if the cookie does not violate any constraints imposed +// by the cookie name's prefix, as described in +// https://tools.ietf.org/html/draft-west-cookie-prefixes +bool IsCookiePrefixValid(const GURL& url, const ParsedCookie& parsed_cookie) { + const char kSecurePrefix[] = "$Secure-"; + const char kHostPrefix[] = "$Host-"; + if (parsed_cookie.Name().find(kSecurePrefix) == 0) + return parsed_cookie.IsSecure() && url.SchemeIsCryptographic(); + if (parsed_cookie.Name().find(kHostPrefix) == 0) { + return parsed_cookie.IsSecure() && url.SchemeIsCryptographic() && + !parsed_cookie.HasDomain() && parsed_cookie.Path() == "/"; + } + return true; +} + } // namespace CanonicalCookie::CanonicalCookie() @@ -248,6 +263,12 @@ creation_time, server_time); + if (options.enforce_prefixes() && !IsCookiePrefixValid(url, parsed_cookie)) { + VLOG(kVlogSetCookies) + << "Create() failed because the cookie violated prefix rules."; + return nullptr; + } + return new CanonicalCookie( url, parsed_cookie.Name(), parsed_cookie.Value(), cookie_domain, cookie_path, creation_time, cookie_expires, creation_time,
diff --git a/net/cookies/canonical_cookie_unittest.cc b/net/cookies/canonical_cookie_unittest.cc index 58c12ca6..cc0426e 100644 --- a/net/cookies/canonical_cookie_unittest.cc +++ b/net/cookies/canonical_cookie_unittest.cc
@@ -449,4 +449,93 @@ check_consistency(*cookie_different_path, *cookie_different_value); } +TEST(CanonicalCookieTest, SecureCookiePrefix) { + GURL https_url("https://www.example.test"); + GURL http_url("http://www.example.test"); + base::Time creation_time = base::Time::Now(); + CookieOptions options; + options.set_enforce_prefixes(); + + // A $Secure- cookie must be Secure. + EXPECT_EQ(nullptr, make_scoped_ptr(CanonicalCookie::Create( + https_url, "$Secure-A=B", creation_time, options))); + EXPECT_EQ(nullptr, + make_scoped_ptr(CanonicalCookie::Create( + https_url, "$Secure-A=B; httponly", creation_time, options))); + + // A typoed prefix does not have to be Secure. + EXPECT_NE(nullptr, + make_scoped_ptr(CanonicalCookie::Create( + https_url, "$secure-A=B; Secure", creation_time, options))); + EXPECT_NE(nullptr, make_scoped_ptr(CanonicalCookie::Create( + https_url, "$secure-A=C;", creation_time, options))); + EXPECT_NE(nullptr, + make_scoped_ptr(CanonicalCookie::Create( + https_url, "$SecureA=B; Secure", creation_time, options))); + EXPECT_NE(nullptr, make_scoped_ptr(CanonicalCookie::Create( + https_url, "$SecureA=C;", creation_time, options))); + + // A $Secure- cookie can't be set on a non-secure origin. + EXPECT_EQ(nullptr, + make_scoped_ptr(CanonicalCookie::Create( + http_url, "$Secure-A=B; Secure", creation_time, options))); +} + +TEST(CanonicalCookieTest, HostCookiePrefix) { + GURL https_url("https://www.example.test"); + GURL http_url("http://www.example.test"); + base::Time creation_time = base::Time::Now(); + CookieOptions options; + options.set_enforce_prefixes(); + std::string domain = https_url.host(); + + // A $Host- cookie must be Secure. + EXPECT_EQ(nullptr, make_scoped_ptr(CanonicalCookie::Create( + https_url, "$Host-A=B;", creation_time, options))); + EXPECT_EQ(nullptr, make_scoped_ptr(CanonicalCookie::Create( + https_url, "$Host-A=B; Domain=" + domain + "; Path=/;", + creation_time, options))); + EXPECT_NE(nullptr, make_scoped_ptr(CanonicalCookie::Create( + https_url, "$Host-A=B; Path=/; Secure;", creation_time, + options))); + + // A $Host- cookie must be set from a secure scheme. + EXPECT_EQ(nullptr, + make_scoped_ptr(CanonicalCookie::Create( + http_url, "$Host-A=B; Domain=" + domain + "; Path=/; Secure;", + creation_time, options))); + EXPECT_NE(nullptr, make_scoped_ptr(CanonicalCookie::Create( + https_url, "$Host-A=B; Path=/; Secure;", creation_time, + options))); + + // A $Host- cookie can't have a Domain. + EXPECT_EQ(nullptr, + make_scoped_ptr(CanonicalCookie::Create( + https_url, "$Host-A=B; Domain=" + domain + "; Path=/; Secure;", + creation_time, options))); + EXPECT_EQ(nullptr, make_scoped_ptr(CanonicalCookie::Create( + https_url, "$Host-A=B; Domain=" + domain + "; Secure;", + creation_time, options))); + + // A $Host- cookie must have a Path of "/". + EXPECT_EQ(nullptr, make_scoped_ptr(CanonicalCookie::Create( + https_url, "$Host-A=B; Path=/foo; Secure;", + creation_time, options))); + EXPECT_EQ(nullptr, + make_scoped_ptr(CanonicalCookie::Create( + https_url, "$Host-A=B; Secure;", creation_time, options))); + EXPECT_NE(nullptr, make_scoped_ptr(CanonicalCookie::Create( + https_url, "$Host-A=B; Secure; Path=/;", creation_time, + options))); + + // Rules don't apply for a typoed prefix. + EXPECT_NE(nullptr, + make_scoped_ptr(CanonicalCookie::Create( + http_url, "$host-A=B; Domain=" + domain + "; Path=/; Secure;", + creation_time, options))); + EXPECT_NE(nullptr, make_scoped_ptr(CanonicalCookie::Create( + https_url, "$HostA=B; Domain=" + domain + "; Secure;", + creation_time, options))); +} + } // namespace net
diff --git a/net/cookies/cookie_monster.cc b/net/cookies/cookie_monster.cc index 9adfa1b..6304eb6c 100644 --- a/net/cookies/cookie_monster.cc +++ b/net/cookies/cookie_monster.cc
@@ -332,13 +332,6 @@ proxy->PostTask(FROM_HERE, base::Bind(callback, cookie, removed)); } -bool CheckCookiePrefix(CanonicalCookie* cc, const CookieOptions& options) { - const char kSecurePrefix[] = "$Secure-"; - if (cc->Name().find(kSecurePrefix) == 0) - return cc->IsSecure() && cc->Source().SchemeIsCryptographic(); - return true; -} - } // namespace CookieMonster::CookieMonster(PersistentCookieStore* store, @@ -1895,12 +1888,6 @@ const std::string key(GetKey((*cc)->Domain())); bool already_expired = (*cc)->IsExpired(creation_time); - if (options.enforce_prefixes() && !CheckCookiePrefix(cc->get(), options)) { - VLOG(kVlogSetCookies) << "SetCookie() not storing cookie '" << (*cc)->Name() - << "' that violates prefix rules."; - return false; - } - if (DeleteAnyEquivalentCookie(key, **cc, options.exclude_httponly(), already_expired)) { VLOG(kVlogSetCookies) << "SetCookie() not clobbering httponly cookie";
diff --git a/net/cookies/cookie_monster_unittest.cc b/net/cookies/cookie_monster_unittest.cc index 82ae3a2..fddd625 100644 --- a/net/cookies/cookie_monster_unittest.cc +++ b/net/cookies/cookie_monster_unittest.cc
@@ -2967,29 +2967,6 @@ CookieMonster::COOKIE_SOURCE_NONSECURE_COOKIE_NONCRYPTOGRAPHIC_SCHEME, 1); } -TEST_F(CookieMonsterTest, SecureCookiePrefix) { - scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL)); - // A $Secure- cookie must be Secure. - EXPECT_FALSE(SetCookie(cm.get(), https_www_google_.url(), "$Secure-A=B")); - EXPECT_FALSE( - SetCookie(cm.get(), https_www_google_.url(), "$Secure-A=B; httponly")); - - // A typoed prefix does not have to be Secure. - EXPECT_TRUE( - SetCookie(cm.get(), https_www_google_.url(), "$secure-A=B; Secure")); - EXPECT_TRUE(SetCookie(cm.get(), https_www_google_.url(), "$secure-A=C;")); - EXPECT_TRUE( - SetCookie(cm.get(), https_www_google_.url(), "$SecureA=B; Secure")); - EXPECT_TRUE(SetCookie(cm.get(), https_www_google_.url(), "$SecureA=C;")); - - EXPECT_TRUE( - SetCookie(cm.get(), https_www_google_.url(), "$Secure-A=B; Secure")); - - // A $Secure- cookie can't be set on a non-secure origin. - EXPECT_FALSE( - SetCookie(cm.get(), http_www_google_.url(), "$Secure-A=B; Secure")); -} - class CookieMonsterNotificationTest : public CookieMonsterTest { public: CookieMonsterNotificationTest()
diff --git a/remoting/android/java/src/org/chromium/chromoting/DesktopCanvas.java b/remoting/android/java/src/org/chromium/chromoting/DesktopCanvas.java new file mode 100644 index 0000000..b9edf31 --- /dev/null +++ b/remoting/android/java/src/org/chromium/chromoting/DesktopCanvas.java
@@ -0,0 +1,196 @@ +// Copyright 2015 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. + +package org.chromium.chromoting; + +import android.graphics.PointF; +import android.graphics.RectF; + +/** + * This class is responsible for transforming the desktop image matrix. + */ +public class DesktopCanvas { + /** + * Maximum allowed zoom level - see {@link #repositionImageWithZoom()}. + */ + private static final float MAX_ZOOM_FACTOR = 100.0f; + + private final DesktopViewInterface mViewer; + private final RenderData mRenderData; + + /** + * The current cursor position is stored here as a float so that the desktop image can be + * positioned with sub-pixel accuracy to give a smoother panning animation at high zoom levels. + */ + private PointF mCursorPosition = new PointF(); + + /** + * Represents the amount of vertical space in pixels used by the soft input device and + * accompanying system UI. + */ + private int mInputMethodOffsetY = 0; + + /** + * Represents the amount of horizontal space in pixels used by the soft input device and + * accompanying system UI. + */ + private int mInputMethodOffsetX = 0; + + /** Used to determine whether the view should be locked to the cursor. */ + private boolean mCenterCursorInView = true; + + public DesktopCanvas(DesktopViewInterface viewer, RenderData renderData) { + mViewer = viewer; + mRenderData = renderData; + } + + public void setCenterCursorInView(boolean centerCursor) { + mCenterCursorInView = centerCursor; + } + + public PointF getCursorPosition() { + return new PointF(mCursorPosition.x, mCursorPosition.y); + } + + public void setCursorPosition(float newX, float newY) { + mCursorPosition.set(newX, newY); + } + + public void setInputMethodOffsetValues(int offsetX, int offsetY) { + mInputMethodOffsetX = offsetX; + mInputMethodOffsetY = offsetY; + } + + /** Repositions the image by zooming it such that the complete image fits on the screen. */ + public void resizeImageToFitScreen() { + synchronized (mRenderData) { + // Protect against being called before the image has been initialized. + if (mRenderData.imageWidth == 0 || mRenderData.imageHeight == 0) { + return; + } + + float screenToImageScale = 1.0f; + float[] imageSize = {mRenderData.imageWidth, mRenderData.imageHeight}; + mRenderData.transform.mapVectors(imageSize); + + // If the image is smaller than the screen in both dimensions, then we want + // to scale it up to fit. + boolean scaleImageUp = imageSize[0] < mRenderData.screenWidth + && imageSize[1] < mRenderData.screenHeight; + + // If the image is larger than the screen in any dimension, we want to + // shrink it to fit. + boolean scaleImageDown = imageSize[0] > mRenderData.screenWidth + || imageSize[1] > mRenderData.screenHeight; + + if (scaleImageUp || scaleImageDown) { + // Displayed image is too small or too large to fit the screen dimensions. + // Apply the minimum scale needed to fit both the width and height. + screenToImageScale = + Math.min((float) mRenderData.screenWidth / mRenderData.imageWidth, + (float) mRenderData.screenHeight / mRenderData.imageHeight); + mRenderData.transform.setScale(screenToImageScale, screenToImageScale); + } + } + + repositionImage(); + } + + /** + * Repositions the image by translating it (without affecting the zoom level) to place the + * cursor close to the center of the screen. + */ + public void repositionImage() { + synchronized (mRenderData) { + float adjustedScreenWidth = mRenderData.screenWidth - mInputMethodOffsetX; + float adjustedScreenHeight = mRenderData.screenHeight - mInputMethodOffsetY; + + if (mCenterCursorInView) { + // For indirect input modes such as Trackpad emulation, we want to try to position + // the view so the cursor is centered. We move it here and then make adjustments + // below as needed to keep as much of the image on screen as possible. + + // Get the current cursor position in screen coordinates. + float[] cursorScreen = {mCursorPosition.x, mCursorPosition.y}; + mRenderData.transform.mapPoints(cursorScreen); + + // Translate so the cursor is displayed in the middle of the screen. + mRenderData.transform.postTranslate( + (float) adjustedScreenWidth / 2 - cursorScreen[0], + (float) adjustedScreenHeight / 2 - cursorScreen[1]); + } + + // Get the coordinates of the desktop rectangle (top-left/bottom-right corners) in + // screen coordinates. Order is: left, top, right, bottom. + RectF rectScreen = new RectF(0, 0, mRenderData.imageWidth, mRenderData.imageHeight); + mRenderData.transform.mapRect(rectScreen); + + float leftDelta = rectScreen.left; + float rightDelta = rectScreen.right - mRenderData.screenWidth + mInputMethodOffsetX; + float topDelta = rectScreen.top; + float bottomDelta = rectScreen.bottom - mRenderData.screenHeight + mInputMethodOffsetY; + float xAdjust = 0; + float yAdjust = 0; + + if (rectScreen.right - rectScreen.left < adjustedScreenWidth) { + // Image is narrower than the screen, so center it. + xAdjust = -(rightDelta + leftDelta) / 2; + } else if (leftDelta > 0 && rightDelta > 0) { + // Panning the image left will show more of it. + xAdjust = -Math.min(leftDelta, rightDelta); + } else if (leftDelta < 0 && rightDelta < 0) { + // Pan the image right. + xAdjust = Math.min(-leftDelta, -rightDelta); + } + + // Apply similar logic for yAdjust. + if (rectScreen.bottom - rectScreen.top < adjustedScreenHeight) { + yAdjust = -(bottomDelta + topDelta) / 2; + } else if (topDelta > 0 && bottomDelta > 0) { + yAdjust = -Math.min(topDelta, bottomDelta); + } else if (topDelta < 0 && bottomDelta < 0) { + yAdjust = Math.min(-topDelta, -bottomDelta); + } + + mRenderData.transform.postTranslate(xAdjust, yAdjust); + + mViewer.transformationChanged(); + } + } + + /** + * Repositions the image by translating and zooming it, to keep the zoom level within sensible + * limits. The minimum zoom level is chosen to avoid black space around all 4 sides. The + * maximum zoom level is set arbitrarily, so that the user can zoom out again in a reasonable + * time, and to prevent arithmetic overflow problems from displaying the image. + */ + public void repositionImageWithZoom() { + synchronized (mRenderData) { + // Avoid division by zero in case this gets called before the image size is initialized. + if (mRenderData.imageWidth == 0 || mRenderData.imageHeight == 0) { + return; + } + + // Zoom out if the zoom level is too high. + float currentZoomLevel = mRenderData.transform.mapRadius(1.0f); + if (currentZoomLevel > MAX_ZOOM_FACTOR) { + mRenderData.transform.setScale(MAX_ZOOM_FACTOR, MAX_ZOOM_FACTOR); + } + + // Get image size scaled to screen coordinates. + float[] imageSize = {mRenderData.imageWidth, mRenderData.imageHeight}; + mRenderData.transform.mapVectors(imageSize); + + if (imageSize[0] < mRenderData.screenWidth && imageSize[1] < mRenderData.screenHeight) { + // Displayed image is too small in both directions, so apply the minimum zoom + // level needed to fit either the width or height. + float scale = Math.min((float) mRenderData.screenWidth / mRenderData.imageWidth, + (float) mRenderData.screenHeight / mRenderData.imageHeight); + mRenderData.transform.setScale(scale, scale); + } + } + + repositionImage(); + } +}
diff --git a/remoting/android/java/src/org/chromium/chromoting/DesktopView.java b/remoting/android/java/src/org/chromium/chromoting/DesktopView.java index d517f4a2..466012b9 100644 --- a/remoting/android/java/src/org/chromium/chromoting/DesktopView.java +++ b/remoting/android/java/src/org/chromium/chromoting/DesktopView.java
@@ -35,10 +35,13 @@ /** GUI element that holds the drawing canvas. */ public class DesktopView extends SurfaceView implements DesktopViewInterface, SurfaceHolder.Callback { + /** Used to define the animation feedback shown when a user touches the screen. */ + public enum InputFeedbackType { NONE, SMALL_ANIMATION, LARGE_ANIMATION } + private static final String TAG = "Chromoting"; private final RenderData mRenderData; - private TouchInputHandlerInterface mInputHandler; + private final TouchInputHandlerInterface mInputHandler; /** The parent Desktop activity. */ private Desktop mDesktop; @@ -63,6 +66,9 @@ private boolean mRunning = false; + /** Contains the size of the feedback animation for the most recent request. */ + private float mFeedbackSizeInPixels; + /** Lock to allow multithreaded access to {@link #mStartTime} and {@link #mRunning}. */ private final Object mLock = new Object(); @@ -79,22 +85,29 @@ * call {@link #render(Canvas, float, float, float)} periodically whilst * {@link #isAnimationRunning()} returns true. */ - public void startAnimation() { + public void startAnimation(InputFeedbackType feedbackType) { + if (feedbackType == InputFeedbackType.NONE) { + return; + } + synchronized (mLock) { mRunning = true; mStartTime = SystemClock.uptimeMillis(); + mFeedbackSizeInPixels = getInputFeedbackSizeInPixels(feedbackType); } } - public void render(Canvas canvas, float x, float y, float size) { + public void render(Canvas canvas, float x, float y, float scale) { // |progress| is 0 at the beginning, 1 at the end. float progress; + float size; synchronized (mLock) { progress = (SystemClock.uptimeMillis() - mStartTime) / TOTAL_DURATION_MS; if (progress >= 1) { mRunning = false; return; } + size = mFeedbackSizeInPixels / scale; } // Animation grows from 0 to |size|, and goes from fully opaque to transparent for a @@ -111,6 +124,21 @@ new float[] {0.0f, 0.8f, 0.9f, 1.0f}, Shader.TileMode.CLAMP)); canvas.drawCircle(x, y, radius, mPaint); } + + private float getInputFeedbackSizeInPixels(InputFeedbackType feedbackType) { + switch (feedbackType) { + case SMALL_ANIMATION: + return 40.0f; + + case LARGE_ANIMATION: + return 160.0f; + + default: + // Unreachable, but required by Google Java style and findbugs. + assert false : "Unreached"; + return 0.0f; + } + } } private FeedbackAnimator mFeedbackAnimator = new FeedbackAnimator(); @@ -131,6 +159,10 @@ mRenderData = new RenderData(); mInputHandler = new TouchInputHandler(this, context, mRenderData); + // TODO(joedow): Move this into a method which will choose the correct input strategy + // based on host support and current toggle setting in the UI. + mInputHandler.setInputStrategy(new TrackpadInputStrategy(this, mRenderData)); + mRepaintPending = false; getHolder().addCallback(this); @@ -221,7 +253,7 @@ synchronized (mRenderData) { scaleFactor = mRenderData.transform.mapRadius(1); } - mFeedbackAnimator.render(canvas, x, y, 40 / scaleFactor); + mFeedbackAnimator.render(canvas, x, y, scaleFactor); } Bitmap cursorBitmap = JniInterface.getCursorBitmap(); @@ -327,46 +359,14 @@ } @Override - public void injectMouseEvent(int x, int y, int button, boolean pressed) { - boolean cursorMoved = false; - synchronized (mRenderData) { - // Test if the cursor actually moved, which requires repainting the cursor. This - // requires that the TouchInputHandler doesn't mutate |mRenderData.cursorPosition| - // directly. - if (x != mRenderData.cursorPosition.x) { - mRenderData.cursorPosition.x = x; - cursorMoved = true; - } - if (y != mRenderData.cursorPosition.y) { - mRenderData.cursorPosition.y = y; - cursorMoved = true; - } - } - - if (button == TouchInputHandler.BUTTON_UNDEFINED && !cursorMoved) { - // No need to inject anything or repaint. - return; - } - - JniInterface.sendMouseEvent(x, y, button, pressed); - if (cursorMoved) { - // TODO(lambroslambrou): Optimize this by only repainting the affected areas. + public void showInputFeedback(InputFeedbackType feedbackToShow) { + if (feedbackToShow != InputFeedbackType.NONE) { + mFeedbackAnimator.startAnimation(feedbackToShow); requestRepaint(); } } @Override - public void injectMouseWheelDeltaEvent(int deltaX, int deltaY) { - JniInterface.sendMouseWheelEvent(deltaX, deltaY); - } - - @Override - public void showLongPressFeedback() { - mFeedbackAnimator.startAnimation(); - requestRepaint(); - } - - @Override public void showActionBar() { mDesktop.showActionBar(); }
diff --git a/remoting/android/java/src/org/chromium/chromoting/DesktopViewInterface.java b/remoting/android/java/src/org/chromium/chromoting/DesktopViewInterface.java index 1dd0b82..b9d3147 100644 --- a/remoting/android/java/src/org/chromium/chromoting/DesktopViewInterface.java +++ b/remoting/android/java/src/org/chromium/chromoting/DesktopViewInterface.java
@@ -8,14 +8,8 @@ * Callback interface to allow the TouchInputHandler to request actions on the DesktopView. */ public interface DesktopViewInterface { - /** Injects a mouse-move event, with optional button press/release. */ - void injectMouseEvent(int x, int y, int button, boolean pressed); - - /** Injects a mouse-wheel event with delta values. */ - void injectMouseWheelDeltaEvent(int deltaX, int deltaY); - - /** Triggers a brief cursor animation to indicate a long-press event. */ - void showLongPressFeedback(); + /** Triggers a brief animation to indicate the existence and location of an input event. */ + void showInputFeedback(DesktopView.InputFeedbackType feedbackToShow); /** Shows the action bar. */ void showActionBar();
diff --git a/remoting/android/java/src/org/chromium/chromoting/InputStrategyInterface.java b/remoting/android/java/src/org/chromium/chromoting/InputStrategyInterface.java new file mode 100644 index 0000000..1048f51 --- /dev/null +++ b/remoting/android/java/src/org/chromium/chromoting/InputStrategyInterface.java
@@ -0,0 +1,36 @@ +// Copyright 2015 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. + +package org.chromium.chromoting; + +/** + * This interface defines the methods used to customize input handling for + * a particular strategy. The implementing class is responsible for sending + * remote input events and defining implementation specific behavior. + */ +public interface InputStrategyInterface { + /** Sends a pointer move event to the remote host. */ + void injectRemoteMoveEvent(int x, int y); + + /** Sends a pointer button event to the remote host. */ + void injectRemoteButtonEvent(int button, boolean pressed); + + /** Sends a scroll/pan event to the remote host. */ + void injectRemoteScrollEvent(int deltaX, int deltaY); + + /** Returns the feedback animation type to use for a short press. */ + DesktopView.InputFeedbackType getShortPressFeedbackType(); + + /** Returns the feedback animation type to use for a long press. */ + DesktopView.InputFeedbackType getLongPressFeedbackType(); + + /** + * Indicates whether the view should be manipulated to keep the cursor in the center or if the + * view and cursor are not linked. + */ + boolean centerCursorInView(); + + /** Indicates whether to invert cursor movement for panning/scrolling. */ + boolean invertCursorMovement(); +}
diff --git a/remoting/android/java/src/org/chromium/chromoting/TouchInputHandler.java b/remoting/android/java/src/org/chromium/chromoting/TouchInputHandler.java index 421c58c..d7520f7 100644 --- a/remoting/android/java/src/org/chromium/chromoting/TouchInputHandler.java +++ b/remoting/android/java/src/org/chromium/chromoting/TouchInputHandler.java
@@ -8,14 +8,15 @@ import android.graphics.Matrix; import android.graphics.PointF; import android.graphics.Rect; -import android.graphics.RectF; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.ScaleGestureDetector; import android.widget.Scroller; /** - * This class implements the cursor-tracking behavior and gestures. + * This class is responsible for handling Touch input from the user. Touch events which manipulate + * the local canvas are handled in this class and any input which should be sent to the remote host + * are passed to the InputStrategyInterface implementation set by the DesktopView. */ public class TouchInputHandler implements TouchInputHandlerInterface { /** @@ -24,13 +25,10 @@ */ private static final double MIN_ZOOM_DELTA = 0.05; - /** - * Maximum allowed zoom level - see {@link #repositionImageWithZoom()}. - */ - private static final float MAX_ZOOM_FACTOR = 100.0f; - - private DesktopViewInterface mViewer; + private final DesktopViewInterface mViewer; private final RenderData mRenderData; + private final DesktopCanvas mDesktopCanvas; + private InputStrategyInterface mInputStrategy; private GestureDetector mScroller; private ScaleGestureDetector mZoomer; @@ -43,12 +41,6 @@ private SwipePinchDetector mSwipePinchDetector; /** - * The current cursor position is stored here as floats, so that the desktop image can be - * positioned with sub-pixel accuracy, to give a smoother panning animation at high zoom levels. - */ - private PointF mCursorPosition; - - /** * Used for tracking swipe gestures. Only the Y-direction is needed for responding to swipe-up * or swipe-down. */ @@ -81,21 +73,10 @@ */ private boolean mSwipeCompleted = false; - /** - * Represents the amount of vertical space in pixels used by the soft input device and - * accompanying system UI. - */ - private int mInputMethodOffsetY = 0; - - /** - * Represents the amount of horizontal space in pixels used by the soft input device and - * accompanying system UI. - */ - private int mInputMethodOffsetX = 0; - public TouchInputHandler(DesktopViewInterface viewer, Context context, RenderData renderData) { mViewer = viewer; mRenderData = renderData; + mDesktopCanvas = new DesktopCanvas(mViewer, mRenderData); GestureListener listener = new GestureListener(); mScroller = new GestureDetector(context, listener, null, false); @@ -111,8 +92,6 @@ mFlingScroller = new Scroller(context); mSwipePinchDetector = new SwipePinchDetector(context); - mCursorPosition = new PointF(); - // The threshold needs to be bigger than the ScaledTouchSlop used by the gesture-detectors, // so that a gesture cannot be both a tap and a swipe. It also needs to be small enough so // that intentional swipes are usually detected. @@ -120,148 +99,6 @@ mSwipeThreshold = 40 * density; } - /** - * Moves the mouse-cursor, injects a mouse-move event and repositions the image. - */ - private void moveCursor(float newX, float newY) { - synchronized (mRenderData) { - // Constrain cursor to the image area. - if (newX < 0) newX = 0; - if (newY < 0) newY = 0; - if (newX > mRenderData.imageWidth) newX = mRenderData.imageWidth; - if (newY > mRenderData.imageHeight) newY = mRenderData.imageHeight; - mCursorPosition.set(newX, newY); - repositionImage(); - } - - mViewer.injectMouseEvent((int) newX, (int) newY, BUTTON_UNDEFINED, false); - } - - /** - * Repositions the image by translating it (without affecting the zoom level) to place the - * cursor close to the center of the screen. - */ - private void repositionImage() { - synchronized (mRenderData) { - float adjustedScreenWidth = mRenderData.screenWidth - mInputMethodOffsetX; - float adjustedScreenHeight = mRenderData.screenHeight - mInputMethodOffsetY; - - // Get the current cursor position in screen coordinates. - float[] cursorScreen = {mCursorPosition.x, mCursorPosition.y}; - mRenderData.transform.mapPoints(cursorScreen); - - // Translate so the cursor is displayed in the middle of the screen. - mRenderData.transform.postTranslate( - (float) adjustedScreenWidth / 2 - cursorScreen[0], - (float) adjustedScreenHeight / 2 - cursorScreen[1]); - - // Now the cursor is displayed in the middle of the screen, see if the image can be - // panned so that more of it is visible. The primary goal is to show as much of the - // image as possible. The secondary goal is to keep the cursor in the middle. - - // Get the coordinates of the desktop rectangle (top-left/bottom-right corners) in - // screen coordinates. Order is: left, top, right, bottom. - RectF rectScreen = new RectF(0, 0, mRenderData.imageWidth, mRenderData.imageHeight); - mRenderData.transform.mapRect(rectScreen); - - float leftDelta = rectScreen.left; - float rightDelta = rectScreen.right - mRenderData.screenWidth + mInputMethodOffsetX; - float topDelta = rectScreen.top; - float bottomDelta = rectScreen.bottom - mRenderData.screenHeight + mInputMethodOffsetY; - float xAdjust = 0; - float yAdjust = 0; - - if (rectScreen.right - rectScreen.left < adjustedScreenWidth) { - // Image is narrower than the screen, so center it. - xAdjust = -(rightDelta + leftDelta) / 2; - } else if (leftDelta > 0 && rightDelta > 0) { - // Panning the image left will show more of it. - xAdjust = -Math.min(leftDelta, rightDelta); - } else if (leftDelta < 0 && rightDelta < 0) { - // Pan the image right. - xAdjust = Math.min(-leftDelta, -rightDelta); - } - - // Apply similar logic for yAdjust. - if (rectScreen.bottom - rectScreen.top < adjustedScreenHeight) { - yAdjust = -(bottomDelta + topDelta) / 2; - } else if (topDelta > 0 && bottomDelta > 0) { - yAdjust = -Math.min(topDelta, bottomDelta); - } else if (topDelta < 0 && bottomDelta < 0) { - yAdjust = Math.min(-topDelta, -bottomDelta); - } - - mRenderData.transform.postTranslate(xAdjust, yAdjust); - } - mViewer.transformationChanged(); - } - - /** - * Repositions the image by translating and zooming it, to keep the zoom level within sensible - * limits. The minimum zoom level is chosen to avoid black space around all 4 sides. The - * maximum zoom level is set arbitrarily, so that the user can zoom out again in a reasonable - * time, and to prevent arithmetic overflow problems from displaying the image. - */ - private void repositionImageWithZoom() { - synchronized (mRenderData) { - // Avoid division by zero in case this gets called before the image size is initialized. - if (mRenderData.imageWidth == 0 || mRenderData.imageHeight == 0) { - return; - } - - // Zoom out if the zoom level is too high. - float currentZoomLevel = mRenderData.transform.mapRadius(1.0f); - if (currentZoomLevel > MAX_ZOOM_FACTOR) { - mRenderData.transform.setScale(MAX_ZOOM_FACTOR, MAX_ZOOM_FACTOR); - } - - // Get image size scaled to screen coordinates. - float[] imageSize = {mRenderData.imageWidth, mRenderData.imageHeight}; - mRenderData.transform.mapVectors(imageSize); - - if (imageSize[0] < mRenderData.screenWidth && imageSize[1] < mRenderData.screenHeight) { - // Displayed image is too small in both directions, so apply the minimum zoom - // level needed to fit either the width or height. - float scale = Math.min((float) mRenderData.screenWidth / mRenderData.imageWidth, - (float) mRenderData.screenHeight / mRenderData.imageHeight); - mRenderData.transform.setScale(scale, scale); - } - - repositionImage(); - } - } - - /** Injects a button event using the current cursor location. */ - private void injectButtonEvent(int button, boolean pressed) { - mViewer.injectMouseEvent((int) mCursorPosition.x, (int) mCursorPosition.y, button, pressed); - } - - /** Processes a (multi-finger) swipe gesture. */ - private boolean onSwipe() { - if (mTotalMotionY > mSwipeThreshold) { - // Swipe down occurred. - mViewer.showActionBar(); - } else if (mTotalMotionY < -mSwipeThreshold) { - // Swipe up occurred. - mViewer.showKeyboard(); - } else { - return false; - } - - mSuppressCursorMovement = true; - mSuppressFling = true; - mSwipeCompleted = true; - return true; - } - - /** Injects a button-up event if the button is currently held down (during a drag event). */ - private void releaseAnyHeldButton() { - if (mHeldButton != BUTTON_UNDEFINED) { - injectButtonEvent(mHeldButton, false); - mHeldButton = BUTTON_UNDEFINED; - } - } - @Override public boolean onTouchEvent(MotionEvent event) { // Avoid short-circuit logic evaluation - ensure all gesture detectors see all events so @@ -295,28 +132,27 @@ @Override public void onClientSizeChanged(int width, int height) { - repositionImageWithZoom(); + mDesktopCanvas.repositionImageWithZoom(); } @Override public void onHostSizeChanged(int width, int height) { moveCursor((float) width / 2, (float) height / 2); - repositionImageWithZoom(); + mDesktopCanvas.resizeImageToFitScreen(); } @Override public void onSoftInputMethodVisibilityChanged(boolean inputMethodVisible, Rect bounds) { synchronized (mRenderData) { if (inputMethodVisible) { - mInputMethodOffsetY = mRenderData.screenHeight - bounds.bottom; - mInputMethodOffsetX = mRenderData.screenWidth - bounds.right; + mDesktopCanvas.setInputMethodOffsetValues(mRenderData.screenWidth - bounds.right, + mRenderData.screenHeight - bounds.bottom); } else { - mInputMethodOffsetY = 0; - mInputMethodOffsetX = 0; + mDesktopCanvas.setInputMethodOffsetValues(0, 0); } } - repositionImageWithZoom(); + mDesktopCanvas.repositionImageWithZoom(); } @Override @@ -336,7 +172,74 @@ canvasToImage.mapVectors(delta); } - moveCursor(mCursorPosition.x + delta[0], mCursorPosition.y + delta[1]); + moveCursorRelative(-delta[0], -delta[1]); + } + + @Override + public void setInputStrategy(InputStrategyInterface inputStrategy) { + mInputStrategy = inputStrategy; + mDesktopCanvas.setCenterCursorInView(mInputStrategy.centerCursorInView()); + } + + /** Moves the mouse-cursor relative to the current position. */ + private void moveCursorRelative(float deltaX, float deltaY) { + if (mInputStrategy.invertCursorMovement()) { + deltaX = -deltaX; + deltaY = -deltaY; + } + + PointF cursorPosition = mDesktopCanvas.getCursorPosition(); + moveCursor(cursorPosition.x + deltaX, cursorPosition.y + deltaY); + } + + /** Moves the mouse-cursor, injects a mouse-move event and repositions the image. */ + private void moveCursor(float newX, float newY) { + synchronized (mRenderData) { + // Constrain cursor to the image area. + if (newX < 0) { + newX = 0; + } else if (newX > mRenderData.imageWidth) { + newX = mRenderData.imageWidth; + } + + if (newY < 0) { + newY = 0; + } else if (newY > mRenderData.imageHeight) { + newY = mRenderData.imageHeight; + } + + mDesktopCanvas.setCursorPosition(newX, newY); + } + + mDesktopCanvas.repositionImage(); + + mInputStrategy.injectRemoteMoveEvent((int) newX, (int) newY); + } + + /** Processes a (multi-finger) swipe gesture. */ + private boolean onSwipe() { + if (mTotalMotionY > mSwipeThreshold) { + // Swipe down occurred. + mViewer.showActionBar(); + } else if (mTotalMotionY < -mSwipeThreshold) { + // Swipe up occurred. + mViewer.showKeyboard(); + } else { + return false; + } + + mSuppressCursorMovement = true; + mSuppressFling = true; + mSwipeCompleted = true; + return true; + } + + /** Injects a button-up event if the button is currently held down (during a drag event). */ + private void releaseAnyHeldButton() { + if (mHeldButton != BUTTON_UNDEFINED) { + mInputStrategy.injectRemoteButtonEvent(mHeldButton, false); + mHeldButton = BUTTON_UNDEFINED; + } } /** Responds to touch events filtered by the gesture detectors. */ @@ -358,7 +261,7 @@ } if (pointerCount == 2 && mSwipePinchDetector.isSwiping()) { - mViewer.injectMouseWheelDeltaEvent(-(int) distanceX, -(int) distanceY); + mInputStrategy.injectRemoteScrollEvent(-(int) distanceX, -(int) distanceY); // Prevent the cursor being moved or flung by the gesture. mSuppressCursorMovement = true; @@ -376,7 +279,7 @@ canvasToImage.mapVectors(delta); } - moveCursor(mCursorPosition.x - delta[0], mCursorPosition.y - delta[1]); + moveCursorRelative(delta[0], delta[1]); return true; } @@ -425,7 +328,8 @@ mRenderData.transform.postScale( scaleFactor, scaleFactor, detector.getFocusX(), detector.getFocusY()); } - repositionImageWithZoom(); + mDesktopCanvas.repositionImageWithZoom(); + return true; } @@ -450,6 +354,31 @@ onScale(detector); } + /** Called when the user taps the screen with one or more fingers. */ + @Override + public boolean onTap(int pointerCount) { + int button = mouseButtonFromPointerCount(pointerCount); + if (button == BUTTON_UNDEFINED) { + return false; + } else { + mInputStrategy.injectRemoteButtonEvent(button, true); + mInputStrategy.injectRemoteButtonEvent(button, false); + mViewer.showInputFeedback(mInputStrategy.getShortPressFeedbackType()); + return true; + } + } + + /** Called when a long-press is triggered for one or more fingers. */ + @Override + public void onLongPress(int pointerCount) { + mHeldButton = mouseButtonFromPointerCount(pointerCount); + if (mHeldButton != BUTTON_UNDEFINED) { + mInputStrategy.injectRemoteButtonEvent(mHeldButton, true); + mViewer.showInputFeedback(mInputStrategy.getLongPressFeedbackType()); + mSuppressFling = true; + } + } + /** Maps the number of fingers in a tap or long-press gesture to a mouse-button. */ private int mouseButtonFromPointerCount(int pointerCount) { switch (pointerCount) { @@ -463,29 +392,5 @@ return BUTTON_UNDEFINED; } } - - /** Called when the user taps the screen with one or more fingers. */ - @Override - public boolean onTap(int pointerCount) { - int button = mouseButtonFromPointerCount(pointerCount); - if (button == BUTTON_UNDEFINED) { - return false; - } else { - injectButtonEvent(button, true); - injectButtonEvent(button, false); - return true; - } - } - - /** Called when a long-press is triggered for one or more fingers. */ - @Override - public void onLongPress(int pointerCount) { - mHeldButton = mouseButtonFromPointerCount(pointerCount); - if (mHeldButton != BUTTON_UNDEFINED) { - injectButtonEvent(mHeldButton, true); - mViewer.showLongPressFeedback(); - mSuppressFling = true; - } - } } }
diff --git a/remoting/android/java/src/org/chromium/chromoting/TouchInputHandlerInterface.java b/remoting/android/java/src/org/chromium/chromoting/TouchInputHandlerInterface.java index 8bba3287..80bd162 100644 --- a/remoting/android/java/src/org/chromium/chromoting/TouchInputHandlerInterface.java +++ b/remoting/android/java/src/org/chromium/chromoting/TouchInputHandlerInterface.java
@@ -15,7 +15,7 @@ * showing/hiding UI elements). All methods are called on the main UI thread. */ public interface TouchInputHandlerInterface { - // These constants must match those in the generated struct protoc::MouseEvent_MouseButton. + // These constants must match those in the generated struct protocol::MouseEvent_MouseButton. int BUTTON_UNDEFINED = 0; int BUTTON_LEFT = 1; int BUTTON_MIDDLE = 2; @@ -52,4 +52,7 @@ * cancelled. After this method returns, the DesktopView will schedule a repaint. */ void processAnimation(); + + /** Sets the underlying strategy to use when translating and forwarding local touch input. */ + void setInputStrategy(InputStrategyInterface inputStrategy); }
diff --git a/remoting/android/java/src/org/chromium/chromoting/TrackpadInputStrategy.java b/remoting/android/java/src/org/chromium/chromoting/TrackpadInputStrategy.java new file mode 100644 index 0000000..edc9baf --- /dev/null +++ b/remoting/android/java/src/org/chromium/chromoting/TrackpadInputStrategy.java
@@ -0,0 +1,90 @@ +// Copyright 2015 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. + +package org.chromium.chromoting; + +import org.chromium.chromoting.jni.JniInterface; + +/** + * Defines a set of behavior and methods to simulate trackpad behavior when responding to + * local input event data. This class is also responsible for forwarding input event data + * to the remote host for injection there. + */ +public class TrackpadInputStrategy implements InputStrategyInterface { + private final RenderData mRenderData; + private final DesktopViewInterface mViewer; + + public TrackpadInputStrategy(DesktopViewInterface viewer, RenderData renderData) { + mViewer = viewer; + mRenderData = renderData; + } + + @Override + public void injectRemoteMoveEvent(int x, int y) { + injectRemoteButtonEvent(x, y, TouchInputHandlerInterface.BUTTON_UNDEFINED, false); + } + + @Override + public void injectRemoteButtonEvent(int button, boolean pressed) { + int x; + int y; + synchronized (mRenderData) { + x = mRenderData.cursorPosition.x; + y = mRenderData.cursorPosition.y; + } + + injectRemoteButtonEvent(x, y, button, pressed); + } + + @Override + public void injectRemoteScrollEvent(int deltaX, int deltaY) { + JniInterface.sendMouseWheelEvent(deltaX, deltaY); + } + + @Override + public DesktopView.InputFeedbackType getShortPressFeedbackType() { + return DesktopView.InputFeedbackType.NONE; + } + + @Override + public DesktopView.InputFeedbackType getLongPressFeedbackType() { + return DesktopView.InputFeedbackType.SMALL_ANIMATION; + } + + @Override + public boolean centerCursorInView() { + return true; + } + + @Override + public boolean invertCursorMovement() { + return true; + } + + private void injectRemoteButtonEvent(int x, int y, int button, boolean pressed) { + boolean cursorMoved = false; + synchronized (mRenderData) { + // Test if the cursor actually moved, which requires repainting the cursor. This + // requires that |mRenderData.cursorPosition| was not assigned to beforehand. + if (x != mRenderData.cursorPosition.x) { + mRenderData.cursorPosition.x = x; + cursorMoved = true; + } + if (y != mRenderData.cursorPosition.y) { + mRenderData.cursorPosition.y = y; + cursorMoved = true; + } + } + + if (button == TouchInputHandlerInterface.BUTTON_UNDEFINED && !cursorMoved) { + // No need to inject anything or repaint. + return; + } + + JniInterface.sendMouseEvent(x, y, button, pressed); + if (cursorMoved) { + mViewer.transformationChanged(); + } + } +}
diff --git a/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc b/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc index 8c679a3..8bfb025b 100644 --- a/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc +++ b/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc
@@ -21,6 +21,10 @@ #include "sandbox/linux/services/syscall_wrappers.h" #include "sandbox/linux/system_headers/linux_syscalls.h" +#if !defined(SO_PEEK_OFF) +#define SO_PEEK_OFF 42 +#endif + // Changing this implementation will have an effect on *all* policies. // Currently this means: Renderer/Worker, GPU, Flash and NaCl. @@ -227,6 +231,16 @@ return RestrictSocketcallCommand(); #endif +#if defined(__x86_64__) + if (sysno == __NR_getsockopt || sysno ==__NR_setsockopt) { + // Used by Mojo EDK to catch a message pipe being sent over itself. + const Arg<int> level(1); + const Arg<int> optname(2); + return If(level == SOL_SOCKET && optname == SO_PEEK_OFF, + Allow()).Else(CrashSIGSYS()); + } +#endif + if (IsBaselinePolicyWatched(sysno)) { // Previously unseen syscalls. TODO(jln): some of these should // be denied gracefully right away.
diff --git a/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc b/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc index 614849f..7ece8be 100644 --- a/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc +++ b/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc
@@ -6,6 +6,7 @@ #include <errno.h> #include <fcntl.h> +#include <netinet/in.h> #include <sched.h> #include <signal.h> #include <string.h> @@ -36,6 +37,10 @@ #include "sandbox/linux/tests/test_utils.h" #include "sandbox/linux/tests/unit_tests.h" +#if !defined(SO_PEEK_OFF) +#define SO_PEEK_OFF 42 +#endif + namespace sandbox { namespace { @@ -329,6 +334,51 @@ clock_gettime(CLOCK_MONOTONIC_RAW, &ts); } +#if defined(__x86_64__) +BPF_DEATH_TEST_C(BaselinePolicy, + GetSockOptWrongLevelSigsys, + DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), + BaselinePolicy) { + int fds[2]; + PCHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0); + int id; + socklen_t peek_off_size = sizeof(id); + getsockopt(fds[0], IPPROTO_TCP, SO_PEEK_OFF, &id, &peek_off_size); +} + +BPF_DEATH_TEST_C(BaselinePolicy, + GetSockOptWrongOptionSigsys, + DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), + BaselinePolicy) { + int fds[2]; + PCHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0); + int id; + socklen_t peek_off_size = sizeof(id); + getsockopt(fds[0], SOL_SOCKET, SO_DEBUG, &id, &peek_off_size); +} + +BPF_DEATH_TEST_C(BaselinePolicy, + SetSockOptWrongLevelSigsys, + DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), + BaselinePolicy) { + int fds[2]; + PCHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0); + int id; + setsockopt(fds[0], IPPROTO_TCP, SO_PEEK_OFF, &id, sizeof(id)); +} + + +BPF_DEATH_TEST_C(BaselinePolicy, + SetSockOptWrongOptionSigsys, + DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), + BaselinePolicy) { + int fds[2]; + PCHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0); + int id; + setsockopt(fds[0], SOL_SOCKET, SO_DEBUG, &id, sizeof(id)); +} +#endif + } // namespace } // namespace sandbox
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 25b01660..5fbc1d34 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -503,6 +503,9 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", + "override_compile_targets": [ + "telemetry_gpu_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -510,6 +513,9 @@ { "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", + "override_compile_targets": [ + "telemetry_perf_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -1430,6 +1436,9 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", + "override_compile_targets": [ + "telemetry_gpu_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -1437,6 +1446,9 @@ { "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", + "override_compile_targets": [ + "telemetry_perf_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -1644,6 +1656,9 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", + "override_compile_targets": [ + "telemetry_gpu_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -1651,6 +1666,9 @@ { "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", + "override_compile_targets": [ + "telemetry_perf_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -4739,6 +4757,9 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", + "override_compile_targets": [ + "telemetry_gpu_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -4746,6 +4767,9 @@ { "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", + "override_compile_targets": [ + "telemetry_perf_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -4937,6 +4961,9 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", + "override_compile_targets": [ + "telemetry_gpu_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -4944,6 +4971,9 @@ { "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", + "override_compile_targets": [ + "telemetry_perf_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -5240,6 +5270,9 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", + "override_compile_targets": [ + "telemetry_gpu_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -5247,6 +5280,9 @@ { "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", + "override_compile_targets": [ + "telemetry_perf_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -5426,6 +5462,9 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", + "override_compile_targets": [ + "telemetry_gpu_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -5433,6 +5472,9 @@ { "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", + "override_compile_targets": [ + "telemetry_perf_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true }
diff --git a/testing/buildbot/chromium.json b/testing/buildbot/chromium.json index 47e8916e..e4bdc07 100644 --- a/testing/buildbot/chromium.json +++ b/testing/buildbot/chromium.json
@@ -1,4 +1,26 @@ { + "Linux": { + "additional_compile_targets": [ + "all" + ], + "scripts": [ + { + "name": "checklicenses", + "script": "checklicenses.py" + }, + { + "name": "checkperms", + "script": "checkperms.py" + }, + { + "args": [ + "linux-release/sizes" + ], + "name": "sizes", + "script": "sizes.py" + } + ] + }, "Linux x64": { "additional_compile_targets": [ "all"
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json index 9caca88..ed24041 100644 --- a/testing/buildbot/chromium.linux.json +++ b/testing/buildbot/chromium.linux.json
@@ -673,6 +673,9 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", + "override_compile_targets": [ + "telemetry_gpu_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -680,6 +683,9 @@ { "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", + "override_compile_targets": [ + "telemetry_perf_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -1045,6 +1051,9 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", + "override_compile_targets": [ + "telemetry_gpu_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -1052,6 +1061,9 @@ { "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", + "override_compile_targets": [ + "telemetry_perf_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true }
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json index afc8c09..2da7a3f 100644 --- a/testing/buildbot/chromium.mac.json +++ b/testing/buildbot/chromium.mac.json
@@ -318,6 +318,9 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", + "override_compile_targets": [ + "telemetry_gpu_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -325,6 +328,9 @@ { "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", + "override_compile_targets": [ + "telemetry_perf_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -613,6 +619,9 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", + "override_compile_targets": [ + "telemetry_gpu_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -620,6 +629,9 @@ { "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", + "override_compile_targets": [ + "telemetry_perf_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -908,6 +920,9 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", + "override_compile_targets": [ + "telemetry_gpu_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -915,6 +930,9 @@ { "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", + "override_compile_targets": [ + "telemetry_perf_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -1203,6 +1221,9 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", + "override_compile_targets": [ + "telemetry_gpu_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -1210,6 +1231,9 @@ { "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", + "override_compile_targets": [ + "telemetry_perf_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -1499,6 +1523,19 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", + "override_compile_targets": [ + "telemetry_gpu_unittests_run" + ], + "swarming": { + "can_use_on_swarming_builders": true + } + }, + { + "isolate_name": "telemetry_perf_unittests", + "name": "telemetry_perf_unittests", + "override_compile_targets": [ + "telemetry_perf_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -1510,10 +1547,6 @@ "script": "telemetry_unittests.py" }, { - "name": "telemetry_perf_unittests", - "script": "telemetry_perf_unittests.py" - }, - { "name": "nacl_integration", "script": "nacl_integration.py" }
diff --git a/testing/buildbot/chromium.win.json b/testing/buildbot/chromium.win.json index f4e68fa4..cc97231 100644 --- a/testing/buildbot/chromium.win.json +++ b/testing/buildbot/chromium.win.json
@@ -690,6 +690,9 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", + "override_compile_targets": [ + "telemetry_gpu_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -697,6 +700,9 @@ { "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", + "override_compile_targets": [ + "telemetry_perf_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -1138,6 +1144,9 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", + "override_compile_targets": [ + "telemetry_gpu_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -1145,6 +1154,9 @@ { "isolate_name": "telemetry_perf_unittests", "name": "telemetry_perf_unittests", + "override_compile_targets": [ + "telemetry_perf_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -1490,6 +1502,19 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", + "override_compile_targets": [ + "telemetry_gpu_unittests_run" + ], + "swarming": { + "can_use_on_swarming_builders": true + } + }, + { + "isolate_name": "telemetry_perf_unittests", + "name": "telemetry_perf_unittests", + "override_compile_targets": [ + "telemetry_perf_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true } @@ -1499,10 +1524,6 @@ { "name": "telemetry_unittests", "script": "telemetry_unittests.py" - }, - { - "name": "telemetry_perf_unittests", - "script": "telemetry_perf_unittests.py" } ] }, @@ -1974,6 +1995,9 @@ { "isolate_name": "telemetry_gpu_unittests", "name": "telemetry_gpu_unittests", + "override_compile_targets": [ + "telemetry_gpu_unittests_run" + ], "swarming": { "can_use_on_swarming_builders": true }
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index a1dae79..49c7233 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -258,6 +258,8 @@ crbug.com/535408 fast/js/function-bind.html [ NeedsManualRebaseline ] +crbug.com/334828 fast/box-shadow/inset-subpixel.html [ NeedsRebaseline ] + crbug.com/552574 fast/js/regexp-caching.html [ NeedsManualRebaseline ] crbug.com/498539 http/tests/inspector/elements/styles/selector-line.html [ Pass Timeout ] @@ -1359,5 +1361,3 @@ crbug.com/548765 http/tests/inspector/console-fetch-logging.html [ Failure Pass Slow ] crbug.com/549314 [ XP ] inspector-protocol/layout-fonts/unicode-range-combining-chars-fallback.html [ Failure ] - -crbug.com/555052 http/tests/misc/script-sync-slow-scripts-onerror.html [ Failure Pass ]
diff --git a/third_party/WebKit/LayoutTests/fast/box-shadow/degenerate-radius-crash-expected.txt b/third_party/WebKit/LayoutTests/fast/box-shadow/degenerate-radius-crash-expected.txt new file mode 100644 index 0000000..9b9c9725 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/box-shadow/degenerate-radius-crash-expected.txt
@@ -0,0 +1 @@ +PASS: did not crash.
diff --git a/third_party/WebKit/LayoutTests/fast/box-shadow/degenerate-radius-crash.html b/third_party/WebKit/LayoutTests/fast/box-shadow/degenerate-radius-crash.html new file mode 100644 index 0000000..9763d32 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/box-shadow/degenerate-radius-crash.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<head> + +<style> +div { + width: 200px; + height: 100px; +} + +.negative { + box-shadow: 3px 3px -10px; +} + +.negative-inset { + box-shadow: 3px 3px -10px inset; +} + +.overflow { + box-shadow: 3px 3px 100000000000000000000000000px; +} + +.overflow-inset { + box-shadow: 3px 3px 100000000000000000000000000px inset; +} + +</style> +</head> + +<body> + <!-- Test for crbug.com/424119 --> + <div class="negative"></div> + <div class="negative-inset"></div> + <div class="overflow"></div> + <div class="overflow-inset"></div> + + PASS: did not crash. + + <script> + if (window.testRunner) + testRunner.dumpAsText(); + </script> +</body>
diff --git a/third_party/WebKit/LayoutTests/fast/box-shadow/inset-subpixel.html b/third_party/WebKit/LayoutTests/fast/box-shadow/inset-subpixel.html new file mode 100644 index 0000000..5567c4c9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/box-shadow/inset-subpixel.html
@@ -0,0 +1,40 @@ +<style> + div.square { + width: 80px; + height: 80px; + margin: 10px; + display: inline-block; + background: lightyellow; + border: 10px solid green; + } + .rounded div.square { + -webkit-border-radius: 20px; + } +</style> +<div> + <div class="square" style="-webkit-box-shadow: rgba(0, 0, 0, 0.2) 15.5px 15.5px inset;"></div> + <div class="square" style="-webkit-box-shadow: -15px 15px 0 5.5px rgba(0, 0, 0, 0.2) inset;"></div> + <div class="square" style="-webkit-box-shadow: inset rgba(0, 0, 0, 0.2) 15.5px -15.5px 0 -10px;"></div> + <div class="square" style="-webkit-box-shadow: inset -15.5px -15.5px 5.5px rgba(0, 0, 0, 0.2);"></div> + <div class="square" style="-webkit-box-shadow: rgba(0, 0, 0, 0.2) inset -15.5px -15.5px 5.5px;"></div> +</div> +<div class="rounded"> + <div class="square" style="-webkit-box-shadow: rgba(0, 0, 0, 0.2) 15.5px 15.5px inset;"></div> + <div class="square" style="-webkit-box-shadow: rgba(0, 0, 0, 0.2) -15px 15px 0 5.5px inset;"></div> + <div class="square" style="-webkit-box-shadow: rgba(0, 0, 0, 0.2) 15.5px -15.5px 0 -10px inset;"></div> + <div class="square" style="-webkit-box-shadow: rgba(0, 0, 0, 0.2) -15.5px -15.5px 5.5px inset;"></div> + <div class="square" style="-webkit-box-shadow: rgba(0, 0, 0, 0.2) -15.5px -15.5px inset, rgba(0, 0, 127, 0.6) 5px 5px 5px inset; border-style: dashed;"></div> +</div> +<div style="width: 600px; text-align: center;"> + <span style=" + padding: 0 15px; + font-size: 72px; + background-color: lightyellow; + -webkit-border-radius: 10px; + border: 5px solid green; + line-height: 1.5; + -webkit-box-shadow: 15px 15px 5px rgba(0, 0, 0, 0.2) inset; + "> + This sentence is too long to fit on a single line. + </span> +</div>
diff --git a/third_party/WebKit/LayoutTests/fast/domurl/resources/urlsearchparams-worker.js b/third_party/WebKit/LayoutTests/fast/domurl/resources/urlsearchparams-worker.js new file mode 100644 index 0000000..999ddfc --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/domurl/resources/urlsearchparams-worker.js
@@ -0,0 +1,14 @@ +importScripts("../../../resources/testharness.js") + +test(function() { + assert_true('URLSearchParams' in self); + assert_true('toString' in URLSearchParams.prototype); + assert_true('append' in URLSearchParams.prototype); + assert_true('delete' in URLSearchParams.prototype); + assert_true('get' in URLSearchParams.prototype); + assert_true('getAll' in URLSearchParams.prototype); + assert_true('has' in URLSearchParams.prototype); + assert_true('set' in URLSearchParams.prototype); +}, 'URLSearchParams interface'); + +done();
diff --git a/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-append.html b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-append.html new file mode 100644 index 0000000..74071f1a --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-append.html
@@ -0,0 +1,51 @@ +<!doctype html> +<html> +<head> +<meta charset="utf8"> +<link rel="help" href="https://url.spec.whatwg.org/#dom-urlsearchparams-append"> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="resources/testharness-extras.js"></script> +<script> +test(function() { + var params = new URLSearchParams(); + params.append('a', 'b'); + assert_equals(params + '', 'a=b'); + params.append('a', 'b'); + assert_equals(params + '', 'a=b&a=b'); + params.append('a', 'c'); + assert_equals(params + '', 'a=b&a=b&a=c'); +}, 'Append same name'); + +test(function() { + var params = new URLSearchParams(); + params.append('', ''); + assert_equals(params + '', '='); + params.append('', ''); + assert_equals(params + '', '=&='); +}, 'Append empty strings'); + +test(function() { + var params = new URLSearchParams(); + params.append(null, null); + assert_equals(params + '', 'null=null'); + params.append(null, null); + assert_equals(params + '', 'null=null&null=null'); +}, 'Append null'); + +test(function() { + var params = new URLSearchParams(); + params.append('first', 1); + params.append('second', 2); + params.append('third', ''); + params.append('first', 10); + assert_true(params.has('first'), 'Search params object has name "first"'); + assert_equals(params.get('first'), '1', 'Search params object has name "first" with value "1"'); + assert_equals(params.get('second'), '2', 'Search params object has name "second" with value "2"'); + assert_equals(params.get('third'), '', 'Search params object has name "third" with value ""'); + params.append('first', 10); + assert_equals(params.get('first'), '1', 'Search params object has name "first" with value "1"'); +}, 'Append multiple'); +</script> +</head> +</html>
diff --git a/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-constructor.html b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-constructor.html new file mode 100644 index 0000000..33a446e --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-constructor.html
@@ -0,0 +1,163 @@ +<!doctype html> +<html> +<head> +<meta charset="utf8"> +<link rel="help" href="https://url.spec.whatwg.org/#urlsearchparams"> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="resources/testharness-extras.js"></script> +<script> +function assert_type_error(f, msg) { + assert_throws(TypeError(), f, msg); +} + +// Consider upstreaming something kinda like this. +function assert_iteration_equals(iteration, expectation) { + var actual = [...iteration]; + assert_equals(actual.length, expectation.length); + for (var i = 0; i < actual.length; i++) { + assert_equals(typeof actual[i], typeof expectation[i]); + if (actual[i] instanceof Array) + assert_array_equals(actual[i], expectation[i]); + else + assert_equals(actual[i], expectation[i]); + } +} + +test(function() { + var params = new URLSearchParams(); + assert_equals(params + '', ''); + params = new URLSearchParams(''); + assert_equals(params + '', ''); + params = new URLSearchParams('a=b'); + assert_equals(params + '', 'a=b'); + params = new URLSearchParams(params); + assert_equals(params + '', 'a=b'); +}, 'Basic URLSearchParams construction'); + +test(function() { + assert_type_error(function () { URLSearchParams(); }, 'Failed to construct \'URLSearchParams\': Please use the \'new\' operator, this DOM object constructor cannot be called as a function.'); + + var params = new URLSearchParams(''); + assert_not_equals(params, null, 'constructor returned non-null value.'); + assert_equals(params.__proto__, URLSearchParams.prototype, 'expected URLSearchParams.prototype as prototype.'); + params = new URLSearchParams({}); + assert_equals(params + '', '%5Bobject+Object%5D='); +}, 'URLSearchParams constructor, empty.'); + +test(function() { + var params = new URLSearchParams('a=b'); + assert_not_equals(params, null, 'constructor returned non-null value.'); + assert_true(params.has('a'), 'Search params object has name "a"'); + assert_false(params.has('b'), 'Search params object has not got name "b"'); + + var params = new URLSearchParams('a=b&c'); + assert_not_equals(params, null, 'constructor returned non-null value.'); + assert_true(params.has('a'), 'Search params object has name "a"'); + assert_true(params.has('c'), 'Search params object has name "c"'); + + var params = new URLSearchParams('&a&&& &&&&&a+b=& c&m%c3%b8%c3%b8'); + assert_not_equals(params, null, 'constructor returned non-null value.'); + assert_true(params.has('a'), 'Search params object has name "a"'); + assert_true(params.has('a b'), 'Search params object has name "a b"'); + assert_true(params.has(' '), 'Search params object has name " "'); + assert_false(params.has('c'), 'Search params object did not have the name "c"'); + assert_true(params.has(' c'), 'Search params object has name " c"'); + assert_true(params.has('møø'), 'Search params object has name "møø"'); +}, 'URLSearchParams constructor, string.'); + +test(function() { + var seed = new URLSearchParams('a=b&c=d'); + var params = new URLSearchParams(seed); + assert_not_equals(params, null, 'constructor returned non-null value.'); + assert_iteration_equals(params, [ ['a', 'b' ], [ 'c', 'd' ] ]); + // The name-value pairs are copied when created; later updates + // should not be observable. + seed.append('e', 'f'); + assert_false(params.has('e')); + params.append('g', 'h'); + assert_false(seed.has('g')); +}, 'URLSearchParams constructor, object.'); + +test(function() { + var params = new URLSearchParams('a=b+c'); + assert_equals(params.get('a'), 'b c'); + params = new URLSearchParams('a+b=c'); + assert_equals(params.get('a b'), 'c'); +}, 'Parse +'); + +test(function() { + var params = new URLSearchParams('a=b%2Bc'); + assert_equals(params.get('a'), 'b+c'); + params = new URLSearchParams('a%2Bb=c'); + assert_equals(params.get('a+b'), 'c'); +}, 'Parse %2B'); + +test(function() { + var params = new URLSearchParams('a=b c'); + assert_equals(params.get('a'), 'b c'); + params = new URLSearchParams('a b=c'); + assert_equals(params.get('a b'), 'c'); +}, 'Parse space'); + +test(function() { + var params = new URLSearchParams('a=b%20c'); + assert_equals(params.get('a'), 'b c'); + params = new URLSearchParams('a%20b=c'); + assert_equals(params.get('a b'), 'c'); +}, 'Parse %20'); + +test(function() { + var params = new URLSearchParams('a=b\0c'); + assert_equals(params.get('a'), 'b\0c'); + params = new URLSearchParams('a\0b=c'); + assert_equals(params.get('a\0b'), 'c'); +}, 'Parse \\0'); + +test(function() { + var params = new URLSearchParams('a=b%00c'); + assert_equals(params.get('a'), 'b\0c'); + params = new URLSearchParams('a%00b=c'); + assert_equals(params.get('a\0b'), 'c'); +}, 'Parse %00'); + +test(function() { + var params = new URLSearchParams('a=b\u2384'); + assert_equals(params.get('a'), 'b\u2384'); + params = new URLSearchParams('a\u2384b=c'); + assert_equals(params.get('a\u2384b'), 'c'); +}, 'Parse \u2384'); // Unicode Character 'COMPOSITION SYMBOL' (U+2384) + +test(function() { + var params = new URLSearchParams('a=b%e2%8e%84'); + assert_equals(params.get('a'), 'b\u2384'); + params = new URLSearchParams('a%e2%8e%84b=c'); + assert_equals(params.get('a\u2384b'), 'c'); +}, 'Parse %e2%8e%84'); // Unicode Character 'COMPOSITION SYMBOL' (U+2384) + +test(function() { + var params = new URLSearchParams('a=b\uD83D\uDCA9c'); + assert_equals(params.get('a'), 'b\uD83D\uDCA9c'); + params = new URLSearchParams('a\uD83D\uDCA9b=c'); + assert_equals(params.get('a\uD83D\uDCA9b'), 'c'); +}, 'Parse \uD83D\uDCA9'); // Unicode Character 'PILE OF POO' (U+1F4A9) + +test(function() { + var params = new URLSearchParams('a=b%f0%9f%92%a9c'); + assert_equals(params.get('a'), 'b\uD83D\uDCA9c'); + params = new URLSearchParams('a%f0%9f%92%a9b=c'); + assert_equals(params.get('a\uD83D\uDCA9b'), 'c'); +}, 'Parse %f0%9f%92%a9'); // Unicode Character 'PILE OF POO' (U+1F4A9) + +test(function() { + var params = new URLSearchParams('='); + assert_equals(params.toString(), '='); +}, 'Parse ='); + +test(function() { + var params = new URLSearchParams('foobar=a\nb'); + assert_equals(params.toString(), 'foobar=a%0Ab'); +}, 'Parse \\n'); +</script> +</head> +</html>
diff --git a/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-delete.html b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-delete.html new file mode 100644 index 0000000..0ffae60 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-delete.html
@@ -0,0 +1,42 @@ +<!doctype html> +<html> +<head> +<meta charset="utf8"> +<link rel="help" href="https://url.spec.whatwg.org/#dom-urlsearchparams-delete"> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="resources/testharness-extras.js"></script> +<script> +test(function() { + var params = new URLSearchParams('a=b&c=d'); + params.delete('a'); + assert_equals(params + '', 'c=d'); + params = new URLSearchParams('a=a&b=b&a=a&c=c'); + params.delete('a'); + assert_equals(params + '', 'b=b&c=c'); + params = new URLSearchParams('a=a&=&b=b&c=c'); + params.delete(''); + assert_equals(params + '', 'a=a&b=b&c=c'); + params = new URLSearchParams('a=a&null=null&b=b'); + params.delete(null); + assert_equals(params + '', 'a=a&b=b'); + params = new URLSearchParams('a=a&undefined=undefined&b=b'); + params.delete(undefined); + assert_equals(params + '', 'a=a&b=b'); +}, 'Delete basics'); + +test(function() { + var params = new URLSearchParams(); + params.append('first', 1); + assert_true(params.has('first'), 'Search params object has name "first"'); + assert_equals(params.get('first'), '1', 'Search params object has name "first" with value "1"'); + params.delete('first'); + assert_false(params.has('first'), 'Search params object has no "first" name'); + params.append('first', 1); + params.append('first', 10); + params.delete('first'); + assert_false(params.has('first'), 'Search params object has no "first" name'); +}, 'Deleting appended multiple'); +</script> +</head> +</html>
diff --git a/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-get.html b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-get.html new file mode 100644 index 0000000..91ef209a --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-get.html
@@ -0,0 +1,33 @@ +<!doctype html> +<html> +<head> +<meta charset="utf8"> +<link rel="help" href="https://url.spec.whatwg.org/#dom-urlsearchparams-get"> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="resources/testharness-extras.js"></script> +<script> +test(function() { + var params = new URLSearchParams('a=b&c=d'); + assert_equals(params.get('a'), 'b'); + assert_equals(params.get('c'), 'd'); + assert_equals(params.get('e'), null); + params = new URLSearchParams('a=b&c=d&a=e'); + assert_equals(params.get('a'), 'b'); + params = new URLSearchParams('=b&c=d'); + assert_equals(params.get(''), 'b'); + params = new URLSearchParams('a=&c=d&a=e'); + assert_equals(params.get('a'), ''); +}, 'Get basics'); + +test(function() { + var params = new URLSearchParams('first=second&third&&'); + assert_true(params != null, 'constructor returned non-null value.'); + assert_true(params.has('first'), 'Search params object has name "first"'); + assert_equals(params.get('first'), 'second', 'Search params object has name "first" with value "second"'); + assert_equals(params.get('third'), '', 'Search params object has name "third" with the empty value.'); + assert_equals(params.get('fourth'), null, 'Search params object has no "fourth" name and value.'); +}, 'More get() basics'); +</script> +</head> +</html>
diff --git a/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-getall.html b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-getall.html new file mode 100644 index 0000000..4454e2b --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-getall.html
@@ -0,0 +1,37 @@ +<!doctype html> +<html> +<head> +<meta charset="utf8"> +<link rel="help" href="https://url.spec.whatwg.org/#dom-urlsearchparams-getAll"> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="resources/testharness-extras.js"></script> +<script> +test(function() { + var params = new URLSearchParams('a=b&c=d'); + assert_array_equals(params.getAll('a'), ['b']); + assert_array_equals(params.getAll('c'), ['d']); + assert_array_equals(params.getAll('e'), []); + params = new URLSearchParams('a=b&c=d&a=e'); + assert_array_equals(params.getAll('a'), ['b', 'e']); + params = new URLSearchParams('=b&c=d'); + assert_array_equals(params.getAll(''), ['b']); + params = new URLSearchParams('a=&c=d&a=e'); + assert_array_equals(params.getAll('a'), ['', 'e']); +}, 'getAll() basics'); + +test(function() { + var params = new URLSearchParams('a=1&a=2&a=3&a'); + assert_true(params.has('a'), 'Search params object has name "a"'); + var matches = params.getAll('a'); + assert_true(matches && matches.length == 4, 'Search params object has values for name "a"'); + assert_array_equals(matches, ['1', '2', '3', ''], 'Search params object has expected name "a" values'); + params.set('a', 'one'); + assert_equals(params.get('a'), 'one', 'Search params object has name "a" with value "one"'); + var matches = params.getAll('a'); + assert_true(matches && matches.length == 1, 'Search params object has values for name "a"'); + assert_array_equals(matches, ['one'], 'Search params object has expected name "a" values'); +}, 'getAll() multiples'); +</script> +</head> +</html>
diff --git a/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-has.html b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-has.html new file mode 100644 index 0000000..e020253 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-has.html
@@ -0,0 +1,36 @@ +<!doctype html> +<html> +<head> +<meta charset="utf8"> +<link rel="help" href="https://url.spec.whatwg.org/#dom-urlsearchparams-has"> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="resources/testharness-extras.js"></script> +<script> +test(function() { + var params = new URLSearchParams('a=b&c=d'); + assert_true(params.has('a')); + assert_true(params.has('c')); + assert_false(params.has('e')); + params = new URLSearchParams('a=b&c=d&a=e'); + assert_true(params.has('a')); + params = new URLSearchParams('=b&c=d'); + assert_true(params.has('')); + params = new URLSearchParams('null=a'); + assert_true(params.has(null)); +}, 'has() basics'); + +test(function() { + var params = new URLSearchParams('a=b&c=d&&'); + params.append('first', 1); + params.append('first', 2); + assert_true(params.has('a'), 'Search params object has name "a"'); + assert_true(params.has('c'), 'Search params object has name "c"'); + assert_true(params.has('first'), 'Search params object has name "first"'); + assert_false(params.has('d'), 'Search params object has no name "d"'); + params.delete('first'); + assert_false(params.has('first'), 'Search params object has no name "first"'); +}, 'has() following delete()'); +</script> +</head> +</html>
diff --git a/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-iterable.html b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-iterable.html new file mode 100644 index 0000000..3e7b0f0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-iterable.html
@@ -0,0 +1,66 @@ +<!doctype html> +<html> +<head> +<meta charset="utf8"> +<link rel="help" href="https://url.spec.whatwg.org/#dom-urlsearchparams"> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script> +var expectedValues = { + 'a': '1', + 'b': '2', + 'c': '3' +}; + +var params = new URLSearchParams(); +params.append('a', '1'); +params.append('b', '2'); +params.append('c', '3'); + +test(function() { + for (var param of params) { + var key = param[0]; + var value = param[1]; + assert_true(key in expectedValues); + assert_equals(params.get(key), expectedValues[key]); + assert_equals(value, expectedValues[key]); + } +}, 'for...of Iteration'); + +test(function() { + for (var key of params.keys()) { + assert_true(key in expectedValues); + assert_equals(params.get(key), expectedValues[key]); + } +}, 'keys'); + +test(function() { + var expectedKeys = {}; + for (var key in expectedValues) + expectedKeys[expectedValues[key]] = key; + + for (var value of params.values()) + assert_true(value in expectedKeys); +}, 'values'); + +test(function () { + for (var param of params.entries()) { + var key = param[0]; + var value = param[1]; + assert_true(key in expectedValues); + assert_equals(params.get(key), expectedValues[key]); + assert_equals(value, expectedValues[key]); + } +}, 'entries'); + +test(function () { + params.forEach(function (value, key, paramsObject) { + assert_true(key in expectedValues); + assert_equals(params.get(key), expectedValues[key]); + assert_equals(value, expectedValues[key]); + assert_equals(paramsObject, params); + }); +}, 'forEach'); +</script> +</head> +</html>
diff --git a/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-set.html b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-set.html new file mode 100644 index 0000000..bb9b8a1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-set.html
@@ -0,0 +1,37 @@ +<!doctype html> +<html> +<head> +<meta charset="utf8"> +<link rel="help" href="https://url.spec.whatwg.org/#dom-urlsearchparams-set"> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="resources/testharness-extras.js"></script> +<script> +test(function() { + var params = new URLSearchParams('a=b&c=d'); + params.set('a', 'B'); + assert_equals(params + '', 'a=B&c=d'); + params = new URLSearchParams('a=b&c=d&a=e'); + params.set('a', 'B'); + assert_equals(params + '', 'a=B&c=d') + params.set('e', 'f'); + assert_equals(params + '', 'a=B&c=d&e=f') +}, 'set() basics'); + +test(function() { + var params = new URLSearchParams('a=1&a=2&a=3'); + assert_true(params.has('a'), 'Search params object has name "a"'); + assert_equals(params.get('a'), '1', 'Search params object has name "a" with value "1"'); + params.set('first', 4); + assert_true(params.has('a'), 'Search params object has name "a"'); + assert_equals(params.get('a'), '1', 'Search params object has name "a" with value "1"'); + assert_equals(params + '', 'a=1&a=2&a=3&first=4'); + params.set('a', 4); + assert_true(params.has('a'), 'Search params object has name "a"'); + assert_equals(params.get('a'), '4', 'Search params object has name "a" with value "4"'); + assert_equals(params + '', 'a=4&first=4'); +}, 'set() replaces multiple values'); +</script> +</head> +</html> +
diff --git a/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-stringifier-expected.txt b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-stringifier-expected.txt new file mode 100644 index 0000000..397c97b --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-stringifier-expected.txt
@@ -0,0 +1,270 @@ +This is a testharness.js-based test. +PASS Serialize space +PASS Serialize empty value +PASS Serialize empty name +PASS Serialize empty name and value +PASS Serialize + +PASS Serialize = +PASS Serialize & +PASS Serialize U+0000 -> '\0' +PASS Serialize U+0001 -> '' +PASS Serialize U+0002 -> '' +PASS Serialize U+0003 -> '' +PASS Serialize U+0004 -> '' +PASS Serialize U+0005 -> '' +PASS Serialize U+0006 -> '' +PASS Serialize U+0007 -> '' +PASS Serialize U+0008 -> '' +PASS Serialize U+0009 -> ' ' +PASS Serialize U+000A -> ' +' +PASS Serialize U+000B -> '' +PASS Serialize U+000C -> '' +PASS Serialize U+000D -> '\r' +PASS Serialize U+000E -> '' +PASS Serialize U+000F -> '' +PASS Serialize U+0010 -> '' +PASS Serialize U+0011 -> '' +PASS Serialize U+0012 -> '' +PASS Serialize U+0013 -> '' +PASS Serialize U+0014 -> '' +PASS Serialize U+0015 -> '' +PASS Serialize U+0016 -> '' +PASS Serialize U+0017 -> '' +PASS Serialize U+0018 -> '' +PASS Serialize U+0019 -> '' +PASS Serialize U+001A -> '' +PASS Serialize U+001B -> '' +PASS Serialize U+001C -> '' +PASS Serialize U+001D -> '' +PASS Serialize U+001E -> '' +PASS Serialize U+001F -> '' +PASS Serialize U+0020 -> ' ' +FAIL Serialize U+0021 -> '!' assert_equals: expected "33=%21" but got "33=!" +PASS Serialize U+0022 -> '"' +PASS Serialize U+0023 -> '#' +PASS Serialize U+0024 -> '$' +PASS Serialize U+0025 -> '%' +PASS Serialize U+0026 -> '&' +PASS Serialize U+0027 -> ''' +FAIL Serialize U+0028 -> '(' assert_equals: expected "40=%28" but got "40=(" +FAIL Serialize U+0029 -> ')' assert_equals: expected "41=%29" but got "41=)" +PASS Serialize U+002A -> '*' +PASS Serialize U+002B -> '+' +PASS Serialize U+002C -> ',' +PASS Serialize U+002D -> '-' +PASS Serialize U+002E -> '.' +FAIL Serialize U+002F -> '/' assert_equals: expected "47=%2F" but got "47=/" +PASS Serialize U+0030 -> '0' +PASS Serialize U+0031 -> '1' +PASS Serialize U+0032 -> '2' +PASS Serialize U+0033 -> '3' +PASS Serialize U+0034 -> '4' +PASS Serialize U+0035 -> '5' +PASS Serialize U+0036 -> '6' +PASS Serialize U+0037 -> '7' +PASS Serialize U+0038 -> '8' +PASS Serialize U+0039 -> '9' +PASS Serialize U+003A -> ':' +PASS Serialize U+003B -> ';' +PASS Serialize U+003C -> '<' +PASS Serialize U+003D -> '=' +PASS Serialize U+003E -> '>' +PASS Serialize U+003F -> '?' +PASS Serialize U+0040 -> '@' +PASS Serialize U+0041 -> 'A' +PASS Serialize U+0042 -> 'B' +PASS Serialize U+0043 -> 'C' +PASS Serialize U+0044 -> 'D' +PASS Serialize U+0045 -> 'E' +PASS Serialize U+0046 -> 'F' +PASS Serialize U+0047 -> 'G' +PASS Serialize U+0048 -> 'H' +PASS Serialize U+0049 -> 'I' +PASS Serialize U+004A -> 'J' +PASS Serialize U+004B -> 'K' +PASS Serialize U+004C -> 'L' +PASS Serialize U+004D -> 'M' +PASS Serialize U+004E -> 'N' +PASS Serialize U+004F -> 'O' +PASS Serialize U+0050 -> 'P' +PASS Serialize U+0051 -> 'Q' +PASS Serialize U+0052 -> 'R' +PASS Serialize U+0053 -> 'S' +PASS Serialize U+0054 -> 'T' +PASS Serialize U+0055 -> 'U' +PASS Serialize U+0056 -> 'V' +PASS Serialize U+0057 -> 'W' +PASS Serialize U+0058 -> 'X' +PASS Serialize U+0059 -> 'Y' +PASS Serialize U+005A -> 'Z' +PASS Serialize U+005B -> '[' +PASS Serialize U+005C -> '\' +PASS Serialize U+005D -> ']' +PASS Serialize U+005E -> '^' +PASS Serialize U+005F -> '_' +PASS Serialize U+0060 -> '`' +PASS Serialize U+0061 -> 'a' +PASS Serialize U+0062 -> 'b' +PASS Serialize U+0063 -> 'c' +PASS Serialize U+0064 -> 'd' +PASS Serialize U+0065 -> 'e' +PASS Serialize U+0066 -> 'f' +PASS Serialize U+0067 -> 'g' +PASS Serialize U+0068 -> 'h' +PASS Serialize U+0069 -> 'i' +PASS Serialize U+006A -> 'j' +PASS Serialize U+006B -> 'k' +PASS Serialize U+006C -> 'l' +PASS Serialize U+006D -> 'm' +PASS Serialize U+006E -> 'n' +PASS Serialize U+006F -> 'o' +PASS Serialize U+0070 -> 'p' +PASS Serialize U+0071 -> 'q' +PASS Serialize U+0072 -> 'r' +PASS Serialize U+0073 -> 's' +PASS Serialize U+0074 -> 't' +PASS Serialize U+0075 -> 'u' +PASS Serialize U+0076 -> 'v' +PASS Serialize U+0077 -> 'w' +PASS Serialize U+0078 -> 'x' +PASS Serialize U+0079 -> 'y' +PASS Serialize U+007A -> 'z' +PASS Serialize U+007B -> '{' +PASS Serialize U+007C -> '|' +PASS Serialize U+007D -> '}' +FAIL Serialize U+007E -> '~' assert_equals: expected "126=%7E" but got "126=~" +PASS Serialize U+007F -> '' +PASS Serialize U+0080 -> '' +PASS Serialize U+0081 -> '' +PASS Serialize U+0082 -> '' +PASS Serialize U+0083 -> '' +PASS Serialize U+0084 -> '' +PASS Serialize U+0085 -> ' ' +PASS Serialize U+0086 -> '' +PASS Serialize U+0087 -> '' +PASS Serialize U+0088 -> '' +PASS Serialize U+0089 -> '' +PASS Serialize U+008A -> '' +PASS Serialize U+008B -> '' +PASS Serialize U+008C -> '' +PASS Serialize U+008D -> '' +PASS Serialize U+008E -> '' +PASS Serialize U+008F -> '' +PASS Serialize U+0090 -> '' +PASS Serialize U+0091 -> '' +PASS Serialize U+0092 -> '' +PASS Serialize U+0093 -> '' +PASS Serialize U+0094 -> '' +PASS Serialize U+0095 -> '' +PASS Serialize U+0096 -> '' +PASS Serialize U+0097 -> '' +PASS Serialize U+0098 -> '' +PASS Serialize U+0099 -> '' +PASS Serialize U+009A -> '' +PASS Serialize U+009B -> '' +PASS Serialize U+009C -> '' +PASS Serialize U+009D -> '' +PASS Serialize U+009E -> '' +PASS Serialize U+009F -> '' +PASS Serialize U+00A0 -> ' ' +PASS Serialize U+00A1 -> '¡' +PASS Serialize U+00A2 -> '¢' +PASS Serialize U+00A3 -> '£' +PASS Serialize U+00A4 -> '¤' +PASS Serialize U+00A5 -> '¥' +PASS Serialize U+00A6 -> '¦' +PASS Serialize U+00A7 -> '§' +PASS Serialize U+00A8 -> '¨' +PASS Serialize U+00A9 -> '©' +PASS Serialize U+00AA -> 'ª' +PASS Serialize U+00AB -> '«' +PASS Serialize U+00AC -> '¬' +PASS Serialize U+00AD -> '' +PASS Serialize U+00AE -> '®' +PASS Serialize U+00AF -> '¯' +PASS Serialize U+00B0 -> '°' +PASS Serialize U+00B1 -> '±' +PASS Serialize U+00B2 -> '²' +PASS Serialize U+00B3 -> '³' +PASS Serialize U+00B4 -> '´' +PASS Serialize U+00B5 -> 'µ' +PASS Serialize U+00B6 -> '¶' +PASS Serialize U+00B7 -> '·' +PASS Serialize U+00B8 -> '¸' +PASS Serialize U+00B9 -> '¹' +PASS Serialize U+00BA -> 'º' +PASS Serialize U+00BB -> '»' +PASS Serialize U+00BC -> '¼' +PASS Serialize U+00BD -> '½' +PASS Serialize U+00BE -> '¾' +PASS Serialize U+00BF -> '¿' +PASS Serialize U+00C0 -> 'À' +PASS Serialize U+00C1 -> 'Á' +PASS Serialize U+00C2 -> 'Â' +PASS Serialize U+00C3 -> 'Ã' +PASS Serialize U+00C4 -> 'Ä' +PASS Serialize U+00C5 -> 'Å' +PASS Serialize U+00C6 -> 'Æ' +PASS Serialize U+00C7 -> 'Ç' +PASS Serialize U+00C8 -> 'È' +PASS Serialize U+00C9 -> 'É' +PASS Serialize U+00CA -> 'Ê' +PASS Serialize U+00CB -> 'Ë' +PASS Serialize U+00CC -> 'Ì' +PASS Serialize U+00CD -> 'Í' +PASS Serialize U+00CE -> 'Î' +PASS Serialize U+00CF -> 'Ï' +PASS Serialize U+00D0 -> 'Ð' +PASS Serialize U+00D1 -> 'Ñ' +PASS Serialize U+00D2 -> 'Ò' +PASS Serialize U+00D3 -> 'Ó' +PASS Serialize U+00D4 -> 'Ô' +PASS Serialize U+00D5 -> 'Õ' +PASS Serialize U+00D6 -> 'Ö' +PASS Serialize U+00D7 -> '×' +PASS Serialize U+00D8 -> 'Ø' +PASS Serialize U+00D9 -> 'Ù' +PASS Serialize U+00DA -> 'Ú' +PASS Serialize U+00DB -> 'Û' +PASS Serialize U+00DC -> 'Ü' +PASS Serialize U+00DD -> 'Ý' +PASS Serialize U+00DE -> 'Þ' +PASS Serialize U+00DF -> 'ß' +PASS Serialize U+00E0 -> 'à' +PASS Serialize U+00E1 -> 'á' +PASS Serialize U+00E2 -> 'â' +PASS Serialize U+00E3 -> 'ã' +PASS Serialize U+00E4 -> 'ä' +PASS Serialize U+00E5 -> 'å' +PASS Serialize U+00E6 -> 'æ' +PASS Serialize U+00E7 -> 'ç' +PASS Serialize U+00E8 -> 'è' +PASS Serialize U+00E9 -> 'é' +PASS Serialize U+00EA -> 'ê' +PASS Serialize U+00EB -> 'ë' +PASS Serialize U+00EC -> 'ì' +PASS Serialize U+00ED -> 'í' +PASS Serialize U+00EE -> 'î' +PASS Serialize U+00EF -> 'ï' +PASS Serialize U+00F0 -> 'ð' +PASS Serialize U+00F1 -> 'ñ' +PASS Serialize U+00F2 -> 'ò' +PASS Serialize U+00F3 -> 'ó' +PASS Serialize U+00F4 -> 'ô' +PASS Serialize U+00F5 -> 'õ' +PASS Serialize U+00F6 -> 'ö' +PASS Serialize U+00F7 -> '÷' +PASS Serialize U+00F8 -> 'ø' +PASS Serialize U+00F9 -> 'ù' +PASS Serialize U+00FA -> 'ú' +PASS Serialize U+00FB -> 'û' +PASS Serialize U+00FC -> 'ü' +PASS Serialize U+00FD -> 'ý' +PASS Serialize U+00FE -> 'þ' +PASS Serialize % +PASS Serialize \0 +PASS Serialize 💩 +PASS URLSearchParams.toString +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-stringifier.html b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-stringifier.html new file mode 100644 index 0000000..495a1ac3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-stringifier.html
@@ -0,0 +1,146 @@ +<!doctype html> +<html> +<head> +<meta charset="utf8"> +<link rel="help" href="https://url.spec.whatwg.org/#dom-urlsearchparams-set"> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="resources/testharness-extras.js"></script> +<script> +test(function() { + var params = new URLSearchParams(); + params.append('a', 'b c'); + assert_equals(params + '', 'a=b+c'); + params.delete('a'); + params.append('a b', 'c'); + assert_equals(params + '', 'a+b=c'); +}, 'Serialize space'); + +test(function() { + var params = new URLSearchParams(); + params.append('a', ''); + assert_equals(params + '', 'a='); + params.append('a', ''); + assert_equals(params + '', 'a=&a='); + params.append('', 'b'); + assert_equals(params + '', 'a=&a=&=b'); + params.append('', ''); + assert_equals(params + '', 'a=&a=&=b&='); + params.append('', ''); + assert_equals(params + '', 'a=&a=&=b&=&='); +}, 'Serialize empty value'); + +test(function() { + var params = new URLSearchParams(); + params.append('', 'b'); + assert_equals(params + '', '=b'); + params.append('', 'b'); + assert_equals(params + '', '=b&=b'); +}, 'Serialize empty name'); + +test(function() { + var params = new URLSearchParams(); + params.append('', ''); + assert_equals(params + '', '='); + params.append('', ''); + assert_equals(params + '', '=&='); +}, 'Serialize empty name and value'); + +test(function() { + var params = new URLSearchParams(); + params.append('a', 'b+c'); + assert_equals(params + '', 'a=b%2Bc'); + params.delete('a'); + params.append('a+b', 'c'); + assert_equals(params + '', 'a%2Bb=c'); +}, 'Serialize +'); + +test(function() { + var params = new URLSearchParams(); + params.append('=', 'a'); + assert_equals(params + '', '%3D=a'); + params.append('b', '='); + assert_equals(params + '', '%3D=a&b=%3D'); +}, 'Serialize ='); + +test(function() { + var params = new URLSearchParams(); + params.append('&', 'a'); + assert_equals(params + '', '%26=a'); + params.append('b', '&'); + assert_equals(params + '', '%26=a&b=%26'); +}, 'Serialize &'); + +function intToHex(i) { + return (i<0x10 ? '0':'') + i.toString(16).toUpperCase(); +} + +function urlEncodedSerialize(n) { + if (n === 0x20) { + return "\x2B"; + } + + if (n === 0x2A || n === 0x2D || n === 0x2E || + (0x30 <= n && n <= 0x39) || (0x41 <= n && n <= 0x5A) || + n === 0x5F || (0x61 <= n && n <= 0x7A)) { + return String.fromCharCode(n); + } + var bytes = (new TextEncoder()).encode(String.fromCharCode(n)); + var ret = ""; + for (var i = 0; i < bytes.length; i++) { + ret += "%" + intToHex(bytes[i]); + } + return ret; +} + +for (var i = 0x00; i < 0xFF; i++) { + // Not all bytes can appear in valid UTF-8, so some bytes aren't covered. + // TODO(mkwst): We fail to properly encode a few bytes: https://crbug.com/557063 + test(function() { + var params = new URLSearchParams(); + params.append('' + i, String.fromCodePoint(i)); + assert_equals(params + '', '' + i + '=' + urlEncodedSerialize(i)); + }, "Serialize U+00" + intToHex(i) + " -> '" + String.fromCodePoint(i) + "'"); +} + +test(function() { + var params = new URLSearchParams(); + params.append('a', 'b%c'); + assert_equals(params + '', 'a=b%25c'); + params.delete('a'); + params.append('a%b', 'c'); + assert_equals(params + '', 'a%25b=c'); +}, 'Serialize %'); + +test(function() { + var params = new URLSearchParams(); + params.append('a', 'b\0c'); + assert_equals(params + '', 'a=b%00c'); + params.delete('a'); + params.append('a\0b', 'c'); + assert_equals(params + '', 'a%00b=c'); +}, 'Serialize \\0'); + +test(function() { + var params = new URLSearchParams(); + params.append('a', 'b\uD83D\uDCA9c'); + assert_equals(params + '', 'a=b%F0%9F%92%A9c'); + params.delete('a'); + params.append('a\uD83D\uDCA9b', 'c'); + assert_equals(params + '', 'a%F0%9F%92%A9b=c'); +}, 'Serialize \uD83D\uDCA9'); // Unicode Character 'PILE OF POO' (U+1F4A9) + +test(function() { + var params; + params = new URLSearchParams('a=b&c=d&&e&&'); + assert_equals(params.toString(), 'a=b&c=d&e='); + params = new URLSearchParams('a = b &a=b&c=d%20'); + assert_equals(params.toString(), 'a+=+b+&a=b&c=d+'); + // The lone '=' _does_ survive the roundtrip. + params = new URLSearchParams('a=&a=b'); + assert_equals(params.toString(), 'a=&a=b'); +}, 'URLSearchParams.toString'); +</script> +</head> +</html> +
diff --git a/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-worker.html b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-worker.html new file mode 100644 index 0000000..5fb8474 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams-worker.html
@@ -0,0 +1,12 @@ +<!doctype html> +<html> +<head> +<meta charset="utf8"> +<link rel="help" href="https://url.spec.whatwg.org/#interface-urlsearchparams"> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script> +fetch_tests_from_worker(new Worker("./resources/urlsearchparams-worker.js")); +</script> +</head> +</html>
diff --git a/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams.html b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams.html new file mode 100644 index 0000000..80861f51 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/domurl/urlsearchparams.html
@@ -0,0 +1,21 @@ +<!doctype html> +<html> +<head> +<meta charset="utf8"> +<link rel="help" href="https://url.spec.whatwg.org/#interface-urlsearchparams"> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script> +test(function() { + assert_true('URLSearchParams' in window); + assert_true('toString' in URLSearchParams.prototype); + assert_true('append' in URLSearchParams.prototype); + assert_true('delete' in URLSearchParams.prototype); + assert_true('get' in URLSearchParams.prototype); + assert_true('getAll' in URLSearchParams.prototype); + assert_true('has' in URLSearchParams.prototype); + assert_true('set' in URLSearchParams.prototype); +}, 'URLSearchParams interface'); +</script> +</head> +</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/background_sync/interfaces.html b/third_party/WebKit/LayoutTests/http/tests/background_sync/interfaces.html index c5d4e1b2..d183f40 100644 --- a/third_party/WebKit/LayoutTests/http/tests/background_sync/interfaces.html +++ b/third_party/WebKit/LayoutTests/http/tests/background_sync/interfaces.html
@@ -18,23 +18,9 @@ assert_own_property(self, 'SyncManager', 'SyncManager needs to be exposed as a global.'); assert_own_property(SyncManager.prototype, 'register'); - assert_own_property(SyncManager.prototype, 'getRegistration'); - assert_own_property(SyncManager.prototype, 'getRegistrations'); - assert_own_property(SyncManager.prototype, 'permissionState'); + assert_own_property(SyncManager.prototype, 'getTags'); }, 'SyncManager should be exposed and have the expected interface in a Document.'); - - test(function() { - assert_own_property(self, 'SyncRegistration', 'SyncRegistration needs to be exposed as a global.'); - - // FIXME: Assert existence of the attributes when they are properly - // exposed in the prototype chain. https://crbug.com/43394 - - assert_own_property(SyncRegistration.prototype, 'finished'); - assert_own_property(SyncRegistration.prototype, 'unregister'); - assert_own_property(SyncRegistration.prototype, 'tag'); - - }, 'SyncRegistration should be exposed and have the expected interface in a Document.'); </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/background_sync/oneshot-register-failure-worker-not-activated.html b/third_party/WebKit/LayoutTests/http/tests/background_sync/oneshot-register-failure-worker-not-activated.html index 7768008..9b35a5e 100644 --- a/third_party/WebKit/LayoutTests/http/tests/background_sync/oneshot-register-failure-worker-not-activated.html +++ b/third_party/WebKit/LayoutTests/http/tests/background_sync/oneshot-register-failure-worker-not-activated.html
@@ -17,7 +17,7 @@ swRegistration = serviceWorkerRegistration; assert_not_equals(swRegistration.installing, null, 'The worker should be installing'); assert_equals(swRegistration.active, null, 'The worker should not be active yet'); - return swRegistration.sync.register(); + return swRegistration.sync.register('abcde'); }) .then(function(syncRegistration) { assert_unreached('sync.register() must not succeed without an active service worker');
diff --git a/third_party/WebKit/LayoutTests/http/tests/background_sync/oneshot.html b/third_party/WebKit/LayoutTests/http/tests/background_sync/oneshot.html index 87663fa6..e2090b94 100644 --- a/third_party/WebKit/LayoutTests/http/tests/background_sync/oneshot.html +++ b/third_party/WebKit/LayoutTests/http/tests/background_sync/oneshot.html
@@ -6,7 +6,6 @@ <script src="../resources/testharness-helpers.js"></script> <script src="../resources/testharnessreport.js"></script> <script src="../serviceworker/resources/test-helpers.js"></script> -<script src="resources/test-helpers.js"></script> <script> promise_test(function(t) { @@ -15,9 +14,9 @@ var sync_manager; var sync_registration; - // One-shot syncs can only be registered from a controlled document. This - // test creates a frame, after the service worker is active, in order to use - // its service worker registration. + // This test verifies that one-shot syncs can be registered from service- + // worker-controlled documents. It creates a frame, after the service worker + // is active, in order to use its service worker registration. return service_worker_unregister_and_register(t, url, scope) .then(function(sw_registration_page) { return wait_for_state(t, sw_registration_page.installing, 'activated'); @@ -31,21 +30,14 @@ }) .then(function(sw_registration_frame) { sync_manager = sw_registration_frame.sync; - return clear_registered_syncs(sync_manager); + return sync_manager.getTags(); }) - .then(function() { return sync_manager.getRegistrations(); }) - .then(function(registrations) { - assert_equals(registrations.length, 0, 'One-shot syncs should be ' + + .then(function(tags) { + assert_equals(tags.length, 0, 'One-shot syncs should be ' + 'cleared at the start of the test.'); - return sync_manager.register({tag: 'abcde'}); + return sync_manager.register('abcde'); }) - .then(function(registration) { - sync_registration = registration; - assert_class_string(sync_registration, 'SyncRegistration', 'One-' + - 'shot sync registrations should have the correct ' + - 'class name.'); - assert_equals('abcde', registration.tag, 'Sync registration tag ' + - 'returned should match the tag registered.'); + .then(function() { return service_worker_unregister(t, scope); }); }, 'Background Sync API should allow one-shot syncs to be registered from ' + @@ -57,31 +49,22 @@ var sync_manager; var sync_registration; - // One-shot syncs can also be registered from uncontrolled documents. This - // test creates a frame, after the service worker is active, in order to use - // its service worker registration. + // This test verifies that one-shot syncs can be registered from uncontrolled + // documents. return service_worker_unregister_and_register(t, url, scope) .then(function(sw_registration) { sync_manager = sw_registration.sync; return wait_for_state(t, sw_registration.installing, 'activated'); }) - .then(function() { return clear_registered_syncs(sync_manager); }) - .then(function() { return sync_manager.getRegistrations(); }) - .then(function(registrations) { - assert_equals(registrations.length, 0, 'One-shot syncs should be ' + + .then(function() { return sync_manager.getTags(); }) + .then(function(tags) { + assert_equals(tags.length, 0, 'One-shot syncs should be ' + 'cleared at the start of the test.'); - return sync_manager.register({tag: 'abcde'}); + return sync_manager.register('abcde'); }) - .then(function(registration) { - sync_registration = registration; - assert_class_string(sync_registration, 'SyncRegistration', 'One-' + - 'shot sync registrations should have the correct ' + - 'class name.'); - assert_equals('abcde', registration.tag, 'Sync registration tag ' + - 'returned should match the tag registered.'); + .then(function() { return service_worker_unregister(t, scope); }) - .then(function() { return service_worker_unregister(t, scope); }) }, 'Background Sync API should allow one-shot syncs to be registered ' + 'with window clients not currently controlled by service worker'); </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/background_sync/resources/interfaces-worker.js b/third_party/WebKit/LayoutTests/http/tests/background_sync/resources/interfaces-worker.js index c638025c..0df2dca6 100644 --- a/third_party/WebKit/LayoutTests/http/tests/background_sync/resources/interfaces-worker.js +++ b/third_party/WebKit/LayoutTests/http/tests/background_sync/resources/interfaces-worker.js
@@ -6,27 +6,14 @@ assert_idl_attribute(registration, 'sync', 'One-shot SyncManager needs to be exposed on the registration.'); assert_inherits(registration.sync, 'register'); - assert_inherits(registration.sync, 'getRegistration'); - assert_inherits(registration.sync, 'getRegistrations'); - assert_inherits(registration.sync, 'permissionState'); + assert_inherits(registration.sync, 'getTags'); }, 'SyncManager should be exposed and have the expected interface.'); test(function() { - assert_own_property(self, 'SyncRegistration', 'SyncRegistration needs to be exposed as a global.'); - - // FIXME: Assert existence of the attributes when they are properly - // exposed in the prototype chain. https://crbug.com/43394 - assert_own_property(SyncRegistration.prototype, 'finished'); - assert_own_property(SyncRegistration.prototype, 'unregister'); - assert_own_property(SyncRegistration.prototype, 'tag'); - -}, 'SyncRegistration should be exposed and have the expected interface.'); - -test(function() { assert_own_property(self, 'SyncEvent'); - assert_will_be_idl_attribute(SyncEvent.prototype, 'registration'); + assert_will_be_idl_attribute(SyncEvent.prototype, 'tag'); // SyncEvent should be extending ExtendableEvent. assert_inherits(SyncEvent.prototype, 'waitUntil');
diff --git a/third_party/WebKit/LayoutTests/http/tests/background_sync/resources/test-helpers.js b/third_party/WebKit/LayoutTests/http/tests/background_sync/resources/test-helpers.js deleted file mode 100644 index da0b7e9..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/background_sync/resources/test-helpers.js +++ /dev/null
@@ -1,13 +0,0 @@ -// Returns a promise which resolves when all registrations have been cleared -// from the given background sync manager. -function clear_registered_syncs(sync_manager) { - return sync_manager.getRegistrations().then(function(registrations) { - return Promise.all( - registrations.map(registration => registration.unregister())); - }); -} - -// Clears all background sync registrations from the sync manager. -function clear_all_syncs(serviceworker_registration) { - return clear_registered_syncs(serviceworker_registration.sync); -}
diff --git a/third_party/WebKit/LayoutTests/http/tests/misc/script-sync-slow-scripts-onerror-expected.txt b/third_party/WebKit/LayoutTests/http/tests/misc/script-sync-slow-scripts-onerror-expected.txt index 12463f9..4328e54 100644 --- a/third_party/WebKit/LayoutTests/http/tests/misc/script-sync-slow-scripts-onerror-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/misc/script-sync-slow-scripts-onerror-expected.txt
@@ -3,9 +3,8 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". -PASS firstOnErrorHandlerHasRun is false -PASS firstOnErrorHandlerHasRun is true -PASS secondOnErrorHandlerHasRun is false +PASS firstOnErrorHandlerCount is 1 +PASS secondOnErrorHandlerCount is 1 PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/http/tests/misc/script-sync-slow-scripts-onerror.html b/third_party/WebKit/LayoutTests/http/tests/misc/script-sync-slow-scripts-onerror.html index 31138b6..e21084597 100644 --- a/third_party/WebKit/LayoutTests/http/tests/misc/script-sync-slow-scripts-onerror.html +++ b/third_party/WebKit/LayoutTests/http/tests/misc/script-sync-slow-scripts-onerror.html
@@ -25,22 +25,27 @@ testRunner.waitUntilDone(); } -var firstOnErrorHandlerHasRun = false; +var firstOnErrorHandlerCount = 0; +var secondOnErrorHandlerCount = 0; +function verifyAndFinish() { + shouldBe("firstOnErrorHandlerCount", "1"); + shouldBe("secondOnErrorHandlerCount", "1"); + finishJSTest(); +}; + function failedFirst() { - shouldBeFalse("firstOnErrorHandlerHasRun"); - firstOnErrorHandlerHasRun = true; + firstOnErrorHandlerCount++; // Issue another script load so as to have the script runner // revisit its script queue. This should not result in this // onerror handler running again. - loadScript("resources/success.js?1", true); + var continuation = secondOnErrorHandlerCount ? verifyAndFinish : undefined; + loadScript("resources/success.js?1", true, continuation); } -var secondOnErrorHandlerHasRun = false; function failedSecond() { - shouldBeTrue("firstOnErrorHandlerHasRun"); - shouldBeFalse("secondOnErrorHandlerHasRun"); - secondOnErrorHandlerHasRun = true; - loadScript("resources/success.js?2", true, finishJSTest); + secondOnErrorHandlerCount++; + var continuation = firstOnErrorHandlerCount ? verifyAndFinish : undefined; + loadScript("resources/success.js?2", true, continuation); } function unexpectedLoad() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt index bf66956..54605ce 100644 --- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -587,19 +587,12 @@ method wrapKey interface SyncEvent : ExtendableEvent getter lastChance - getter registration + getter tag method constructor interface SyncManager method constructor - method getRegistration - method getRegistrations - method permissionState + method getTags method register -interface SyncRegistration - getter finished - getter tag - method constructor - method unregister interface TextDecoder getter encoding getter fatal @@ -636,6 +629,19 @@ setter protocol setter search setter username +interface URLSearchParams + method append + method constructor + method delete + method entries + method forEach + method get + method getAll + method has + method keys + method set + method toString + method values interface WebSocket : EventTarget attribute CLOSED attribute CLOSING
diff --git a/third_party/WebKit/LayoutTests/inspector/animation/animation-empty-web-animations.html b/third_party/WebKit/LayoutTests/inspector/animation/animation-empty-web-animations.html index 6f00ef8..cc69dd7 100644 --- a/third_party/WebKit/LayoutTests/inspector/animation/animation-empty-web-animations.html +++ b/third_party/WebKit/LayoutTests/inspector/animation/animation-empty-web-animations.html
@@ -15,11 +15,19 @@ function test() { - var timeline = new WebInspector.AnimationTimeline(); - var elementsPanel = WebInspector.ElementsPanel.instance(); - elementsPanel.setWidgetBelowDOM(timeline); - InspectorTest.addSniffer(WebInspector.AnimationModel.prototype, "animationStarted", animationStarted); - InspectorTest.evaluateInPage("startAnimation()"); + InspectorTest.addSniffer(WebInspector.TabbedPane.prototype, "changeTabView", onChangeTabView, true); + WebInspector.inspectorView.showViewInDrawer("animations", true); + var timeline; + + function onChangeTabView(id, view) + { + if (!timeline && id === "animations") { + timeline = view; + InspectorTest.assertTrue(timeline instanceof WebInspector.AnimationTimeline); + InspectorTest.evaluateInPage("startAnimation()"); + InspectorTest.addSniffer(WebInspector.AnimationModel.prototype, "animationStarted", animationStarted); + } + } function animationStarted() {
diff --git a/third_party/WebKit/LayoutTests/inspector/animation/animation-timeline.html b/third_party/WebKit/LayoutTests/inspector/animation/animation-timeline.html index 2c31d4ae..4c86c0ad 100644 --- a/third_party/WebKit/LayoutTests/inspector/animation/animation-timeline.html +++ b/third_party/WebKit/LayoutTests/inspector/animation/animation-timeline.html
@@ -55,20 +55,23 @@ function test() { - InspectorTest.selectNodeWithId("node", step1); - var timeline = new WebInspector.AnimationTimeline(); - var elementsPanel = WebInspector.ElementsPanel.instance(); - elementsPanel.setWidgetBelowDOM(timeline); // Override timeline width for testing WebInspector.AnimationTimeline.prototype.width = function() { return 1000; } // Override animation color for testing // FIXME: Set animation name of Web Animation instead; not supported yet WebInspector.AnimationUI.Color = function() { return "black"; } + var timeline; + InspectorTest.addSniffer(WebInspector.TabbedPane.prototype, "changeTabView", onChangeTabView, true); + WebInspector.inspectorView.showViewInDrawer("animations", true); - function step1() + function onChangeTabView(id, view) { - InspectorTest.waitForAnimationAdded(step2); - InspectorTest.evaluateInPage("startAnimationWithDelay()"); + if (!timeline && id === "animations") { + timeline = view; + InspectorTest.assertTrue(timeline instanceof WebInspector.AnimationTimeline); + InspectorTest.waitForAnimationAdded(step2); + InspectorTest.evaluateInPage("startAnimationWithDelay()"); + } } function step2(group)
diff --git a/third_party/WebKit/LayoutTests/inspector/elements/css-rule-hover-highlights-selectors-expected.txt b/third_party/WebKit/LayoutTests/inspector/elements/css-rule-hover-highlights-selectors-expected.txt new file mode 100644 index 0000000..a72976f --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector/elements/css-rule-hover-highlights-selectors-expected.txt
@@ -0,0 +1,9 @@ + +Running: setupProxyOverlay + +Running: testRegularNodeSelection +Highlights drawn: 4 + +Running: testShadowDOMNodeSelection +Highlights drawn: 6 +
diff --git a/third_party/WebKit/LayoutTests/inspector/elements/css-rule-hover-highlights-selectors.html b/third_party/WebKit/LayoutTests/inspector/elements/css-rule-hover-highlights-selectors.html new file mode 100644 index 0000000..2f65e41 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector/elements/css-rule-hover-highlights-selectors.html
@@ -0,0 +1,138 @@ +<html> +<head> +<script src="../../http/tests/inspector/inspector-test.js"></script> +<script src="../../http/tests/inspector/elements-test.js"></script> +<style> +.border { + border: 1px solid black; +} +</style> +<script> + +function buildShadowDOM() +{ + var host = document.querySelector("body"); + var root = host.createShadowRoot(); + var template = document.querySelector("#dom-template"); + var clone = document.importNode(template.content, true); + root.appendChild(clone); + var second = root.querySelector("#fifth"); + second.id = "inspected-shadow"; + runTest(); +} + +function test() +{ + InspectorTest.runTestSuite([ + function setupProxyOverlay(next) + { + InspectorTest.evaluateFunctionInOverlay(drawHighlightProxy, next); + }, + + function testRegularNodeSelection(next) + { + InspectorTest.selectNodeAndWaitForStyles("inspected", onSelected); + + function onSelected() + { + resetHighlightCount(onHighlightCountReset); + } + + function onHighlightCountReset() + { + var section = InspectorTest.firstMatchedStyleSection(); + section._highlight(); + testRunner.layoutAndPaintAsyncThen(onHighlighted); + } + + function onHighlighted() + { + dumpHighlightCount(next); + } + }, + + function testShadowDOMNodeSelection(next) + { + InspectorTest.selectNodeAndWaitForStyles("inspected-shadow", onSelected); + + function onSelected() + { + resetHighlightCount(onHighlightCountReset); + } + + function onHighlightCountReset() + { + var section = InspectorTest.firstMatchedStyleSection(); + section._highlight(); + testRunner.layoutAndPaintAsyncThen(onHighlighted); + } + + function onHighlighted() + { + dumpHighlightCount(next); + } + }, + ]); + + function drawHighlightProxy() + { + window._highlightsForTest = []; + var oldDrawHighlight = drawHighlight; + drawHighlight = proxy; + + function proxy(highlight, context) + { + window._highlightsForTest.push(highlight); + oldDrawHighlight(highlight, context); + } + } + + function reportHighlights() + { + var result = window._highlightsForTest.length; + window._highlightsForTest = []; + return result + ""; + } + + function dumpHighlightCount(next) + { + InspectorTest.evaluateFunctionInOverlay(reportHighlights, onResults); + + function onResults(count) + { + InspectorTest.addResult("Highlights drawn: " + count); + next(); + } + } + + function resetHighlightCount(next) + { + InspectorTest.evaluateFunctionInOverlay(reportHighlights, next); + } +} + +</script> +</head> + +<body onload="buildShadowDOM()"> +<p> +Tests that long-hovering over StylesSidebar matched rule selector highlights +matching nodes in the page. +</p> +<div class="border">1st</div> +<div id="inspected" class="border">2nd</div> +<div class="border">3rd</div> +<template id="dom-template"> + <style> + .bck { + border: 1px solid black; + } + </style> + <div class="bck">1st</div> + <div class="bck">2nd</div> + <div class="bck">3rd</div> + <div class="bck">4th</div> + <div class="bck" id="fifth">5th</div> +</template> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/svg/custom/baseuri-href-expected.html b/third_party/WebKit/LayoutTests/svg/custom/baseuri-href-expected.html new file mode 100644 index 0000000..75768a0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/svg/custom/baseuri-href-expected.html
@@ -0,0 +1,5 @@ +<!DOCTYPE html> +<svg> + <rect id="rect" width="100" height="100" fill="green"/> +</svg> +
diff --git a/third_party/WebKit/LayoutTests/svg/custom/baseuri-href.html b/third_party/WebKit/LayoutTests/svg/custom/baseuri-href.html new file mode 100644 index 0000000..731a0b0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/svg/custom/baseuri-href.html
@@ -0,0 +1,7 @@ +<!DOCTYPE html> +<base href="/foo"/> +<svg> + <rect id="rect" width="100" height="100" fill="green"/> + <use xlink:href="#rect" x="150"/> +</svg> +
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt index 48d165e3..36dedba4 100644 --- a/third_party/WebKit/LayoutTests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -528,6 +528,19 @@ setter protocol setter search setter username +interface URLSearchParams + method append + method constructor + method delete + method entries + method forEach + method get + method getAll + method has + method keys + method set + method toString + method values interface WebSocket : EventTarget attribute CLOSED attribute CLOSING
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt index 886ce38..bb0e7c2 100644 --- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -514,6 +514,19 @@ [Worker] setter protocol [Worker] setter search [Worker] setter username +[Worker] interface URLSearchParams +[Worker] method append +[Worker] method constructor +[Worker] method delete +[Worker] method entries +[Worker] method forEach +[Worker] method get +[Worker] method getAll +[Worker] method has +[Worker] method keys +[Worker] method set +[Worker] method toString +[Worker] method values [Worker] interface WebSocket : EventTarget [Worker] attribute CLOSED [Worker] attribute CLOSING
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt index ba13e8c..4311a8b 100644 --- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -4750,6 +4750,19 @@ setter protocol setter search setter username +interface URLSearchParams + method append + method constructor + method delete + method entries + method forEach + method get + method getAll + method has + method keys + method set + method toString + method values interface VTTCue : TextTrackCue getter align getter line
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt index 9af80ab..d53d411 100644 --- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -506,6 +506,19 @@ [Worker] setter protocol [Worker] setter search [Worker] setter username +[Worker] interface URLSearchParams +[Worker] method append +[Worker] method constructor +[Worker] method delete +[Worker] method entries +[Worker] method forEach +[Worker] method get +[Worker] method getAll +[Worker] method has +[Worker] method keys +[Worker] method set +[Worker] method toString +[Worker] method values [Worker] interface WebSocket : EventTarget [Worker] attribute CLOSED [Worker] attribute CLOSING
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt index b71358c..843ac62 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -579,6 +579,19 @@ [Worker] setter protocol [Worker] setter search [Worker] setter username +[Worker] interface URLSearchParams +[Worker] method append +[Worker] method constructor +[Worker] method delete +[Worker] method entries +[Worker] method forEach +[Worker] method get +[Worker] method getAll +[Worker] method has +[Worker] method keys +[Worker] method set +[Worker] method toString +[Worker] method values [Worker] interface WebSocket : EventTarget [Worker] attribute CLOSED [Worker] attribute CLOSING
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt index f468c4a4..33088f5 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -5160,15 +5160,8 @@ method wrapKey interface SyncManager method constructor - method getRegistration - method getRegistrations - method permissionState + method getTags method register -interface SyncRegistration - getter finished - getter tag - method constructor - method unregister interface Text : CharacterData getter wholeText method constructor @@ -5347,6 +5340,19 @@ setter protocol setter search setter username +interface URLSearchParams + method append + method constructor + method delete + method entries + method forEach + method get + method getAll + method has + method keys + method set + method toString + method values interface USBAlternateInterface getter alternateSetting getter endpoints
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt index 01ec856..c0d05bc 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -571,6 +571,19 @@ [Worker] setter protocol [Worker] setter search [Worker] setter username +[Worker] interface URLSearchParams +[Worker] method append +[Worker] method constructor +[Worker] method delete +[Worker] method entries +[Worker] method forEach +[Worker] method get +[Worker] method getAll +[Worker] method has +[Worker] method keys +[Worker] method set +[Worker] method toString +[Worker] method values [Worker] interface WebSocket : EventTarget [Worker] attribute CLOSED [Worker] attribute CLOSING
diff --git a/third_party/WebKit/Source/core/core.gypi b/third_party/WebKit/Source/core/core.gypi index 65788117..c1551df6 100644 --- a/third_party/WebKit/Source/core/core.gypi +++ b/third_party/WebKit/Source/core/core.gypi
@@ -96,6 +96,7 @@ 'dom/Uint32Array.idl', 'dom/Uint8Array.idl', 'dom/Uint8ClampedArray.idl', + 'dom/URLSearchParams.idl', 'dom/XMLDocument.idl', 'dom/shadow/ShadowRoot.idl', 'editing/Selection.idl', @@ -2501,6 +2502,8 @@ 'dom/TreeShared.h', 'dom/TreeWalker.cpp', 'dom/TreeWalker.h', + 'dom/URLSearchParams.cpp', + 'dom/URLSearchParams.h', 'dom/UserActionElementSet.cpp', 'dom/UserActionElementSet.h', 'dom/ViewportDescription.cpp',
diff --git a/third_party/WebKit/Source/core/css/CSSCustomFontData.h b/third_party/WebKit/Source/core/css/CSSCustomFontData.h index 3ca52da..227adfcd 100644 --- a/third_party/WebKit/Source/core/css/CSSCustomFontData.h +++ b/third_party/WebKit/Source/core/css/CSSCustomFontData.h
@@ -23,6 +23,7 @@ #include "core/css/CSSFontFaceSource.h" #include "platform/fonts/CustomFontData.h" +#include "platform/heap/Handle.h" namespace blink { @@ -66,11 +67,13 @@ m_isLoading = source->isLoading(); } - RemoteFontFaceSource* m_fontFaceSource; + // TODO(Oilpan): consider moving (Custom)FontFace hierarchy to the heap, + // thereby making this reference a Member<>. + RawPtrWillBeWeakPersistent<RemoteFontFaceSource> m_fontFaceSource; FallbackVisibility m_fallbackVisibility; mutable bool m_isLoading; }; -} +} // namespace blink #endif // CSSCustomFontData_h
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp index c71f7787..05d1644 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp +++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -1775,6 +1775,56 @@ return consumeColor(range, context); } +static PassRefPtrWillBeRawPtr<CSSValue> consumePaintOrder(CSSParserTokenRange& range) +{ + if (range.peek().id() == CSSValueNormal) + return consumeIdent(range); + + Vector<CSSValueID, 3> paintTypeList; + RefPtrWillBeRawPtr<CSSPrimitiveValue> fill = nullptr; + RefPtrWillBeRawPtr<CSSPrimitiveValue> stroke = nullptr; + RefPtrWillBeRawPtr<CSSPrimitiveValue> markers = nullptr; + do { + CSSValueID id = range.peek().id(); + if (id == CSSValueFill && !fill) + fill = consumeIdent(range); + else if (id == CSSValueStroke && !stroke) + stroke = consumeIdent(range); + else if (id == CSSValueMarkers && !markers) + markers = consumeIdent(range); + else + return nullptr; + paintTypeList.append(id); + } while (!range.atEnd()); + + // After parsing we serialize the paint-order list. Since it is not possible to + // pop a last list items from CSSValueList without bigger cost, we create the + // list after parsing. + CSSValueID firstPaintOrderType = paintTypeList.at(0); + RefPtrWillBeRawPtr<CSSValueList> paintOrderList = CSSValueList::createSpaceSeparated(); + switch (firstPaintOrderType) { + case CSSValueFill: + case CSSValueStroke: + paintOrderList->append(firstPaintOrderType == CSSValueFill ? fill.release() : stroke.release()); + if (paintTypeList.size() > 1) { + if (paintTypeList.at(1) == CSSValueMarkers) + paintOrderList->append(markers.release()); + } + break; + case CSSValueMarkers: + paintOrderList->append(markers.release()); + if (paintTypeList.size() > 1) { + if (paintTypeList.at(1) == CSSValueStroke) + paintOrderList->append(stroke.release()); + } + break; + default: + ASSERT_NOT_REACHED(); + } + + return paintOrderList.release(); +} + PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSPropertyID unresolvedProperty) { CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty); @@ -1929,6 +1979,8 @@ case CSSPropertyFill: case CSSPropertyStroke: return consumePaint(m_range, m_context); + case CSSPropertyPaintOrder: + return consumePaintOrder(m_range); default: return nullptr; }
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h index 3afdcd3..ba0aff0 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h +++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h
@@ -199,8 +199,6 @@ bool parseSVGValue(CSSPropertyID propId, bool important); PassRefPtrWillBeRawPtr<CSSValue> parseSVGStrokeDasharray(); - PassRefPtrWillBeRawPtr<CSSValue> parsePaintOrder() const; - // CSS3 Parsing Routines (for properties specific to CSS3) bool parseBorderImageShorthand(CSSPropertyID, bool important); PassRefPtrWillBeRawPtr<CSSValue> parseBorderImage(CSSPropertyID);
diff --git a/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp index 10a9dbd..66060031 100644 --- a/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp +++ b/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp
@@ -1172,6 +1172,7 @@ case CSSPropertyStopColor: case CSSPropertyFloodColor: case CSSPropertyLightingColor: + case CSSPropertyPaintOrder: validPrimitive = false; break; @@ -5501,13 +5502,6 @@ * correctly and allows optimization in applyRule(..) */ - case CSSPropertyPaintOrder: - if (m_valueList->size() == 1 && id == CSSValueNormal) - validPrimitive = true; - else if ((parsedValue = parsePaintOrder())) - m_valueList->next(); - break; - case CSSPropertyStrokeWidth: // <length> | inherit case CSSPropertyStrokeDashoffset: case CSSPropertyCx: @@ -5600,58 +5594,4 @@ return ret.release(); } -// normal | [ fill || stroke || markers ] -PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parsePaintOrder() const -{ - if (m_valueList->size() > 3) - return nullptr; - - CSSParserValue* value = m_valueList->current(); - ASSERT(value); - - Vector<CSSValueID, 3> paintTypeList; - RefPtrWillBeRawPtr<CSSPrimitiveValue> fill = nullptr; - RefPtrWillBeRawPtr<CSSPrimitiveValue> stroke = nullptr; - RefPtrWillBeRawPtr<CSSPrimitiveValue> markers = nullptr; - while (value) { - if (value->id == CSSValueFill && !fill) - fill = CSSPrimitiveValue::createIdentifier(value->id); - else if (value->id == CSSValueStroke && !stroke) - stroke = CSSPrimitiveValue::createIdentifier(value->id); - else if (value->id == CSSValueMarkers && !markers) - markers = CSSPrimitiveValue::createIdentifier(value->id); - else - return nullptr; - paintTypeList.append(value->id); - value = m_valueList->next(); - } - - // After parsing we serialize the paint-order list. Since it is not possible to - // pop a last list items from CSSValueList without bigger cost, we create the - // list after parsing. - CSSValueID firstPaintOrderType = paintTypeList.at(0); - RefPtrWillBeRawPtr<CSSValueList> paintOrderList = CSSValueList::createSpaceSeparated(); - switch (firstPaintOrderType) { - case CSSValueFill: - case CSSValueStroke: - paintOrderList->append(firstPaintOrderType == CSSValueFill ? fill.release() : stroke.release()); - if (paintTypeList.size() > 1) { - if (paintTypeList.at(1) == CSSValueMarkers) - paintOrderList->append(markers.release()); - } - break; - case CSSValueMarkers: - paintOrderList->append(markers.release()); - if (paintTypeList.size() > 1) { - if (paintTypeList.at(1) == CSSValueStroke) - paintOrderList->append(stroke.release()); - } - break; - default: - ASSERT_NOT_REACHED(); - } - - return paintOrderList.release(); -} - } // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/URLSearchParams.cpp b/third_party/WebKit/Source/core/dom/URLSearchParams.cpp new file mode 100644 index 0000000..141aab146 --- /dev/null +++ b/third_party/WebKit/Source/core/dom/URLSearchParams.cpp
@@ -0,0 +1,188 @@ +// Copyright 2015 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 "config.h" +#include "core/dom/URLSearchParams.h" + +#include "platform/weborigin/KURL.h" +#include "wtf/text/StringBuilder.h" +#include "wtf/text/TextEncoding.h" + +namespace blink { + +namespace { + +class URLSearchParamsIterationSource final : public PairIterable<String, String>::IterationSource { +public: + URLSearchParamsIterationSource(Vector<std::pair<String, String>> params) : m_params(params), m_current(0) { } + + bool next(ScriptState*, String& key, String& value, ExceptionState&) override + { + if (m_current >= m_params.size()) + return false; + + key = m_params[m_current].first; + value = m_params[m_current].second; + m_current++; + return true; + } + +private: + Vector<std::pair<String, String>> m_params; + size_t m_current; +}; + +} // namespace + +URLSearchParams* URLSearchParams::create(const URLSearchParamsInit& init) +{ + if (init.isUSVString()) + return new URLSearchParams(init.getAsUSVString()); + if (init.isURLSearchParams()) + return new URLSearchParams(init.getAsURLSearchParams()); + + ASSERT(init.isNull()); + return new URLSearchParams(String()); +} + +URLSearchParams::URLSearchParams(const String& queryString) +{ + if (!queryString.isEmpty()) + setInput(queryString); +} + +URLSearchParams::URLSearchParams(URLSearchParams* searchParams) +{ + ASSERT(searchParams); + m_params = searchParams->m_params; +} + +URLSearchParams::~URLSearchParams() +{ +} + +static String decodeString(String input) +{ + return decodeURLEscapeSequences(input.replace('+', ' ')); +} + +void URLSearchParams::setInput(const String& queryString) +{ + ASSERT(m_params.isEmpty()); + size_t start = 0; + size_t queryStringLength = queryString.length(); + while (start < queryStringLength) { + size_t nameStart = start; + size_t nameValueEnd = queryString.find('&', start); + if (nameValueEnd == kNotFound) + nameValueEnd = queryStringLength; + if (nameValueEnd > start) { + size_t endOfName = queryString.find('=', start); + if (endOfName == kNotFound || endOfName > nameValueEnd) + endOfName = nameValueEnd; + String name = decodeString(queryString.substring(nameStart, endOfName - nameStart)); + String value; + if (endOfName != nameValueEnd) + value = decodeString(queryString.substring(endOfName + 1, nameValueEnd - endOfName - 1)); + if (value.isNull()) + value = ""; + m_params.append(std::make_pair(name, value)); + } + start = nameValueEnd + 1; + } +} +static String encodeString(const String& input) +{ + return encodeWithURLEscapeSequences(input).replace("%20", "+"); +} + +String URLSearchParams::toString() const +{ + StringBuilder result; + for (size_t i = 0; i < m_params.size(); ++i) { + if (i) + result.append('&'); + result.append(encodeString(m_params[i].first)); + result.append('='); + result.append(encodeString(m_params[i].second)); + } + return result.toString(); +} + +void URLSearchParams::append(const String& name, const String& value) +{ + m_params.append(std::make_pair(name, value)); +} + +void URLSearchParams::deleteAllWithName(const String& name) +{ + for (size_t i = 0; i < m_params.size();) { + if (m_params[i].first == name) + m_params.remove(i); + else + i++; + } +} + +String URLSearchParams::get(const String& name) const +{ + for (const auto& param : m_params) { + if (param.first == name) + return param.second; + } + return String(); +} + +Vector<String> URLSearchParams::getAll(const String& name) const +{ + Vector<String> result; + for (const auto& param : m_params) { + if (param.first == name) + result.append(param.second); + } + return result; +} + +bool URLSearchParams::has(const String& name) const +{ + for (const auto& param : m_params) { + if (param.first == name) + return true; + } + return false; +} + +void URLSearchParams::set(const String& name, const String& value) +{ + bool foundMatch = false; + for (size_t i = 0; i < m_params.size();) { + // If there are any name-value whose name is 'name', set + // the value of the first such name-value pair to 'value' + // and remove the others. + if (m_params[i].first == name) { + if (!foundMatch) { + m_params[i++].second = value; + foundMatch = true; + } else { + m_params.remove(i); + } + } else { + i++; + } + } + // Otherwise, append a new name-value pair to the list. + if (!foundMatch) + append(name, value); +} + +DEFINE_TRACE(URLSearchParams) +{ +} + +PairIterable<String, String>::IterationSource* URLSearchParams::startIteration(ScriptState*, ExceptionState&) +{ + return new URLSearchParamsIterationSource(m_params); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/URLSearchParams.h b/third_party/WebKit/Source/core/dom/URLSearchParams.h new file mode 100644 index 0000000..7eb3dfbe --- /dev/null +++ b/third_party/WebKit/Source/core/dom/URLSearchParams.h
@@ -0,0 +1,58 @@ +// Copyright 2015 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 URLSearchParams_h +#define URLSearchParams_h + +#include "bindings/core/v8/Iterable.h" +#include "bindings/core/v8/ScriptWrappable.h" +#include "bindings/core/v8/UnionTypesCore.h" +#include "platform/heap/Handle.h" +#include "wtf/Forward.h" +#include "wtf/text/WTFString.h" +#include <utility> + +namespace blink { + +class ExceptionState; + +typedef USVStringOrURLSearchParams URLSearchParamsInit; + +class CORE_EXPORT URLSearchParams final : public GarbageCollectedFinalized<URLSearchParams>, public ScriptWrappable, public PairIterable<String, String> { + DEFINE_WRAPPERTYPEINFO(); + +public: + // TODO(mkwst): We should support integration with URLUtils, as explored in + // https://codereview.chromium.org/143313002/. That approach is totally + // reasonable, but relies on Node switching to Oilpan. Sigbjorn assures me + // that this will happen Real Soon Now(tm). + static URLSearchParams* create(const URLSearchParamsInit&); + + // TODO(mkwst): ScriptWrappable doesn't have a destructor with Oilpan, so this + // won't need to be virtual once that's the default. + virtual ~URLSearchParams(); + + // URLSearchParams interface methods + String toString() const; + void append(const String& name, const String& value); + void deleteAllWithName(const String&); + String get(const String&) const; + Vector<String> getAll(const String&) const; + bool has(const String&) const; + void set(const String& name, const String& value); + void setInput(const String&); + + DECLARE_TRACE(); + +private: + explicit URLSearchParams(const String&); + explicit URLSearchParams(URLSearchParams*); + Vector<std::pair<String, String>> m_params; + + IterationSource* startIteration(ScriptState*, ExceptionState&) override; +}; + +} // namespace blink + +#endif // URLSearchParams_h
diff --git a/third_party/WebKit/Source/core/dom/URLSearchParams.idl b/third_party/WebKit/Source/core/dom/URLSearchParams.idl new file mode 100644 index 0000000..409542c --- /dev/null +++ b/third_party/WebKit/Source/core/dom/URLSearchParams.idl
@@ -0,0 +1,21 @@ +// Copyright 2015 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. + +// https://url.spec.whatwg.org/#interface-urlsearchparams + +[ + Constructor(optional (USVString or URLSearchParams) init = ""), + GarbageCollected, + Exposed=(Window,Worker) +] interface URLSearchParams { + void append(USVString name, USVString value); + [ImplementedAs=deleteAllWithName] void delete(USVString name); + USVString? get(USVString name); + sequence<USVString> getAll(USVString name); + boolean has(USVString name); + void set(USVString name, USVString value); + + iterable<USVString, USVString>; + stringifier; +};
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.h b/third_party/WebKit/Source/core/frame/UseCounter.h index afc2599..895bda7f 100644 --- a/third_party/WebKit/Source/core/frame/UseCounter.h +++ b/third_party/WebKit/Source/core/frame/UseCounter.h
@@ -884,6 +884,7 @@ CSSFilterContrast = 1022, CSSFilterBlur = 1023, CSSFilterDropShadow = 1024, + BackgroundSyncRegister = 1025, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/WebKit/Source/core/frame/VisualViewport.cpp b/third_party/WebKit/Source/core/frame/VisualViewport.cpp index eb0b002..e213c0895 100644 --- a/third_party/WebKit/Source/core/frame/VisualViewport.cpp +++ b/third_party/WebKit/Source/core/frame/VisualViewport.cpp
@@ -579,7 +579,12 @@ return m_overlayScrollbarVertical.get(); } -void VisualViewport::paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect* inClip) const +IntRect VisualViewport::computeInterestRect(const GraphicsLayer*, const IntRect&) const +{ + return IntRect(); +} + +void VisualViewport::paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect&) const { } @@ -719,7 +724,7 @@ || (constraints.minimumScale == constraints.maximumScale && constraints.minimumScale != -1); } -String VisualViewport::debugName(const GraphicsLayer* graphicsLayer) +String VisualViewport::debugName(const GraphicsLayer* graphicsLayer) const { String name; if (graphicsLayer == m_innerViewportContainerLayer.get()) {
diff --git a/third_party/WebKit/Source/core/frame/VisualViewport.h b/third_party/WebKit/Source/core/frame/VisualViewport.h index 98dbd75..5538abd 100644 --- a/third_party/WebKit/Source/core/frame/VisualViewport.h +++ b/third_party/WebKit/Source/core/frame/VisualViewport.h
@@ -210,8 +210,9 @@ bool visualViewportSuppliesScrollbars() const; // GraphicsLayerClient implementation. - void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect* inClip) const override; - String debugName(const GraphicsLayer*) override; + IntRect computeInterestRect(const GraphicsLayer*, const IntRect&) const; + void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect&) const override; + String debugName(const GraphicsLayer*) const override; void setupScrollbar(WebScrollbar::Orientation); FloatPoint clampOffsetToBoundaries(const FloatPoint&);
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp index b8440dc0..d61ec02 100644 --- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp +++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
@@ -2191,7 +2191,7 @@ // cc::DisplayListRecordingSource::UpdateAndExpandInvalidation() before we keep only one copy of the algorithm. static const int kPixelDistanceToRecord = 4000; -IntRect CompositedLayerMapping::computeInterestRect(const GraphicsLayer* graphicsLayer, LayoutObject* owningLayoutObject) +IntRect CompositedLayerMapping::recomputeInterestRect(const GraphicsLayer* graphicsLayer, LayoutObject* owningLayoutObject) { FloatRect graphicsLayerBounds(FloatPoint(), graphicsLayer->size()); @@ -2256,33 +2256,23 @@ return false; } -void CompositedLayerMapping::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase graphicsLayerPaintingPhase, const IntRect* interestRect) const +IntRect CompositedLayerMapping::computeInterestRect(const GraphicsLayer* graphicsLayer, const IntRect& previousInterestRect) const { - IntRect defaultInterestRect; - if (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled()) { - if (!interestRect) { - if (graphicsLayer == m_graphicsLayer || graphicsLayer == m_squashingLayer) - defaultInterestRect = computeInterestRect(graphicsLayer, m_owningLayer.layoutObject()); - else - defaultInterestRect = enclosingIntRect(FloatRect(FloatPoint(), graphicsLayer->size())); - interestRect = &defaultInterestRect; - } + if (graphicsLayer != m_graphicsLayer && graphicsLayer != m_squashingLayer) + return IntRect(IntPoint(), expandedIntSize(graphicsLayer->size())); - if (!m_owningLayer.needsRepaint() - && !context.paintController().cacheIsEmpty() - && !interestRectChangedEnoughToRepaint(m_previousPaintInterestRect, *interestRect, expandedIntSize(graphicsLayer->size()))) { - context.paintController().createAndAppend<CachedDisplayItem>(*this, DisplayItem::CachedDisplayItemList); - return; - } - - m_previousPaintInterestRect = *interestRect; - } - - ASSERT(interestRect); - paintContentsInternal(graphicsLayer, context, graphicsLayerPaintingPhase, *interestRect); + IntRect newInterestRect = recomputeInterestRect(graphicsLayer, m_owningLayer.layoutObject()); + if (interestRectChangedEnoughToRepaint(previousInterestRect, newInterestRect, expandedIntSize(graphicsLayer->size()))) + return newInterestRect; + return previousInterestRect; } -void CompositedLayerMapping::paintContentsInternal(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase graphicsLayerPaintingPhase, const IntRect& interestRect) const +bool CompositedLayerMapping::needsRepaint() const +{ + return m_owningLayer.needsRepaint(); +} + +void CompositedLayerMapping::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase graphicsLayerPaintingPhase, const IntRect& interestRect) const { // https://code.google.com/p/chromium/issues/detail?id=343772 DisableCompositingQueryAsserts disabler; @@ -2481,7 +2471,7 @@ } } -String CompositedLayerMapping::debugName(const GraphicsLayer* graphicsLayer) +String CompositedLayerMapping::debugName(const GraphicsLayer* graphicsLayer) const { String name; if (graphicsLayer == m_graphicsLayer.get()) {
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h index a479f84d..758b9ca 100644 --- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h +++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h
@@ -154,7 +154,10 @@ void notifyFirstTextPaint() override; void notifyFirstImagePaint() override; - void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect* clip) const override; + IntRect computeInterestRect(const GraphicsLayer*, const IntRect& previousInterestRect) const override; + bool needsRepaint() const override; + void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& interestRect) const override; + bool isTrackingPaintInvalidations() const override; #if ENABLE(ASSERT) @@ -194,7 +197,7 @@ void assertNeedsToUpdateGraphicsLayerBitsCleared() { ASSERT(m_pendingUpdateScope == GraphicsLayerUpdateNone); } #endif - String debugName(const GraphicsLayer*) override; + String debugName(const GraphicsLayer*) const override; LayoutSize contentOffsetInCompositingLayer() const; @@ -212,7 +215,7 @@ String debugName() const { return "CompositedLayerMapping for " + owningLayer().debugName(); } private: - static IntRect computeInterestRect(const GraphicsLayer*, LayoutObject* owningLayoutObject); + static IntRect recomputeInterestRect(const GraphicsLayer*, LayoutObject* owningLayoutObject); static bool interestRectChangedEnoughToRepaint(const IntRect& previousInterestRect, const IntRect& newInterestRect, const IntSize& layerSize); static const GraphicsLayerPaintInfo* containingSquashedLayer(const LayoutObject*, const Vector<GraphicsLayerPaintInfo>& layers, unsigned maxSquashedLayerIndex); @@ -316,8 +319,6 @@ // not appear earlier in the set of layers for this object. bool invalidateLayerIfNoPrecedingEntry(size_t); - void paintContentsInternal(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& interestRect) const; - PaintLayer& m_owningLayer; // The hierarchy of layers that is maintained by the CompositedLayerMapping looks like this: @@ -441,8 +442,6 @@ unsigned m_backgroundLayerPaintsFixedRootBackground : 1; unsigned m_scrollingContentsAreEmpty : 1; - mutable IntRect m_previousPaintInterestRect; - friend class CompositedLayerMappingTest; };
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMappingTest.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMappingTest.cpp index 0490a8a6..57e923cf 100644 --- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMappingTest.cpp +++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMappingTest.cpp
@@ -8,6 +8,7 @@ #include "core/frame/FrameView.h" #include "core/layout/LayoutBoxModelObject.h" #include "core/layout/LayoutTestHelper.h" +#include "core/layout/LayoutView.h" #include "core/paint/PaintLayer.h" #include <gtest/gtest.h> @@ -19,9 +20,9 @@ : m_originalSlimmingPaintSynchronizedPaintingEnabled(RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled()) { } protected: - IntRect computeInterestRect(const GraphicsLayer* graphicsLayer, LayoutObject* owningLayoutObject) + IntRect recomputeInterestRect(const GraphicsLayer* graphicsLayer, LayoutObject* owningLayoutObject) { - return CompositedLayerMapping::computeInterestRect(graphicsLayer, owningLayoutObject); + return CompositedLayerMapping::recomputeInterestRect(graphicsLayer, owningLayoutObject); } bool interestRectChangedEnoughToRepaint(const IntRect& previousInterestRect, const IntRect& newInterestRect, const IntSize& layerSize) @@ -29,6 +30,11 @@ return CompositedLayerMapping::interestRectChangedEnoughToRepaint(previousInterestRect, newInterestRect, layerSize); } + IntRect previousInterestRect(const GraphicsLayer* graphicsLayer) + { + return graphicsLayer->m_previousInterestRect; + } + private: void SetUp() override { @@ -48,22 +54,13 @@ bool m_originalSlimmingPaintSynchronizedPaintingEnabled; }; -static void printRect(IntRect rect) -{ - fprintf(stderr, "[x=%d y=%d maxX=%d maxY=%d]\n", rect.x(), rect.y(), rect.maxX(), rect.maxY()); -} - -static bool checkRectsEqual(const IntRect& expected, const IntRect& actual) -{ - if (expected != actual) { - fprintf(stderr, "Expected: "); - printRect(expected); - fprintf(stderr, "Actual: "); - printRect(actual); - return false; - } - return true; -} +#define EXPECT_RECT_EQ(expected, actual) \ + do { \ + EXPECT_EQ(expected.x(), actual.x()); \ + EXPECT_EQ(expected.y(), actual.y()); \ + EXPECT_EQ(expected.width(), actual.width()); \ + EXPECT_EQ(expected.height(), actual.height()); \ + } while (false) TEST_F(CompositedLayerMappingTest, SimpleInterestRect) { @@ -73,7 +70,7 @@ Element* element = document().getElementById("target"); PaintLayer* paintLayer = toLayoutBoxModelObject(element->layoutObject())->layer(); ASSERT_TRUE(!!paintLayer->graphicsLayerBacking()); - EXPECT_TRUE(checkRectsEqual(IntRect(0, 0, 200, 200), computeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject()))); + EXPECT_RECT_EQ(IntRect(0, 0, 200, 200), recomputeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject())); } TEST_F(CompositedLayerMappingTest, TallLayerInterestRect) @@ -86,7 +83,7 @@ ASSERT_TRUE(paintLayer->graphicsLayerBacking()); // Screen-space visible content rect is [8, 8, 200, 600]. Mapping back to local, adding 4000px in all directions, then // clipping, yields this rect. - EXPECT_TRUE(checkRectsEqual(IntRect(0, 0, 200, 4592), computeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject()))); + EXPECT_RECT_EQ(IntRect(0, 0, 200, 4592), recomputeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject())); } TEST_F(CompositedLayerMappingTest, RotatedInterestRect) @@ -98,7 +95,7 @@ Element* element = document().getElementById("target"); PaintLayer* paintLayer = toLayoutBoxModelObject(element->layoutObject())->layer(); ASSERT_TRUE(!!paintLayer->graphicsLayerBacking()); - EXPECT_TRUE(checkRectsEqual(IntRect(0, 0, 200, 200), computeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject()))); + EXPECT_RECT_EQ(IntRect(0, 0, 200, 200), recomputeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject())); } TEST_F(CompositedLayerMappingTest, 3D90DegRotatedTallInterestRect) @@ -112,7 +109,7 @@ Element* element = document().getElementById("target"); PaintLayer* paintLayer = toLayoutBoxModelObject(element->layoutObject())->layer(); ASSERT_TRUE(!!paintLayer->graphicsLayerBacking()); - EXPECT_TRUE(checkRectsEqual(IntRect(0, 0, 200, 4000), computeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject()))); + EXPECT_RECT_EQ(IntRect(0, 0, 200, 4000), recomputeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject())); } TEST_F(CompositedLayerMappingTest, 3D45DegRotatedTallInterestRect) @@ -124,7 +121,7 @@ Element* element = document().getElementById("target"); PaintLayer* paintLayer = toLayoutBoxModelObject(element->layoutObject())->layer(); ASSERT_TRUE(!!paintLayer->graphicsLayerBacking()); - EXPECT_TRUE(checkRectsEqual(IntRect(0, 0, 200, 4592), computeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject()))); + EXPECT_RECT_EQ(IntRect(0, 0, 200, 4592), recomputeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject())); } TEST_F(CompositedLayerMappingTest, RotatedTallInterestRect) @@ -136,7 +133,7 @@ Element* element = document().getElementById("target"); PaintLayer* paintLayer = toLayoutBoxModelObject(element->layoutObject())->layer(); ASSERT_TRUE(!!paintLayer->graphicsLayerBacking()); - EXPECT_TRUE(checkRectsEqual(IntRect(0, 0, 200, 4000), computeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject()))); + EXPECT_RECT_EQ(IntRect(0, 0, 200, 4000), recomputeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject())); } TEST_F(CompositedLayerMappingTest, WideLayerInterestRect) @@ -149,7 +146,7 @@ ASSERT_TRUE(!!paintLayer->graphicsLayerBacking()); // Screen-space visible content rect is [8, 8, 800, 200] (the screen is 800x600). // Mapping back to local, adding 4000px in all directions, then clipping, yields this rect. - EXPECT_TRUE(checkRectsEqual(IntRect(0, 0, 4792, 200), computeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject()))); + EXPECT_RECT_EQ(IntRect(0, 0, 4792, 200), recomputeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject())); } TEST_F(CompositedLayerMappingTest, FixedPositionInterestRect) @@ -161,7 +158,7 @@ Element* element = document().getElementById("target"); PaintLayer* paintLayer = toLayoutBoxModelObject(element->layoutObject())->layer(); ASSERT_TRUE(!!paintLayer->graphicsLayerBacking()); - EXPECT_TRUE(checkRectsEqual(IntRect(0, 0, 300, 400), computeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject()))); + EXPECT_RECT_EQ(IntRect(0, 0, 300, 400), recomputeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject())); } TEST_F(CompositedLayerMappingTest, LayerOffscreenInterestRect) @@ -175,7 +172,7 @@ PaintLayer* paintLayer = toLayoutBoxModelObject(element->layoutObject())->layer(); ASSERT_TRUE(!!paintLayer->graphicsLayerBacking()); // Offscreen layers are painted as usual. - EXPECT_TRUE(checkRectsEqual(IntRect(0, 0, 200, 200), computeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject()))); + EXPECT_RECT_EQ(IntRect(0, 0, 200, 200), recomputeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject())); } TEST_F(CompositedLayerMappingTest, ScrollingLayerInterestRect) @@ -191,7 +188,7 @@ ASSERT_TRUE(paintLayer->graphicsLayerBacking()); // Offscreen layers are painted as usual. ASSERT_TRUE(paintLayer->compositedLayerMapping()->scrollingLayer()); - EXPECT_TRUE(checkRectsEqual(IntRect(0, 0, 195, 4592), computeInterestRect(paintLayer->graphicsLayerBackingForScrolling(), paintLayer->layoutObject()))); + EXPECT_RECT_EQ(IntRect(0, 0, 195, 4592), recomputeInterestRect(paintLayer->graphicsLayerBackingForScrolling(), paintLayer->layoutObject())); } TEST_F(CompositedLayerMappingTest, ClippedBigLayer) @@ -205,7 +202,7 @@ PaintLayer* paintLayer = toLayoutBoxModelObject(element->layoutObject())->layer(); ASSERT_TRUE(paintLayer->graphicsLayerBacking()); // Offscreen layers are painted as usual. - EXPECT_TRUE(checkRectsEqual(IntRect(0, 0, 4001, 4001), computeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject()))); + EXPECT_RECT_EQ(IntRect(0, 0, 4001, 4001), recomputeInterestRect(paintLayer->graphicsLayerBacking(), paintLayer->layoutObject())); } TEST_F(CompositedLayerMappingTest, ClippingMaskLayer) @@ -306,4 +303,73 @@ EXPECT_TRUE(interestRectChangedEnoughToRepaint(previousInterestRect, newInterestRect, layerSize)); } +TEST_F(CompositedLayerMappingTest, InterestRectChangeOnScroll) +{ + setBodyInnerHTML( + "<style>" + " ::-webkit-scrollbar { width: 0; height: 0; }" + " body { margin: 0; }" + "</style>" + "<div id='div' style='width: 100px; height: 10000px'>Text</div>"); + + document().view()->updateAllLifecyclePhases(); + GraphicsLayer* rootScrollingLayer = document().layoutView()->layer()->graphicsLayerBackingForScrolling(); + EXPECT_RECT_EQ(IntRect(0, 0, 800, 4600), previousInterestRect(rootScrollingLayer)); + + document().view()->setScrollPosition(IntPoint(0, 300), ProgrammaticScroll); + document().view()->updateAllLifecyclePhases(); + // Still use the previous interest rect because the recomputed rect hasn't changed enough. + EXPECT_RECT_EQ(IntRect(0, 0, 800, 4900), recomputeInterestRect(rootScrollingLayer, document().layoutView())); + EXPECT_RECT_EQ(IntRect(0, 0, 800, 4600), previousInterestRect(rootScrollingLayer)); + + document().view()->setScrollPosition(IntPoint(0, 600), ProgrammaticScroll); + document().view()->updateAllLifecyclePhases(); + // Use recomputed interest rect because it changed enough. + EXPECT_RECT_EQ(IntRect(0, 0, 800, 5200), recomputeInterestRect(rootScrollingLayer, document().layoutView())); + EXPECT_RECT_EQ(IntRect(0, 0, 800, 5200), previousInterestRect(rootScrollingLayer)); + + document().view()->setScrollPosition(IntPoint(0, 5400), ProgrammaticScroll); + document().view()->updateAllLifecyclePhases(); + EXPECT_RECT_EQ(IntRect(0, 1400, 800, 8600), recomputeInterestRect(rootScrollingLayer, document().layoutView())); + EXPECT_RECT_EQ(IntRect(0, 1400, 800, 8600), previousInterestRect(rootScrollingLayer)); + + document().view()->setScrollPosition(IntPoint(0, 9000), ProgrammaticScroll); + document().view()->updateAllLifecyclePhases(); + // Still use the previous interest rect because it contains the recomputed interest rect. + EXPECT_RECT_EQ(IntRect(0, 5000, 800, 5000), recomputeInterestRect(rootScrollingLayer, document().layoutView())); + EXPECT_RECT_EQ(IntRect(0, 1400, 800, 8600), previousInterestRect(rootScrollingLayer)); + + document().view()->setScrollPosition(IntPoint(0, 2000), ProgrammaticScroll); + // Use recomputed interest rect because it changed enough. + document().view()->updateAllLifecyclePhases(); + EXPECT_RECT_EQ(IntRect(0, 0, 800, 6600), recomputeInterestRect(rootScrollingLayer, document().layoutView())); + EXPECT_RECT_EQ(IntRect(0, 0, 800, 6600), previousInterestRect(rootScrollingLayer)); +} + +TEST_F(CompositedLayerMappingTest, InterestRectShouldNotChangeOnPaintInvalidation) +{ + setBodyInnerHTML( + "<style>" + " ::-webkit-scrollbar { width: 0; height: 0; }" + " body { margin: 0; }" + "</style>" + "<div id='div' style='width: 100px; height: 10000px'>Text</div>"); + + GraphicsLayer* rootScrollingLayer = document().layoutView()->layer()->graphicsLayerBackingForScrolling(); + + document().view()->setScrollPosition(IntPoint(0, 5400), ProgrammaticScroll); + document().view()->updateAllLifecyclePhases(); + document().view()->setScrollPosition(IntPoint(0, 9400), ProgrammaticScroll); + // The above code creates an interest rect bigger than the interest rect if recomputed now. + document().view()->updateAllLifecyclePhases(); + EXPECT_RECT_EQ(IntRect(0, 5400, 800, 4600), recomputeInterestRect(rootScrollingLayer, document().layoutView())); + EXPECT_RECT_EQ(IntRect(0, 1400, 800, 8600), previousInterestRect(rootScrollingLayer)); + + // Paint invalidation and repaint should not change previous paint interest rect. + document().getElementById("div")->setTextContent("Change"); + document().view()->updateAllLifecyclePhases(); + EXPECT_RECT_EQ(IntRect(0, 5400, 800, 4600), recomputeInterestRect(rootScrollingLayer, document().layoutView())); + EXPECT_RECT_EQ(IntRect(0, 1400, 800, 8600), previousInterestRect(rootScrollingLayer)); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp b/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp index aa46e439..9da2256 100644 --- a/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp +++ b/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp
@@ -800,21 +800,19 @@ scrollbar->paint(&context, CullRect(transformedClip)); } -void PaintLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect* clip) const +IntRect PaintLayerCompositor::computeInterestRect(const GraphicsLayer* graphicsLayer, const IntRect&) const { - IntRect defaultClip; - if (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled() && !clip) { - defaultClip.setSize(m_layoutView.layoutSize(IncludeScrollbars)); - clip = &defaultClip; - } - ASSERT(clip); + return IntRect(IntPoint(), m_layoutView.layoutSize(IncludeScrollbars)); +} +void PaintLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& interestRect) const +{ if (graphicsLayer == layerForHorizontalScrollbar()) - paintScrollbar(m_layoutView.frameView()->horizontalScrollbar(), context, *clip); + paintScrollbar(m_layoutView.frameView()->horizontalScrollbar(), context, interestRect); else if (graphicsLayer == layerForVerticalScrollbar()) - paintScrollbar(m_layoutView.frameView()->verticalScrollbar(), context, *clip); + paintScrollbar(m_layoutView.frameView()->verticalScrollbar(), context, interestRect); else if (graphicsLayer == layerForScrollCorner()) - FramePainter(*m_layoutView.frameView()).paintScrollCorner(&context, *clip); + FramePainter(*m_layoutView.frameView()).paintScrollCorner(&context, interestRect); } bool PaintLayerCompositor::supportsFixedRootBackgroundCompositing() const @@ -1184,7 +1182,7 @@ return m_layoutView.document().lifecycle(); } -String PaintLayerCompositor::debugName(const GraphicsLayer* graphicsLayer) +String PaintLayerCompositor::debugName(const GraphicsLayer* graphicsLayer) const { String name; if (graphicsLayer == m_rootContentLayer.get()) {
diff --git a/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.h b/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.h index f4f7f60..e679e81 100644 --- a/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.h +++ b/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.h
@@ -152,7 +152,7 @@ void resetTrackedPaintInvalidationRects(); void setTracksPaintInvalidations(bool); - String debugName(const GraphicsLayer*) override; + String debugName(const GraphicsLayer*) const override; DocumentLifecycle& lifecycle() const; bool needsUpdateDescendantDependentFlags() const { return m_needsUpdateDescendantDependentFlags; } @@ -177,7 +177,8 @@ #endif // GraphicsLayerClient implementation - void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect*) const override; + IntRect computeInterestRect(const GraphicsLayer*, const IntRect&) const override; + void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& interestRect) const override; bool isTrackingPaintInvalidations() const override;
diff --git a/third_party/WebKit/Source/core/paint/BoxPainter.cpp b/third_party/WebKit/Source/core/paint/BoxPainter.cpp index a4e829f..3b1f0b3 100644 --- a/third_party/WebKit/Source/core/paint/BoxPainter.cpp +++ b/third_party/WebKit/Source/core/paint/BoxPainter.cpp
@@ -671,7 +671,6 @@ else influenceRect.shrinkRadii(-changeAmount); - // TODO: support non-integer shadows - crbug.com/334829 FloatRoundedRect roundedFillRect = border; roundedFillRect.inflate(shadowSpread); @@ -701,8 +700,7 @@ else clippedEdges |= GraphicsContext::BottomEdge; } - // TODO: support non-integer shadows - crbug.com/334828 - context->drawInnerShadow(border, shadowColor, flooredIntSize(shadowOffset), shadowBlur, shadowSpread, clippedEdges); + context->drawInnerShadow(border, shadowColor, shadowOffset, shadowBlur, shadowSpread, clippedEdges); } } }
diff --git a/third_party/WebKit/Source/core/paint/ThemePainterMac.mm b/third_party/WebKit/Source/core/paint/ThemePainterMac.mm index 2c9ae64..681dcf65 100644 --- a/third_party/WebKit/Source/core/paint/ThemePainterMac.mm +++ b/third_party/WebKit/Source/core/paint/ThemePainterMac.mm
@@ -347,10 +347,10 @@ FloatRoundedRect fillRect(fillBounds, fillRadius, fillRadius, fillRadius, fillRadius); paintInfo.context->fillRoundedRect(fillRect, fillColor); - IntSize shadowOffset(isVerticalSlider ? 1 : 0, - isVerticalSlider ? 0 : 1); - int shadowBlur = 3; - int shadowSpread = 0; + FloatSize shadowOffset(isVerticalSlider ? 1 : 0, + isVerticalSlider ? 0 : 1); + float shadowBlur = 3; + float shadowSpread = 0; paintInfo.context->save(); paintInfo.context->drawInnerShadow(fillRect, shadowColor, shadowOffset, shadowBlur, shadowSpread); paintInfo.context->restore();
diff --git a/third_party/WebKit/Source/core/svg/SVGURIReference.h b/third_party/WebKit/Source/core/svg/SVGURIReference.h index 1caa06a..7174a3b 100644 --- a/third_party/WebKit/Source/core/svg/SVGURIReference.h +++ b/third_party/WebKit/Source/core/svg/SVGURIReference.h
@@ -41,10 +41,6 @@ static inline bool isExternalURIReference(const String& uri, const Document& document) { - // Fragment-only URIs are always internal - if (uri.startsWith('#')) - return false; - // If the URI matches our documents URL, we're dealing with a local reference. KURL url = document.completeURL(uri); return !equalIgnoringFragmentIdentifier(url, document.url());
diff --git a/third_party/WebKit/Source/devtools/front_end/animation/AnimationControlPane.js b/third_party/WebKit/Source/devtools/front_end/animation/AnimationControlPane.js index c6b1f76..9b48eca 100644 --- a/third_party/WebKit/Source/devtools/front_end/animation/AnimationControlPane.js +++ b/third_party/WebKit/Source/devtools/front_end/animation/AnimationControlPane.js
@@ -110,18 +110,6 @@ /** * @param {boolean} toggleOn */ - _toggleAnimationTimelineMode: function(toggleOn) - { - if (!this._animationTimeline) - this._animationTimeline = new WebInspector.AnimationTimeline(); - this._button.setToggled(toggleOn); - var elementsPanel = WebInspector.ElementsPanel.instance(); - elementsPanel.setWidgetBelowDOM(toggleOn ? this._animationTimeline : null); - }, - - /** - * @param {boolean} toggleOn - */ _toggleAnimationControlPaneMode: function(toggleOn) { if (!this._animationsControlPane) @@ -132,7 +120,7 @@ _clicked: function() { if (Runtime.experiments.isEnabled("animationInspection")) - this._toggleAnimationTimelineMode(!this._button.toggled()); + WebInspector.inspectorView.showViewInDrawer("animations"); else this._toggleAnimationControlPaneMode(!this._button.toggled()); }, @@ -140,10 +128,7 @@ _nodeChanged: function() { var node = WebInspector.context.flavor(WebInspector.DOMNode); - if (Runtime.experiments.isEnabled("animationInspection")) { - if (this._animationTimeline) - this._animationTimeline.setNode(node); - } else { + if (!Runtime.experiments.isEnabled("animationInspection")) { this._button.setEnabled(!!node); if (!node) this._toggleAnimationControlPaneMode(false);
diff --git a/third_party/WebKit/Source/devtools/front_end/animation/AnimationTimeline.js b/third_party/WebKit/Source/devtools/front_end/animation/AnimationTimeline.js index 8ae7d31..908e853a 100644 --- a/third_party/WebKit/Source/devtools/front_end/animation/AnimationTimeline.js +++ b/third_party/WebKit/Source/devtools/front_end/animation/AnimationTimeline.js
@@ -91,13 +91,10 @@ animationModel.removeEventListener(WebInspector.AnimationModel.Events.AnimationGroupStarted, this._animationGroupStarted, this); }, - /** - * @param {?WebInspector.DOMNode} node - */ - setNode: function(node) + _nodeChanged: function() { for (var nodeUI of this._nodesMap.values()) - nodeUI.setNode(node); + nodeUI._nodeChanged(); }, /** @@ -646,6 +643,7 @@ if (!node) return; this._node = node; + this._nodeChanged(); this._description.appendChild(WebInspector.DOMPresentationUtils.linkifyNodeReference(node)); } @@ -709,12 +707,9 @@ this.element.classList.add("animation-node-removed"); }, - /** - * @param {?WebInspector.DOMNode} node - */ - setNode: function(node) + _nodeChanged: function() { - this.element.classList.toggle("animation-node-selected", node === this._node); + this.element.classList.toggle("animation-node-selected", this._node && this._node === WebInspector.context.flavor(WebInspector.DOMNode)); } }
diff --git a/third_party/WebKit/Source/devtools/front_end/animation/animationTimeline.css b/third_party/WebKit/Source/devtools/front_end/animation/animationTimeline.css index aed052d7..759024e 100644 --- a/third_party/WebKit/Source/devtools/front_end/animation/animationTimeline.css +++ b/third_party/WebKit/Source/devtools/front_end/animation/animationTimeline.css
@@ -4,6 +4,10 @@ * found in the LICENSE file. */ +:host { + overflow: hidden; +} + .animation-node-row { width: 100%; display: flex;
diff --git a/third_party/WebKit/Source/devtools/front_end/animation/module.json b/third_party/WebKit/Source/devtools/front_end/animation/module.json index 0f424268..05f4df2 100644 --- a/third_party/WebKit/Source/devtools/front_end/animation/module.json +++ b/third_party/WebKit/Source/devtools/front_end/animation/module.json
@@ -5,6 +5,14 @@ "className": "WebInspector.AnimationControlPane.ButtonProvider", "order": 2, "location": "styles-sidebarpane-toolbar" + }, + { + "type": "drawer-view", + "name": "animations", + "title": "Animations", + "persistence": "closeable", + "order": 0, + "className": "WebInspector.AnimationTimeline" } ], "dependencies": [
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js b/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js index ea5bb07..647c85d 100644 --- a/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js +++ b/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js
@@ -53,10 +53,7 @@ stackElement.appendChild(this._contentElement); stackElement.appendChild(crumbsContainer); - this._treeOutlineSplit = new WebInspector.SplitWidget(false, true, "treeOutlineAnimationTimelineWidget", 300, 300); - this._treeOutlineSplit.hideSidebar(); - this._treeOutlineSplit.setMainWidget(this._searchableView); - this._splitWidget.setMainWidget(this._treeOutlineSplit); + this._splitWidget.setMainWidget(this._searchableView); this._contentElement.id = "elements-content"; // FIXME: crbug.com/425984 @@ -1057,19 +1054,6 @@ this._extensionSidebarPanesContainer.addPane(pane); }, - /** - * @param {?WebInspector.Widget} widget - */ - setWidgetBelowDOM: function(widget) - { - if (widget) { - this._treeOutlineSplit.setSidebarWidget(widget); - this._treeOutlineSplit.showBoth(true); - } else { - this._treeOutlineSplit.hideSidebar(true); - } - }, - __proto__: WebInspector.Panel.prototype }
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js index 3d05b5a..1d6e0bea 100644 --- a/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js +++ b/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js
@@ -921,7 +921,6 @@ var domModel = node.domModel(); var selectors = this._style.parentRule ? this._style.parentRule.selectorText() : undefined; domModel.highlightDOMNodeWithConfig(node.id, { mode: "all", showInfo: undefined, selectors: selectors }); - this._activeHighlightDOMModel = domModel; }, /**
diff --git a/third_party/WebKit/Source/devtools/front_end/main/Main.js b/third_party/WebKit/Source/devtools/front_end/main/Main.js index a626ceb..6bbcc23 100644 --- a/third_party/WebKit/Source/devtools/front_end/main/Main.js +++ b/third_party/WebKit/Source/devtools/front_end/main/Main.js
@@ -147,6 +147,7 @@ } Runtime.experiments.setDefaultExperiments([ + "animationInspection", "deviceMode", "securityPanel" ]);
diff --git a/third_party/WebKit/Source/modules/background_sync/SyncCallbacks.cpp b/third_party/WebKit/Source/modules/background_sync/SyncCallbacks.cpp index c0cd78e..9f31ab1 100644 --- a/third_party/WebKit/Source/modules/background_sync/SyncCallbacks.cpp +++ b/third_party/WebKit/Source/modules/background_sync/SyncCallbacks.cpp
@@ -120,20 +120,14 @@ void SyncGetRegistrationsCallbacks::onSuccess(const WebVector<WebSyncRegistration*>& webSyncRegistrations) { - Vector<OwnPtr<WebSyncRegistration>> registrations; - for (WebSyncRegistration* r : webSyncRegistrations) { - registrations.append(adoptPtr(r)); - } if (!m_resolver->executionContext() || m_resolver->executionContext()->activeDOMObjectsAreStopped()) { return; } - - HeapVector<Member<SyncRegistration>> syncRegistrations; - for (auto& r : registrations) { - SyncRegistration* reg = SyncRegistration::take(m_resolver.get(), r.release(), m_serviceWorkerRegistration); - syncRegistrations.append(reg); + Vector<String> tags; + for (const WebSyncRegistration* r : webSyncRegistrations) { + tags.append(r->tag); } - m_resolver->resolve(syncRegistrations); + m_resolver->resolve(tags); } void SyncGetRegistrationsCallbacks::onError(const WebSyncError& error)
diff --git a/third_party/WebKit/Source/modules/background_sync/SyncEvent.cpp b/third_party/WebKit/Source/modules/background_sync/SyncEvent.cpp index b109a111..c4f7906 100644 --- a/third_party/WebKit/Source/modules/background_sync/SyncEvent.cpp +++ b/third_party/WebKit/Source/modules/background_sync/SyncEvent.cpp
@@ -11,9 +11,9 @@ { } -SyncEvent::SyncEvent(const AtomicString& type, SyncRegistration* syncRegistration, bool lastChance, WaitUntilObserver* observer) +SyncEvent::SyncEvent(const AtomicString& type, const String& tag, bool lastChance, WaitUntilObserver* observer) : ExtendableEvent(type, ExtendableEventInit(), observer) - , m_syncRegistration(syncRegistration) + , m_tag(tag) , m_lastChance(lastChance) { } @@ -21,7 +21,7 @@ SyncEvent::SyncEvent(const AtomicString& type, const SyncEventInit& init) : ExtendableEvent(type, init) { - m_syncRegistration = init.registration(); + m_tag = init.tag(); m_lastChance = init.lastChance(); } @@ -34,9 +34,9 @@ return EventNames::SyncEvent; } -SyncRegistration* SyncEvent::registration() +String SyncEvent::tag() { - return m_syncRegistration.get(); + return m_tag; } bool SyncEvent::lastChance() @@ -46,7 +46,6 @@ DEFINE_TRACE(SyncEvent) { - visitor->trace(m_syncRegistration); ExtendableEvent::trace(visitor); }
diff --git a/third_party/WebKit/Source/modules/background_sync/SyncEvent.h b/third_party/WebKit/Source/modules/background_sync/SyncEvent.h index d5b8665..5b969a5 100644 --- a/third_party/WebKit/Source/modules/background_sync/SyncEvent.h +++ b/third_party/WebKit/Source/modules/background_sync/SyncEvent.h
@@ -22,9 +22,9 @@ { return adoptRefWillBeNoop(new SyncEvent); } - static PassRefPtrWillBeRawPtr<SyncEvent> create(const AtomicString& type, SyncRegistration* syncRegistration, bool lastChance, WaitUntilObserver* observer) + static PassRefPtrWillBeRawPtr<SyncEvent> create(const AtomicString& type, const String& tag, bool lastChance, WaitUntilObserver* observer) { - return adoptRefWillBeNoop(new SyncEvent(type, syncRegistration, lastChance, observer)); + return adoptRefWillBeNoop(new SyncEvent(type, tag, lastChance, observer)); } static PassRefPtrWillBeRawPtr<SyncEvent> create(const AtomicString& type, const SyncEventInit& init) { @@ -35,17 +35,17 @@ const AtomicString& interfaceName() const override; - SyncRegistration* registration(); + String tag(); bool lastChance(); DECLARE_VIRTUAL_TRACE(); private: SyncEvent(); - SyncEvent(const AtomicString& type, SyncRegistration*, bool, WaitUntilObserver*); + SyncEvent(const AtomicString& type, const String&, bool, WaitUntilObserver*); SyncEvent(const AtomicString& type, const SyncEventInit&); - PersistentWillBeMember<SyncRegistration> m_syncRegistration; + String m_tag; bool m_lastChance; };
diff --git a/third_party/WebKit/Source/modules/background_sync/SyncEvent.idl b/third_party/WebKit/Source/modules/background_sync/SyncEvent.idl index f828e499..f663de05 100644 --- a/third_party/WebKit/Source/modules/background_sync/SyncEvent.idl +++ b/third_party/WebKit/Source/modules/background_sync/SyncEvent.idl
@@ -7,6 +7,6 @@ Exposed=ServiceWorker, RuntimeEnabled=BackgroundSync, ] interface SyncEvent : ExtendableEvent { - readonly attribute SyncRegistration registration; + readonly attribute DOMString tag; readonly attribute boolean lastChance; };
diff --git a/third_party/WebKit/Source/modules/background_sync/SyncEventInit.idl b/third_party/WebKit/Source/modules/background_sync/SyncEventInit.idl index df44f64..1a2a8049 100644 --- a/third_party/WebKit/Source/modules/background_sync/SyncEventInit.idl +++ b/third_party/WebKit/Source/modules/background_sync/SyncEventInit.idl
@@ -3,6 +3,6 @@ // found in the LICENSE file. dictionary SyncEventInit : ExtendableEventInit { - required SyncRegistration registration; - required boolean lastChance; + required DOMString tag; + boolean lastChance = false; };
diff --git a/third_party/WebKit/Source/modules/background_sync/SyncManager.cpp b/third_party/WebKit/Source/modules/background_sync/SyncManager.cpp index dae56c1ee..4593672 100644 --- a/third_party/WebKit/Source/modules/background_sync/SyncManager.cpp +++ b/third_party/WebKit/Source/modules/background_sync/SyncManager.cpp
@@ -40,7 +40,7 @@ ASSERT(registration); } -ScriptPromise SyncManager::registerFunction(ScriptState* scriptState, ExecutionContext* context, const SyncRegistrationOptions& options) +ScriptPromise SyncManager::registerFunction(ScriptState* scriptState, ExecutionContext* context, const String& tag) { // TODO(jkarlin): Wait for the registration to become active instead of rejecting. See crbug.com/542437. if (!m_registration->active()) @@ -52,7 +52,7 @@ WebSyncRegistration* webSyncRegistration = new WebSyncRegistration( WebSyncRegistration::UNREGISTERED_SYNC_ID /* id */, WebSyncRegistration::PeriodicityOneShot, - options.tag(), + tag, 0 /* minPeriod */, WebSyncRegistration::NetworkStateOnline /* networkState */, WebSyncRegistration::PowerStateAuto /* powerState */ @@ -62,17 +62,7 @@ return promise; } -ScriptPromise SyncManager::getRegistration(ScriptState* scriptState, const String& syncRegistrationId) -{ - ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); - ScriptPromise promise = resolver->promise(); - - backgroundSyncProvider()->getRegistration(WebSyncRegistration::PeriodicityOneShot, syncRegistrationId, m_registration->webRegistration(), new SyncRegistrationCallbacks(resolver, m_registration)); - - return promise; -} - -ScriptPromise SyncManager::getRegistrations(ScriptState* scriptState) +ScriptPromise SyncManager::getTags(ScriptState* scriptState) { ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); @@ -82,16 +72,6 @@ return promise; } -ScriptPromise SyncManager::permissionState(ScriptState* scriptState) -{ - ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); - ScriptPromise promise = resolver->promise(); - - backgroundSyncProvider()->getPermissionStatus(WebSyncRegistration::PeriodicityOneShot, m_registration->webRegistration(), new SyncGetPermissionStatusCallbacks(resolver, m_registration)); - - return promise; -} - DEFINE_TRACE(SyncManager) { visitor->trace(m_registration);
diff --git a/third_party/WebKit/Source/modules/background_sync/SyncManager.h b/third_party/WebKit/Source/modules/background_sync/SyncManager.h index 8690788f..2529574 100644 --- a/third_party/WebKit/Source/modules/background_sync/SyncManager.h +++ b/third_party/WebKit/Source/modules/background_sync/SyncManager.h
@@ -27,10 +27,8 @@ unsigned long minAllowablePeriod(); - ScriptPromise registerFunction(ScriptState*, ExecutionContext*, const SyncRegistrationOptions&); - ScriptPromise getRegistration(ScriptState*, const String&); - ScriptPromise getRegistrations(ScriptState*); - ScriptPromise permissionState(ScriptState*); + ScriptPromise registerFunction(ScriptState*, ExecutionContext*, const String&); + ScriptPromise getTags(ScriptState*); DECLARE_TRACE();
diff --git a/third_party/WebKit/Source/modules/background_sync/SyncManager.idl b/third_party/WebKit/Source/modules/background_sync/SyncManager.idl index 30f3ada..de186a1 100644 --- a/third_party/WebKit/Source/modules/background_sync/SyncManager.idl +++ b/third_party/WebKit/Source/modules/background_sync/SyncManager.idl
@@ -14,8 +14,6 @@ RuntimeEnabled=BackgroundSync, TypeChecking=Interface, ] interface SyncManager { - [CallWith=(ScriptState,ExecutionContext),ImplementedAs=registerFunction] Promise<SyncRegistration> register([RuntimeEnabled=BackgroundSyncV2] optional SyncRegistrationOptions options); - [CallWith=ScriptState] Promise<SyncRegistration> getRegistration(DOMString tag); - [CallWith=ScriptState] Promise<sequence<SyncRegistration>> getRegistrations(); - [RuntimeEnabled=BackgroundSyncV2, CallWith=ScriptState] Promise<SyncPermissionState> permissionState(); + [MeasureAs=BackgroundSyncRegister,CallWith=(ScriptState,ExecutionContext),ImplementedAs=registerFunction] Promise<void> register(DOMString tag); + [CallWith=ScriptState] Promise<sequence<DOMString>> getTags(); };
diff --git a/third_party/WebKit/Source/modules/background_sync/SyncRegistration.idl b/third_party/WebKit/Source/modules/background_sync/SyncRegistration.idl index add356ea..ccc69db8 100644 --- a/third_party/WebKit/Source/modules/background_sync/SyncRegistration.idl +++ b/third_party/WebKit/Source/modules/background_sync/SyncRegistration.idl
@@ -3,8 +3,8 @@ // found in the LICENSE file. [ - Exposed=(Window,ServiceWorker), GarbageCollected, + NoInterfaceObject, RuntimeEnabled=BackgroundSync, ] interface SyncRegistration { readonly attribute DOMString tag;
diff --git a/third_party/WebKit/Source/platform/fonts/Character.cpp b/third_party/WebKit/Source/platform/fonts/Character.cpp index ea33001a..5ea155b 100644 --- a/third_party/WebKit/Source/platform/fonts/Character.cpp +++ b/third_party/WebKit/Source/platform/fonts/Character.cpp
@@ -148,6 +148,14 @@ if (supplementaryCharacter <= 0x1F1FF) return ComplexPath; + // Man and Woman Emojies, + // in order to support emoji joiner combinations for family and couple pictographs. + // Compare http://unicode.org/reports/tr51/#Emoji_ZWJ_Sequences + if (supplementaryCharacter < 0x1F468) + continue; + if (supplementaryCharacter <= 0x1F469) + return ComplexPath; + if (supplementaryCharacter < 0xE0100) // U+E0100 through U+E01EF Unicode variation selectors. continue; if (supplementaryCharacter <= 0xE01EF)
diff --git a/third_party/WebKit/Source/platform/fonts/Character.h b/third_party/WebKit/Source/platform/fonts/Character.h index bb6ef77c..f14fa08 100644 --- a/third_party/WebKit/Source/platform/fonts/Character.h +++ b/third_party/WebKit/Source/platform/fonts/Character.h
@@ -93,6 +93,11 @@ } static bool canReceiveTextEmphasis(UChar32); + static bool isModifier(UChar32 c) + { + return c >= 0x1F3FB && c <= 0x1F3FF; + } + static inline UChar normalizeSpaces(UChar character) { if (treatAsSpace(character))
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp index 0678568..3934ccb 100644 --- a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp +++ b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp
@@ -107,6 +107,8 @@ character = spaceCharacter; else if (Character::treatAsZeroWidthSpaceInComplexScript(character)) character = zeroWidthSpaceCharacter; + else if (Character::isModifier(character)) + character = zeroWidthSpaceCharacter; U16_APPEND(destination, *destinationLength, length, character, error); ASSERT_UNUSED(error, !error);
diff --git a/third_party/WebKit/Source/platform/graphics/ContentLayerDelegate.h b/third_party/WebKit/Source/platform/graphics/ContentLayerDelegate.h index 6403762..e07ce0d 100644 --- a/third_party/WebKit/Source/platform/graphics/ContentLayerDelegate.h +++ b/third_party/WebKit/Source/platform/graphics/ContentLayerDelegate.h
@@ -41,7 +41,7 @@ class PLATFORM_EXPORT GraphicsContextPainter { public: - virtual void paint(GraphicsContext&, const IntRect* clip) = 0; + virtual void paint(GraphicsContext&, const IntRect* interestRect) = 0; virtual PaintController* paintController() = 0; protected:
diff --git a/third_party/WebKit/Source/platform/graphics/DrawLooperBuilder.cpp b/third_party/WebKit/Source/platform/graphics/DrawLooperBuilder.cpp index fc1c648..7c16dc9a 100644 --- a/third_party/WebKit/Source/platform/graphics/DrawLooperBuilder.cpp +++ b/third_party/WebKit/Source/platform/graphics/DrawLooperBuilder.cpp
@@ -67,9 +67,7 @@ void DrawLooperBuilder::addShadow(const FloatSize& offset, float blur, const Color& color, ShadowTransformMode shadowTransformMode, ShadowAlphaMode shadowAlphaMode) { - // Negative blurs are not allowed, so just pin the value to 0 - if (blur < 0) - blur = 0; + ASSERT(blur >= 0); // Detect when there's no effective shadow. if (!color.alpha())
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp index 18eb9a03..ec3f157 100644 --- a/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp +++ b/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp
@@ -31,6 +31,7 @@ #include "platform/geometry/IntRect.h" #include "platform/graphics/ColorSpace.h" #include "platform/graphics/Gradient.h" +#include "platform/graphics/GraphicsContextStateSaver.h" #include "platform/graphics/ImageBuffer.h" #include "platform/graphics/paint/PaintController.h" #include "platform/weborigin/KURL.h" @@ -412,21 +413,23 @@ } } -static inline FloatRect areaCastingShadowInHole(const FloatRect& holeRect, int shadowBlur, int shadowSpread, const IntSize& shadowOffset) +static inline FloatRect areaCastingShadowInHole(const FloatRect& holeRect, float shadowBlur, + float shadowSpread, const FloatSize& shadowOffset) { - IntRect bounds(holeRect); + FloatRect bounds(holeRect); bounds.inflate(shadowBlur); if (shadowSpread < 0) bounds.inflate(-shadowSpread); - IntRect offsetBounds = bounds; + FloatRect offsetBounds = bounds; offsetBounds.move(-shadowOffset); return unionRect(bounds, offsetBounds); } -void GraphicsContext::drawInnerShadow(const FloatRoundedRect& rect, const Color& shadowColor, const IntSize shadowOffset, int shadowBlur, int shadowSpread, Edges clippedEdges) +void GraphicsContext::drawInnerShadow(const FloatRoundedRect& rect, const Color& shadowColor, + const FloatSize& shadowOffset, float shadowBlur, float shadowSpread, Edges clippedEdges) { if (contextDisabled()) return; @@ -440,24 +443,24 @@ } if (clippedEdges & LeftEdge) { - holeRect.move(-std::max(shadowOffset.width(), 0) - shadowBlur, 0); - holeRect.setWidth(holeRect.width() + std::max(shadowOffset.width(), 0) + shadowBlur); + holeRect.move(-std::max(shadowOffset.width(), 0.0f) - shadowBlur, 0); + holeRect.setWidth(holeRect.width() + std::max(shadowOffset.width(), 0.0f) + shadowBlur); } if (clippedEdges & TopEdge) { - holeRect.move(0, -std::max(shadowOffset.height(), 0) - shadowBlur); - holeRect.setHeight(holeRect.height() + std::max(shadowOffset.height(), 0) + shadowBlur); + holeRect.move(0, -std::max(shadowOffset.height(), 0.0f) - shadowBlur); + holeRect.setHeight(holeRect.height() + std::max(shadowOffset.height(), 0.0f) + shadowBlur); } if (clippedEdges & RightEdge) - holeRect.setWidth(holeRect.width() - std::min(shadowOffset.width(), 0) + shadowBlur); + holeRect.setWidth(holeRect.width() - std::min(shadowOffset.width(), 0.0f) + shadowBlur); if (clippedEdges & BottomEdge) - holeRect.setHeight(holeRect.height() - std::min(shadowOffset.height(), 0) + shadowBlur); + holeRect.setHeight(holeRect.height() - std::min(shadowOffset.height(), 0.0f) + shadowBlur); Color fillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), 255); FloatRect outerRect = areaCastingShadowInHole(rect.rect(), shadowBlur, shadowSpread, shadowOffset); FloatRoundedRect roundedHole(holeRect, rect.radii()); - save(); + GraphicsContextStateSaver stateSaver(*this); if (rect.isRounded()) { clipRoundedRect(rect); if (shadowSpread < 0) @@ -473,8 +476,6 @@ DrawLooperBuilder::ShadowRespectsTransforms, DrawLooperBuilder::ShadowIgnoresAlpha); setDrawLooper(drawLooperBuilder.release()); fillRectWithRoundedHole(outerRect, roundedHole, fillColor); - restore(); - clearDrawLooper(); } void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsContext.h b/third_party/WebKit/Source/platform/graphics/GraphicsContext.h index be487e63..c700e6d 100644 --- a/third_party/WebKit/Source/platform/graphics/GraphicsContext.h +++ b/third_party/WebKit/Source/platform/graphics/GraphicsContext.h
@@ -231,7 +231,9 @@ LeftEdge = 1 << 4 }; typedef unsigned Edges; - void drawInnerShadow(const FloatRoundedRect&, const Color& shadowColor, const IntSize shadowOffset, int shadowBlur, int shadowSpread, Edges clippedEdges = NoEdge); + void drawInnerShadow(const FloatRoundedRect&, const Color& shadowColor, + const FloatSize& shadowOffset, float shadowBlur, float shadowSpread, + Edges clippedEdges = NoEdge); const SkPaint& fillPaint() const { return immutableState()->fillPaint(); }
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp index 4d51cb8a..6dadd470 100644 --- a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp +++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
@@ -293,9 +293,9 @@ setNeedsDisplay(); } -void GraphicsLayer::paint(GraphicsContext& context, const IntRect* clip) +void GraphicsLayer::paint(GraphicsContext& context, const IntRect* interestRect) { - ASSERT(clip || RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled()); + ASSERT(interestRect || RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled()); ASSERT(drawsContent()); if (!m_client) @@ -312,8 +312,22 @@ } } #endif - m_client->paintContents(this, context, m_paintingPhase, clip); + + IntRect newInterestRect; + if (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled()) { + if (!interestRect) { + newInterestRect = m_client->computeInterestRect(this, m_previousInterestRect); + interestRect = &newInterestRect; + } + if (!m_client->needsRepaint() && !paintController()->cacheIsEmpty() && m_previousInterestRect == *interestRect) { + paintController()->createAndAppend<CachedDisplayItem>(*this, DisplayItem::CachedDisplayItemList); + return; + } + } + + m_client->paintContents(this, context, m_paintingPhase, *interestRect); notifyFirstPaintToClient(); + m_previousInterestRect = *interestRect; } void GraphicsLayer::notifyFirstPaintToClient()
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h index 48105ff..6e58663 100644 --- a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h +++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
@@ -246,7 +246,7 @@ static void unregisterContentsLayer(WebLayer*); // GraphicsContextPainter implementation. - void paint(GraphicsContext&, const IntRect* clip) override; + void paint(GraphicsContext&, const IntRect* interestRect) override; // WebCompositorAnimationDelegate implementation. void notifyAnimationStarted(double monotonicTime, int group) override; @@ -263,10 +263,8 @@ static void setDrawDebugRedFillForTesting(bool); ContentLayerDelegate* contentLayerDelegateForTesting() const { return m_contentLayerDelegate.get(); } -#ifndef NDEBUG DisplayItemClient displayItemClient() const { return toDisplayItemClient(this); } - String debugName() const { return m_client->debugName(this) + " debug red fill"; } -#endif + String debugName() const { return m_client->debugName(this); } protected: String debugName(WebLayer*) const; @@ -275,6 +273,7 @@ // GraphicsLayerFactoryChromium that wants to create a GraphicsLayer need to be friends. friend class GraphicsLayerFactoryChromium; // for testing + friend class CompositedLayerMappingTest; friend class FakeGraphicsLayerFactory; private: @@ -374,6 +373,8 @@ int m_3dRenderingContext; OwnPtr<PaintController> m_paintController; + + IntRect m_previousInterestRect; }; } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayerClient.h b/third_party/WebKit/Source/platform/graphics/GraphicsLayerClient.h index e2406d5..6959096b3 100644 --- a/third_party/WebKit/Source/platform/graphics/GraphicsLayerClient.h +++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayerClient.h
@@ -69,10 +69,13 @@ virtual void notifyFirstTextPaint() { } virtual void notifyFirstImagePaint() { } - virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect* inClip) const = 0; + virtual IntRect computeInterestRect(const GraphicsLayer*, const IntRect& previousInterestRect) const = 0; + virtual bool needsRepaint() const { return true; } + virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& interestRect) const = 0; + virtual bool isTrackingPaintInvalidations() const { return false; } - virtual String debugName(const GraphicsLayer*) = 0; + virtual String debugName(const GraphicsLayer*) const = 0; #if ENABLE(ASSERT) // CompositedLayerMapping overrides this to verify that it is not
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp index 756bf7d0..8123bc2c 100644 --- a/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp
@@ -49,8 +49,9 @@ class MockGraphicsLayerClient : public GraphicsLayerClient { public: - void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect* inClip) const override { } - String debugName(const GraphicsLayer*) override { return String(); } + IntRect computeInterestRect(const GraphicsLayer*, const IntRect&) const { return IntRect(); } + void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect&) const override { } + String debugName(const GraphicsLayer*) const override { return String(); } }; class GraphicsLayerForTesting : public GraphicsLayer {
diff --git a/third_party/WebKit/Source/platform/graphics/ImageLayerChromiumTest.cpp b/third_party/WebKit/Source/platform/graphics/ImageLayerChromiumTest.cpp index f742a96..61f05d9a 100644 --- a/third_party/WebKit/Source/platform/graphics/ImageLayerChromiumTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/ImageLayerChromiumTest.cpp
@@ -37,9 +37,9 @@ class MockGraphicsLayerClient : public GraphicsLayerClient { public: - void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect*) const override { } - - String debugName(const GraphicsLayer*) override { return String(); } + IntRect computeInterestRect(const GraphicsLayer*, const IntRect&) const { return IntRect(); } + void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect&) const override { } + String debugName(const GraphicsLayer*) const override { return String(); } }; class TestImage : public Image {
diff --git a/third_party/WebKit/Source/web/InspectorOverlay.cpp b/third_party/WebKit/Source/web/InspectorOverlay.cpp index 5d9c444..6aac655 100644 --- a/third_party/WebKit/Source/web/InspectorOverlay.cpp +++ b/third_party/WebKit/Source/web/InspectorOverlay.cpp
@@ -411,8 +411,11 @@ String selectors = m_nodeHighlightConfig.selectorList; RefPtrWillBeRawPtr<StaticElementList> elements = nullptr; TrackExceptionState exceptionState; + ContainerNode* queryBase = m_highlightNode->containingShadowRoot(); + if (!queryBase) + queryBase = m_highlightNode->ownerDocument(); if (selectors.length()) - elements = m_highlightNode->ownerDocument()->querySelectorAll(AtomicString(selectors), exceptionState); + elements = queryBase->querySelectorAll(AtomicString(selectors), exceptionState); if (elements && !exceptionState.hadException()) { for (unsigned i = 0; i < elements->length(); ++i) { Element* element = elements->item(i);
diff --git a/third_party/WebKit/Source/web/PageOverlay.cpp b/third_party/WebKit/Source/web/PageOverlay.cpp index 86ae847..cf837ab 100644 --- a/third_party/WebKit/Source/web/PageOverlay.cpp +++ b/third_party/WebKit/Source/web/PageOverlay.cpp
@@ -96,13 +96,18 @@ m_layer->setNeedsDisplay(); } -void PageOverlay::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& gc, GraphicsLayerPaintingPhase phase, const IntRect* inClip) const +IntRect PageOverlay::computeInterestRect(const GraphicsLayer* graphicsLayer, const IntRect&) const { - ASSERT(m_layer); - m_delegate->paintPageOverlay(*this, gc, expandedIntSize(m_layer->size())); + return IntRect(IntPoint(), expandedIntSize(m_layer->size())); } -String PageOverlay::debugName(const GraphicsLayer*) +void PageOverlay::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& gc, GraphicsLayerPaintingPhase phase, const IntRect& interestRect) const +{ + ASSERT(m_layer); + m_delegate->paintPageOverlay(*this, gc, interestRect.size()); +} + +String PageOverlay::debugName(const GraphicsLayer*) const { return "WebViewImpl Page Overlay Content Layer"; }
diff --git a/third_party/WebKit/Source/web/PageOverlay.h b/third_party/WebKit/Source/web/PageOverlay.h index 305fe2d..87f772f 100644 --- a/third_party/WebKit/Source/web/PageOverlay.h +++ b/third_party/WebKit/Source/web/PageOverlay.h
@@ -69,8 +69,9 @@ String debugName() const { return "PageOverlay"; } // GraphicsLayerClient implementation - void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect* inClip) const override; - String debugName(const GraphicsLayer*) override; + IntRect computeInterestRect(const GraphicsLayer*, const IntRect&) const override; + void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& interestRect) const override; + String debugName(const GraphicsLayer*) const override; private: PageOverlay(WebViewImpl*, PageOverlay::Delegate*);
diff --git a/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.cpp b/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.cpp index 3a311b1..fbf8875a 100644 --- a/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.cpp +++ b/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.cpp
@@ -61,6 +61,7 @@ #include "modules/serviceworkers/WaitUntilObserver.h" #include "platform/RuntimeEnabledFeatures.h" #include "public/platform/WebCrossOriginServiceWorkerClient.h" +#include "public/platform/modules/background_sync/WebSyncRegistration.h" #include "public/platform/modules/notifications/WebNotificationData.h" #include "public/platform/modules/serviceworker/WebServiceWorkerEventResult.h" #include "public/platform/modules/serviceworker/WebServiceWorkerRequest.h" @@ -177,7 +178,7 @@ return; } WaitUntilObserver* observer = WaitUntilObserver::create(m_workerGlobalScope, WaitUntilObserver::Sync, eventID); - RefPtrWillBeRawPtr<Event> event(SyncEvent::create(EventTypeNames::sync, SyncRegistration::create(registration, m_workerGlobalScope->registration()), lastChance == IsLastChance, observer)); + RefPtrWillBeRawPtr<Event> event(SyncEvent::create(EventTypeNames::sync, registration.tag, lastChance == IsLastChance, observer)); m_workerGlobalScope->dispatchExtendableEvent(event.release(), observer); }
diff --git a/third_party/WebKit/Source/web/WebDOMResourceProgressEvent.cpp b/third_party/WebKit/Source/web/WebDOMResourceProgressEvent.cpp deleted file mode 100644 index 6720fae..0000000 --- a/third_party/WebKit/Source/web/WebDOMResourceProgressEvent.cpp +++ /dev/null
@@ -1,45 +0,0 @@ -/* - * Copyright (C) 2013 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "public/web/WebDOMResourceProgressEvent.h" - -#include "core/events/ResourceProgressEvent.h" -#include "public/platform/WebString.h" - -namespace blink { - -WebDOMResourceProgressEvent::WebDOMResourceProgressEvent(const WebString& type, bool lengthIsComputable, unsigned long long loaded, unsigned long long total, const WebString& url) - : WebDOMProgressEvent() -{ - assign(ResourceProgressEvent::create(type, lengthIsComputable, loaded, total, url)); -} - -} // namespace blink
diff --git a/third_party/WebKit/Source/web/WebElement.cpp b/third_party/WebKit/Source/web/WebElement.cpp index 6888f61..0fada19a 100644 --- a/third_party/WebKit/Source/web/WebElement.cpp +++ b/third_party/WebKit/Source/web/WebElement.cpp
@@ -94,14 +94,6 @@ return constUnwrap<Element>()->hasAttribute(attrName); } -void WebElement::removeAttribute(const WebString& attrName) -{ - // TODO: Custom element callbacks need to be called on WebKit API methods that - // mutate the DOM in any way. - CustomElementProcessingStack::CallbackDeliveryScope deliverCustomElementCallbacks; - unwrap<Element>()->removeAttribute(attrName); -} - WebString WebElement::getAttribute(const WebString& attrName) const { return constUnwrap<Element>()->getAttribute(attrName);
diff --git a/third_party/WebKit/Source/web/WebImageCache.cpp b/third_party/WebKit/Source/web/WebImageCache.cpp index 8648b1e2..0e22c37 100644 --- a/third_party/WebKit/Source/web/WebImageCache.cpp +++ b/third_party/WebKit/Source/web/WebImageCache.cpp
@@ -35,24 +35,9 @@ namespace blink { -void WebImageCache::setCacheLimitInBytes(size_t size) -{ - ImageDecodingStore::instance().setCacheLimitInBytes(size); -} - void WebImageCache::clear() { ImageDecodingStore::instance().clear(); } -size_t WebImageCache::memoryUsageInBytes() -{ - return ImageDecodingStore::instance().memoryUsageInBytes(); -} - -unsigned WebImageCache::cacheEntries() -{ - return ImageDecodingStore::instance().cacheEntries(); -} - } // namespace blink
diff --git a/third_party/WebKit/Source/web/WebOptionElement.cpp b/third_party/WebKit/Source/web/WebOptionElement.cpp index e1c03d5..2d6e97eb 100644 --- a/third_party/WebKit/Source/web/WebOptionElement.cpp +++ b/third_party/WebKit/Source/web/WebOptionElement.cpp
@@ -33,27 +33,16 @@ #include "core/HTMLNames.h" #include "core/html/HTMLOptionElement.h" -#include "core/html/HTMLSelectElement.h" #include "public/platform/WebString.h" #include "wtf/PassRefPtr.h" namespace blink { -void WebOptionElement::setValue(const WebString& newValue) -{ - unwrap<HTMLOptionElement>()->setValue(newValue); -} - WebString WebOptionElement::value() const { return constUnwrap<HTMLOptionElement>()->value(); } -int WebOptionElement::index() const -{ - return constUnwrap<HTMLOptionElement>()->index(); -} - WebString WebOptionElement::text() const { return constUnwrap<HTMLOptionElement>()->displayLabel(); @@ -64,11 +53,6 @@ return constUnwrap<HTMLOptionElement>()->label(); } -bool WebOptionElement::isEnabled() const -{ - return !(constUnwrap<HTMLOptionElement>()->isDisabledFormControl()); -} - WebOptionElement::WebOptionElement(const PassRefPtrWillBeRawPtr<HTMLOptionElement>& elem) : WebElement(elem) {
diff --git a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp index 60ab35cf..6c4a2be 100644 --- a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp +++ b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
@@ -43,6 +43,8 @@ #include "core/events/GestureEvent.h" #include "core/events/KeyboardEvent.h" #include "core/events/MouseEvent.h" +#include "core/events/ProgressEvent.h" +#include "core/events/ResourceProgressEvent.h" #include "core/events/TouchEvent.h" #include "core/events/WheelEvent.h" #include "core/frame/EventHandlerRegistry.h" @@ -391,6 +393,17 @@ return WebElement(m_element); } +void WebPluginContainerImpl::dispatchProgressEvent(const WebString& type, bool lengthComputable, unsigned long long loaded, unsigned long long total, const WebString& url) +{ + RefPtrWillBeRawPtr<ProgressEvent> event; + if (url.isEmpty()) { + event = ProgressEvent::create(type, lengthComputable, loaded, total); + } else { + event = ResourceProgressEvent::create(type, lengthComputable, loaded, total, url); + } + m_element->dispatchEvent(event.release()); +} + void WebPluginContainerImpl::invalidate() { Widget::invalidate();
diff --git a/third_party/WebKit/Source/web/WebPluginContainerImpl.h b/third_party/WebKit/Source/web/WebPluginContainerImpl.h index dad54db..d0be624 100644 --- a/third_party/WebKit/Source/web/WebPluginContainerImpl.h +++ b/third_party/WebKit/Source/web/WebPluginContainerImpl.h
@@ -97,6 +97,7 @@ // WebPluginContainer methods WebElement element() override; + void dispatchProgressEvent(const WebString& type, bool lengthComputable, unsigned long long loaded, unsigned long long total, const WebString& url) override; void invalidate() override; void invalidateRect(const WebRect&) override; void scrollRect(const WebRect&) override;
diff --git a/third_party/WebKit/Source/web/web.gypi b/third_party/WebKit/Source/web/web.gypi index 023ed7ac..ea6eaaa1 100644 --- a/third_party/WebKit/Source/web/web.gypi +++ b/third_party/WebKit/Source/web/web.gypi
@@ -123,7 +123,6 @@ 'WebDOMMediaStreamTrack.cpp', 'WebDOMMessageEvent.cpp', 'WebDOMProgressEvent.cpp', - 'WebDOMResourceProgressEvent.cpp', 'WebDataSourceImpl.cpp', 'WebDataSourceImpl.h', 'WebDatabase.cpp',
diff --git a/third_party/WebKit/public/blink_headers.gypi b/third_party/WebKit/public/blink_headers.gypi index 398fdf82..a3747be 100644 --- a/third_party/WebKit/public/blink_headers.gypi +++ b/third_party/WebKit/public/blink_headers.gypi
@@ -359,7 +359,6 @@ "web/WebDOMMediaStreamTrack.h", "web/WebDOMMessageEvent.h", "web/WebDOMProgressEvent.h", - "web/WebDOMResourceProgressEvent.h", "web/WebDataSource.h", "web/WebDatabase.h", "web/WebDateTimeChooserCompletion.h",
diff --git a/third_party/WebKit/public/web/WebDOMResourceProgressEvent.h b/third_party/WebKit/public/web/WebDOMResourceProgressEvent.h deleted file mode 100644 index 9736e8f..0000000 --- a/third_party/WebKit/public/web/WebDOMResourceProgressEvent.h +++ /dev/null
@@ -1,48 +0,0 @@ -/* - * Copyright (C) 2013 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WebDOMResourceProgressEvent_h -#define WebDOMResourceProgressEvent_h - -#include "WebDOMProgressEvent.h" - -namespace blink { - -class WebString; - -class WebDOMResourceProgressEvent : public WebDOMProgressEvent { -public: - WebDOMResourceProgressEvent() { } - BLINK_EXPORT WebDOMResourceProgressEvent(const WebString& type, bool lengthIsComputable, unsigned long long loaded, unsigned long long total, const WebString& url); -}; - -} // namespace blink - -#endif
diff --git a/third_party/WebKit/public/web/WebElement.h b/third_party/WebKit/public/web/WebElement.h index 012fe328..ae356e5 100644 --- a/third_party/WebKit/public/web/WebElement.h +++ b/third_party/WebKit/public/web/WebElement.h
@@ -59,7 +59,6 @@ // namespace. Tag name matching is case-insensitive. BLINK_EXPORT bool hasHTMLTagName(const WebString&) const; BLINK_EXPORT bool hasAttribute(const WebString&) const; - BLINK_EXPORT void removeAttribute(const WebString&); BLINK_EXPORT WebString getAttribute(const WebString&) const; BLINK_EXPORT bool setAttribute(const WebString& name, const WebString& value); BLINK_EXPORT WebString textContent() const;
diff --git a/third_party/WebKit/public/web/WebImageCache.h b/third_party/WebKit/public/web/WebImageCache.h index 8dcdd4e..22a524c 100644 --- a/third_party/WebKit/public/web/WebImageCache.h +++ b/third_party/WebKit/public/web/WebImageCache.h
@@ -35,8 +35,6 @@ namespace blink { -// An interface to query and configure WebKit's image cache. -// // Methods of this interface can be called on any thread. // // Methods of this interface can be only be used after blink::initialize() @@ -44,19 +42,10 @@ class WebImageCache { public: - // Sets the capacities of the image cache, evicting objects as necessary. - BLINK_EXPORT static void setCacheLimitInBytes(size_t); - // Clears the cache (as much as possible; some resources may not be // cleared if they are actively referenced). BLINK_EXPORT static void clear(); - // Returns the number of bytes used by the cache. - BLINK_EXPORT static size_t memoryUsageInBytes(); - - // Returns the number of cached entries. - BLINK_EXPORT static unsigned cacheEntries(); - private: WebImageCache(); // Not intended to be instanced. };
diff --git a/third_party/WebKit/public/web/WebOptionElement.h b/third_party/WebKit/public/web/WebOptionElement.h index bc98f98..01c00e6 100644 --- a/third_party/WebKit/public/web/WebOptionElement.h +++ b/third_party/WebKit/public/web/WebOptionElement.h
@@ -31,14 +31,13 @@ #ifndef WebOptionElement_h #define WebOptionElement_h -#include "../platform/WebVector.h" #include "WebElement.h" namespace blink { class HTMLOptionElement; +class WebString; -// Provides readonly access to some properties of a DOM option element node. class WebOptionElement final : public WebElement { public: WebOptionElement() : WebElement() { } @@ -51,13 +50,9 @@ } void assign(const WebOptionElement& element) { WebElement::assign(element); } - BLINK_EXPORT void setValue(const WebString&); BLINK_EXPORT WebString value() const; - - BLINK_EXPORT int index() const; BLINK_EXPORT WebString text() const; BLINK_EXPORT WebString label() const; - BLINK_EXPORT bool isEnabled() const; #if BLINK_IMPLEMENTATION WebOptionElement(const PassRefPtrWillBeRawPtr<HTMLOptionElement>&);
diff --git a/third_party/WebKit/public/web/WebPluginContainer.h b/third_party/WebKit/public/web/WebPluginContainer.h index aff88c6..b757702 100644 --- a/third_party/WebKit/public/web/WebPluginContainer.h +++ b/third_party/WebKit/public/web/WebPluginContainer.h
@@ -59,6 +59,8 @@ // Returns the element containing this plugin. virtual WebElement element() = 0; + virtual void dispatchProgressEvent(const WebString& type, bool lengthComputable, unsigned long long loaded, unsigned long long total, const WebString& url) = 0; + virtual void invalidate() = 0; virtual void invalidateRect(const WebRect&) = 0; virtual void scrollRect(const WebRect&) = 0;
diff --git a/third_party/libjingle/README.chromium b/third_party/libjingle/README.chromium index b135b34d..9ee3b5d 100644 --- a/third_party/libjingle/README.chromium +++ b/third_party/libjingle/README.chromium
@@ -1,7 +1,7 @@ Name: libjingle URL: http://www.webrtc.org Version: unknown -Revision: 10646 +Revision: 10659 License: BSD License File: source/talk/COPYING Security Critical: yes
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index c0391ce..d37d8921 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -47990,6 +47990,14 @@ </summary> </histogram> +<histogram name="TabManager.Discarding.InactiveToReloadTime" units="ms"> + <owner>georgesak@chromium.org</owner> + <summary> + Elapsed time between the time a tab switched from being active to inactive + (that eventually gets discarded) until it gets reloaded. + </summary> +</histogram> + <histogram name="TabManager.Discarding.ReloadCount" units="Reloads"> <owner>georgesak@chromium.org</owner> <summary> @@ -58667,6 +58675,7 @@ <int value="308" label="Default printer selection rules"/> <int value="309" label="Allow Dinosaur Easter Egg Game"/> <int value="310" label="Whether RC4 cipher suites in TLS are enabled"/> + <int value="311" label="Default value for Display Rotation"/> </enum> <enum name="EnterprisePolicyInvalidations" type="int"> @@ -75842,7 +75851,7 @@ <int value="10" label="kDefaultSearchProviderName"/> <int value="11" label="kPinnedTabs"/> <int value="12" label="kKnownDisabled (Obsolete 07/2014)"/> - <int value="13" label="kProfileResetPromptMemento"/> + <int value="13" label="kProfileResetPromptMemento (Obsolete 11/2015)"/> <int value="14" label="kDefaultSearchProviderDataPrefName"/> <int value="15" label="kPreferenceResetTime"/> <int value="16" label="kSafeBrowsingIncidentReportSent"/>
diff --git a/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java b/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java index ad02b45..615b0ab 100644 --- a/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java +++ b/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java
@@ -41,7 +41,6 @@ private static final String PERMISSION_QUERIED_KEY_PREFIX = "HasRequestedAndroidPermission::"; - private final WeakReference<Activity> mActivityRef; private final Handler mHandler; private final SparseArray<PermissionCallback> mOutstandingPermissionRequests; @@ -63,8 +62,7 @@ * @param listenToActivityState Whether to listen to activity state changes. */ public ActivityWindowAndroid(Activity activity, boolean listenToActivityState) { - super(activity.getApplicationContext()); - mActivityRef = new WeakReference<Activity>(activity); + super(activity); mHandler = new Handler(); mOutstandingPermissionRequests = new SparseArray<PermissionCallback>(); if (listenToActivityState) { @@ -76,16 +74,16 @@ @Override protected void registerKeyboardVisibilityCallbacks() { - Activity activity = mActivityRef.get(); + Activity activity = getActivity().get(); if (activity == null) return; View content = activity.findViewById(android.R.id.content); - mIsKeyboardShowing = UiUtils.isKeyboardShowing(mActivityRef.get(), content); + mIsKeyboardShowing = UiUtils.isKeyboardShowing(getActivity().get(), content); content.addOnLayoutChangeListener(this); } @Override protected void unregisterKeyboardVisibilityCallbacks() { - Activity activity = mActivityRef.get(); + Activity activity = getActivity().get(); if (activity == null) return; activity.findViewById(android.R.id.content).removeOnLayoutChangeListener(this); } @@ -93,7 +91,7 @@ @Override public int showCancelableIntent( PendingIntent intent, IntentCallback callback, Integer errorId) { - Activity activity = mActivityRef.get(); + Activity activity = getActivity().get(); if (activity == null) return START_INTENT_FAILURE; int requestCode = generateNextRequestCode(); @@ -111,7 +109,7 @@ @Override public int showCancelableIntent(Intent intent, IntentCallback callback, Integer errorId) { - Activity activity = mActivityRef.get(); + Activity activity = getActivity().get(); if (activity == null) return START_INTENT_FAILURE; int requestCode = generateNextRequestCode(); @@ -128,7 +126,7 @@ @Override public void cancelIntent(int requestCode) { - Activity activity = mActivityRef.get(); + Activity activity = getActivity().get(); if (activity == null) return; activity.finishActivity(requestCode); } @@ -190,7 +188,7 @@ */ public boolean onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { - Activity activity = mActivityRef.get(); + Activity activity = getActivity().get(); assert activity != null; SharedPreferences.Editor editor = @@ -209,8 +207,7 @@ @Override public WeakReference<Activity> getActivity() { - // Return a new WeakReference to prevent clients from releasing our internal WeakReference. - return new WeakReference<Activity>(mActivityRef.get()); + return new WeakReference<Activity>((Activity) getContext().get()); } @Override @@ -225,7 +222,7 @@ @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { - keyboardVisibilityPossiblyChanged(UiUtils.isKeyboardShowing(mActivityRef.get(), v)); + keyboardVisibilityPossiblyChanged(UiUtils.isKeyboardShowing(getActivity().get(), v)); } private int generateNextRequestCode() { @@ -251,7 +248,7 @@ public boolean canRequestPermission(String permission) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return false; - Activity activity = mActivityRef.get(); + Activity activity = getActivity().get(); if (activity == null) return false; if (isPermissionRevokedByPolicy(permission)) { @@ -275,7 +272,7 @@ public boolean isPermissionRevokedByPolicy(String permission) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return false; - Activity activity = mActivityRef.get(); + Activity activity = getActivity().get(); if (activity == null) return false; return activity.getPackageManager().isPermissionRevokedByPolicy( @@ -311,7 +308,7 @@ private boolean requestPermissionsInternal( String[] permissions, PermissionCallback callback) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return false; - Activity activity = mActivityRef.get(); + Activity activity = getActivity().get(); if (activity == null) return false; int requestCode = generateNextRequestCode();
diff --git a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java index 3d775de1..658d0be 100644 --- a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java +++ b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
@@ -77,6 +77,8 @@ protected Context mApplicationContext; protected SparseArray<IntentCallback> mOutstandingIntents; + // We use a weak reference here to prevent this from leaking in WebView. + private WeakReference<Context> mContextRef; // Ideally, this would be a SparseArray<String>, but there's no easy way to store a // SparseArray<String> in a bundle during saveInstanceState(). So we use a HashMap and suppress @@ -136,13 +138,20 @@ */ @SuppressLint("UseSparseArrays") public WindowAndroid(Context context) { - assert context == context.getApplicationContext(); - mApplicationContext = context; + mApplicationContext = context.getApplicationContext(); + // context does not have the same lifetime guarantees as an application context so we can't + // hold a strong reference to it. + mContextRef = new WeakReference<Context>(context); mOutstandingIntents = new SparseArray<IntentCallback>(); mIntentErrors = new HashMap<Integer, String>(); mVSyncMonitor = new VSyncMonitor(context, mVSyncListener); - mAccessibilityManager = (AccessibilityManager) - context.getSystemService(Context.ACCESSIBILITY_SERVICE); + mAccessibilityManager = (AccessibilityManager) mApplicationContext.getSystemService( + Context.ACCESSIBILITY_SERVICE); + } + + @CalledByNative + private static WindowAndroid createForTesting(Context context) { + return new WindowAndroid(context); } /** @@ -584,6 +593,16 @@ } /** + * Getter for the current context (not necessarily the application context). + * Make no assumptions regarding what type of Context is returned here, it could be for example + * an Activity or a Context created specifically to target an external display. + */ + public WeakReference<Context> getContext() { + // Return a new WeakReference to prevent clients from releasing our internal WeakReference. + return new WeakReference<Context>(mContextRef.get()); + } + + /** * Update whether the placeholder is 'drawn' based on whether an animation is running * or touch exploration is enabled - if either of those are true, we call * setWillNotDraw(false) to ensure that the animation is drawn over the SurfaceView,
diff --git a/ui/android/java/src/org/chromium/ui/resources/ResourceManager.java b/ui/android/java/src/org/chromium/ui/resources/ResourceManager.java index da3d254..3e96bbb 100644 --- a/ui/android/java/src/org/chromium/ui/resources/ResourceManager.java +++ b/ui/android/java/src/org/chromium/ui/resources/ResourceManager.java
@@ -13,6 +13,8 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.MainDex; +import org.chromium.ui.base.WindowAndroid; +import org.chromium.ui.gfx.DeviceDisplayInfo; import org.chromium.ui.resources.ResourceLoader.ResourceLoaderCallback; import org.chromium.ui.resources.dynamics.DynamicResource; import org.chromium.ui.resources.dynamics.DynamicResourceLoader; @@ -37,33 +39,51 @@ private long mNativeResourceManagerPtr; - private ResourceManager(Context context, long staticResourceManagerPtr) { - Resources resources = context.getResources(); + private ResourceManager( + Resources resources, int minScreenSideLength, long staticResourceManagerPtr) { mPxToDp = 1.f / resources.getDisplayMetrics().density; - // Register ResourceLoaders registerResourceLoader(new StaticResourceLoader( AndroidResourceType.STATIC, this, resources)); registerResourceLoader(new DynamicResourceLoader( AndroidResourceType.DYNAMIC, this)); registerResourceLoader(new DynamicResourceLoader( AndroidResourceType.DYNAMIC_BITMAP, this)); - registerResourceLoader(new SystemResourceLoader( - AndroidResourceType.SYSTEM, this, context)); + registerResourceLoader( + new SystemResourceLoader(AndroidResourceType.SYSTEM, this, minScreenSideLength)); mCrushedSpriteResourceLoader = new CrushedSpriteResourceLoader(this, resources); mNativeResourceManagerPtr = staticResourceManagerPtr; } /** - * Creates an instance of a {@link ResourceManager}. This will - * @param context A {@link Context} instance to grab {@link Resources} from. + * Creates an instance of a {@link ResourceManager}. + * @param WindowAndroid A {@link WindowAndroid} instance to fetch a {@link Context} + * and thus grab {@link Resources} from. * @param staticResourceManagerPtr A pointer to the native component of this class. * @return A new instance of a {@link ResourceManager}. */ @CalledByNative - private static ResourceManager create(Context context, long staticResourceManagerPtr) { - return new ResourceManager(context, staticResourceManagerPtr); + private static ResourceManager create( + WindowAndroid windowAndroid, long staticResourceManagerPtr) { + Context context = windowAndroid.getContext().get(); + // This call should happen early enough (i.e. during construction) that this context should + // not yet have been released. + if (context == null) { + throw new IllegalStateException("Context should not be null during initialization."); + } + + DeviceDisplayInfo displayInfo = DeviceDisplayInfo.create(context); + int screenWidth = displayInfo.getPhysicalDisplayWidth() != 0 + ? displayInfo.getPhysicalDisplayWidth() + : displayInfo.getDisplayWidth(); + int screenHeight = displayInfo.getPhysicalDisplayHeight() != 0 + ? displayInfo.getPhysicalDisplayHeight() + : displayInfo.getDisplayHeight(); + int minScreenSideLength = Math.min(screenWidth, screenHeight); + + Resources resources = context.getResources(); + return new ResourceManager(resources, minScreenSideLength, staticResourceManagerPtr); } /**
diff --git a/ui/android/java/src/org/chromium/ui/resources/system/SystemResourceLoader.java b/ui/android/java/src/org/chromium/ui/resources/system/SystemResourceLoader.java index 9039ac23..0cbedf5 100644 --- a/ui/android/java/src/org/chromium/ui/resources/system/SystemResourceLoader.java +++ b/ui/android/java/src/org/chromium/ui/resources/system/SystemResourceLoader.java
@@ -4,7 +4,6 @@ package org.chromium.ui.resources.system; -import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Canvas; @@ -12,7 +11,6 @@ import android.graphics.Paint.Style; import android.graphics.RectF; -import org.chromium.ui.gfx.DeviceDisplayInfo; import org.chromium.ui.resources.Resource; import org.chromium.ui.resources.SystemUIResourceType; import org.chromium.ui.resources.async.AsyncPreloadResourceLoader; @@ -30,19 +28,19 @@ * @param resourceType The resource type this loader is responsible for loading. * @param callback The {@link ResourceLoaderCallback} to notify when a {@link Resource} is * done loading. - * @param resources A {@link Resources} instance to load assets from. + * @param minScreenSideLengthPx The length (in pixels) of the smallest side of the screen. */ - public SystemResourceLoader(int resourceType, ResourceLoaderCallback callback, - final Context context) { + public SystemResourceLoader( + int resourceType, ResourceLoaderCallback callback, final int minScreenSideLengthPx) { super(resourceType, callback, new ResourceCreator() { @Override public Resource create(int resId) { - return createResource(context, resId); + return createResource(minScreenSideLengthPx, resId); } }); } - private static Resource createResource(Context context, int resId) { + private static Resource createResource(int minScreenSideLengthPx, int resId) { switch (resId) { case SystemUIResourceType.OVERSCROLL_EDGE: return StaticResource.create(Resources.getSystem(), @@ -51,7 +49,7 @@ return StaticResource.create(Resources.getSystem(), getResourceId("android:drawable/overscroll_glow"), 128, 64); case SystemUIResourceType.OVERSCROLL_GLOW_L: - return createOverscrollGlowLBitmap(context); + return createOverscrollGlowLBitmap(minScreenSideLengthPx); default: assert false; @@ -59,14 +57,8 @@ return null; } - private static Resource createOverscrollGlowLBitmap(Context context) { - DeviceDisplayInfo displayInfo = DeviceDisplayInfo.create(context); - int screenWidth = displayInfo.getPhysicalDisplayWidth() != 0 - ? displayInfo.getPhysicalDisplayWidth() : displayInfo.getDisplayWidth(); - int screenHeight = displayInfo.getPhysicalDisplayHeight() != 0 - ? displayInfo.getPhysicalDisplayHeight() : displayInfo.getDisplayHeight(); - - float arcWidth = Math.min(screenWidth, screenHeight) * 0.5f / SIN_PI_OVER_6; + private static Resource createOverscrollGlowLBitmap(int minScreenSideLengthPx) { + float arcWidth = minScreenSideLengthPx * 0.5f / SIN_PI_OVER_6; float y = COS_PI_OVER_6 * arcWidth; float height = arcWidth - y;
diff --git a/ui/android/resources/resource_manager_impl.cc b/ui/android/resources/resource_manager_impl.cc index a4f2373..c5dd3b6 100644 --- a/ui/android/resources/resource_manager_impl.cc +++ b/ui/android/resources/resource_manager_impl.cc
@@ -13,6 +13,7 @@ #include "cc/resources/scoped_ui_resource.h" #include "jni/ResourceManager_jni.h" #include "ui/android/resources/ui_resource_provider.h" +#include "ui/android/window_android.h" #include "ui/gfx/android/java_bitmap.h" #include "ui/gfx/geometry/rect.h" @@ -27,11 +28,13 @@ jobj)); } -ResourceManagerImpl::ResourceManagerImpl() : host_(nullptr) { +ResourceManagerImpl::ResourceManagerImpl(gfx::NativeWindow native_window) + : host_(nullptr) { JNIEnv* env = base::android::AttachCurrentThread(); java_obj_.Reset(env, Java_ResourceManager_create( - env, base::android::GetApplicationContext(), - reinterpret_cast<intptr_t>(this)).obj()); + env, native_window->GetJavaObject().obj(), + reinterpret_cast<intptr_t>(this)) + .obj()); DCHECK(!java_obj_.is_null()); }
diff --git a/ui/android/resources/resource_manager_impl.h b/ui/android/resources/resource_manager_impl.h index 04d59cc..4618a36 100644 --- a/ui/android/resources/resource_manager_impl.h +++ b/ui/android/resources/resource_manager_impl.h
@@ -9,6 +9,7 @@ #include "ui/android/resources/resource_manager.h" #include "ui/android/ui_android_export.h" #include "ui/gfx/geometry/rect.h" +#include "ui/gfx/native_widget_types.h" namespace ui { @@ -16,7 +17,7 @@ public: static ResourceManagerImpl* FromJavaObject(jobject jobj); - ResourceManagerImpl(); + explicit ResourceManagerImpl(gfx::NativeWindow native_window); ~ResourceManagerImpl() override; void Init(cc::LayerTreeHost* host);
diff --git a/ui/android/resources/resource_manager_impl_unittest.cc b/ui/android/resources/resource_manager_impl_unittest.cc index dbf2e65a..fd57f70 100644 --- a/ui/android/resources/resource_manager_impl_unittest.cc +++ b/ui/android/resources/resource_manager_impl_unittest.cc
@@ -12,6 +12,7 @@ #include "third_party/skia/include/core/SkCanvas.h" #include "ui/android/resources/resource_manager_impl.h" #include "ui/android/resources/system_ui_resource_type.h" +#include "ui/android/window_android.h" #include "ui/gfx/android/java_bitmap.h" @@ -34,7 +35,9 @@ class TestResourceManagerImpl : public ResourceManagerImpl { public: - TestResourceManagerImpl() {} + TestResourceManagerImpl(WindowAndroid* window_android) + : ResourceManagerImpl(window_android) {} + ~TestResourceManagerImpl() override {} void SetResourceAsLoaded(AndroidResourceType res_type, int res_id) { @@ -80,7 +83,10 @@ class ResourceManagerTest : public testing::Test { public: - ResourceManagerTest() : fake_client_(cc::FakeLayerTreeHostClient::DIRECT_3D) { + ResourceManagerTest() + : window_android_(WindowAndroid::createForTesting()), + resource_manager_(window_android_), + fake_client_(cc::FakeLayerTreeHostClient::DIRECT_3D) { cc::LayerTreeHost::InitParams params; cc::LayerTreeSettings settings; params.client = &fake_client_; @@ -90,6 +96,8 @@ resource_manager_.Init(host_.get()); } + ~ResourceManagerTest() override { window_android_->Destroy(NULL, NULL); } + void PreloadResource(ui::SystemUIResourceType type) { resource_manager_.PreloadResource(ui::ANDROID_RESOURCE_TYPE_SYSTEM, type); } @@ -104,6 +112,9 @@ type); } + private: + WindowAndroid* window_android_; + protected: scoped_ptr<MockLayerTreeHost> host_; TestResourceManagerImpl resource_manager_;
diff --git a/ui/android/window_android.cc b/ui/android/window_android.cc index 5fe7779..0ba6e6cc 100644 --- a/ui/android/window_android.cc +++ b/ui/android/window_android.cc
@@ -38,6 +38,13 @@ DCHECK(!compositor_); } +WindowAndroid* WindowAndroid::createForTesting() { + JNIEnv* env = AttachCurrentThread(); + jobject context = base::android::GetApplicationContext(); + return new WindowAndroid( + env, Java_WindowAndroid_createForTesting(env, context).obj()); +} + void WindowAndroid::OnCompositingDidCommit() { FOR_EACH_OBSERVER(WindowAndroidObserver, observer_list_,
diff --git a/ui/android/window_android.h b/ui/android/window_android.h index 58f1e28..f08b2f2 100644 --- a/ui/android/window_android.h +++ b/ui/android/window_android.h
@@ -69,6 +69,8 @@ // Return whether the specified Android permission can be requested by Chrome. bool CanRequestPermission(const std::string& permission); + static WindowAndroid* createForTesting(); + private: ~WindowAndroid();
diff --git a/ui/aura/window_tree_host_platform.cc b/ui/aura/window_tree_host_platform.cc index 10c5013..409f92a 100644 --- a/ui/aura/window_tree_host_platform.cc +++ b/ui/aura/window_tree_host_platform.cc
@@ -49,8 +49,7 @@ WindowTreeHostPlatform::WindowTreeHostPlatform() : widget_(gfx::kNullAcceleratedWidget), - current_cursor_(ui::kCursorNull), - has_capture_(false) {} + current_cursor_(ui::kCursorNull) {} void WindowTreeHostPlatform::SetPlatformWindow( scoped_ptr<ui::PlatformWindow> window) { @@ -91,15 +90,11 @@ } void WindowTreeHostPlatform::SetCapture() { - if (!has_capture_) { - has_capture_ = true; - window_->SetCapture(); - } + window_->SetCapture(); } void WindowTreeHostPlatform::ReleaseCapture() { - if (has_capture_) - window_->ReleaseCapture(); + window_->ReleaseCapture(); } void WindowTreeHostPlatform::SetCursorNative(gfx::NativeCursor cursor) { @@ -164,10 +159,7 @@ ui::PlatformWindowState new_state) {} void WindowTreeHostPlatform::OnLostCapture() { - if (has_capture_) { - has_capture_ = false; - OnHostLostWindowCapture(); - } + OnHostLostWindowCapture(); } void WindowTreeHostPlatform::OnAcceleratedWidgetAvailable(
diff --git a/ui/aura/window_tree_host_platform.h b/ui/aura/window_tree_host_platform.h index 18b8e4d..b885e73 100644 --- a/ui/aura/window_tree_host_platform.h +++ b/ui/aura/window_tree_host_platform.h
@@ -60,7 +60,6 @@ gfx::AcceleratedWidget widget_; scoped_ptr<ui::PlatformWindow> window_; gfx::NativeCursor current_cursor_; - bool has_capture_; gfx::Rect bounds_; DISALLOW_COPY_AND_ASSIGN(WindowTreeHostPlatform);
diff --git a/ui/base/clipboard/clipboard_mac.mm b/ui/base/clipboard/clipboard_mac.mm index 62331947..306502f 100644 --- a/ui/base/clipboard/clipboard_mac.mm +++ b/ui/base/clipboard/clipboard_mac.mm
@@ -307,8 +307,21 @@ // may throw, and that exception will leak. Prevent a crash in that case; // a blank image is better. base::scoped_nsobject<NSImage> image; + NSPasteboard* pb = GetPasteboard(); @try { - image.reset([[NSImage alloc] initWithPasteboard:GetPasteboard()]); + if ([[pb types] containsObject:NSFilenamesPboardType]) { + // -[NSImage initWithPasteboard:] gets confused with copies of a single + // file from the Finder, so extract the path ourselves. + // http://crbug.com/553686 + NSArray* paths = [pb propertyListForType:NSFilenamesPboardType]; + if ([paths count]) { + // If N number of files are selected from finder, choose the last one. + image.reset([[NSImage alloc] + initWithContentsOfURL:[NSURL fileURLWithPath:[paths lastObject]]]); + } + } else { + image.reset([[NSImage alloc] initWithPasteboard:pb]); + } } @catch (id exception) { }
diff --git a/ui/gfx/display.h b/ui/gfx/display.h index 650c95f..b355c1a8d 100644 --- a/ui/gfx/display.h +++ b/ui/gfx/display.h
@@ -23,6 +23,8 @@ class GFX_EXPORT Display { public: // Screen Rotation in clock-wise degrees. + // This enum corresponds to DisplayRotationDefaultProto::Rotation in + // chrome/browser/chromeos/policy/proto/chrome_device_policy.proto. enum Rotation { ROTATE_0 = 0, ROTATE_90,
diff --git a/ui/gl/BUILD.gn b/ui/gl/BUILD.gn index 1131722..6d101e37 100644 --- a/ui/gl/BUILD.gn +++ b/ui/gl/BUILD.gn
@@ -344,10 +344,6 @@ sources += [ "glx_api_unittest.cc" ] } - if (use_ozone) { - sources += [ "gl_image_ozone_native_pixmap_unittest.cc" ] - } - include_dirs = [ "//third_party/khronos" ] deps = [
diff --git a/ui/gl/gl_image_egl.cc b/ui/gl/gl_image_egl.cc index c130832..91800e2 100644 --- a/ui/gl/gl_image_egl.cc +++ b/ui/gl/gl_image_egl.cc
@@ -56,9 +56,7 @@ bool GLImageEGL::BindTexImage(unsigned target) { DCHECK(thread_checker_.CalledOnValidThread()); - if (egl_image_ == EGL_NO_IMAGE_KHR) - return false; - + DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_); glEGLImageTargetTexture2DOES(target, egl_image_); DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); return true;
diff --git a/ui/gl/gl_image_ozone_native_pixmap_unittest.cc b/ui/gl/gl_image_ozone_native_pixmap_unittest.cc deleted file mode 100644 index a21a444..0000000 --- a/ui/gl/gl_image_ozone_native_pixmap_unittest.cc +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2015 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 "testing/gtest/include/gtest/gtest.h" -#include "ui/gfx/buffer_types.h" -#include "ui/gl/gl_image_ozone_native_pixmap.h" -#include "ui/gl/test/gl_image_test_template.h" -#include "ui/ozone/public/ozone_platform.h" -#include "ui/ozone/public/surface_factory_ozone.h" - -namespace gl { -namespace { - -class GLImageOzoneNativePixmapTestDelegate { - public: - scoped_refptr<gl::GLImage> CreateSolidColorImage( - const gfx::Size& size, - const uint8_t color[4]) const { - ui::SurfaceFactoryOzone* surface_factory = - ui::OzonePlatform::GetInstance()->GetSurfaceFactoryOzone(); - scoped_refptr<ui::NativePixmap> pixmap = - surface_factory->CreateNativePixmap(gfx::kNullAcceleratedWidget, size, - gfx::BufferFormat::RGBA_8888, - gfx::BufferUsage::SCANOUT); - EXPECT_TRUE(pixmap != nullptr); - scoped_refptr<gfx::GLImageOzoneNativePixmap> image( - new gfx::GLImageOzoneNativePixmap(size, GL_RGBA)); - EXPECT_TRUE(image->Initialize(pixmap.get(), pixmap->GetBufferFormat())); - return image; - } -}; - -INSTANTIATE_TYPED_TEST_CASE_P(GLImageOzoneNativePixmap, - GLImageTest, - GLImageOzoneNativePixmapTestDelegate); - -} // namespace -} // namespace gl
diff --git a/ui/gl/gl_tests.gyp b/ui/gl/gl_tests.gyp index 9b09ad81..d369723 100644 --- a/ui/gl/gl_tests.gyp +++ b/ui/gl/gl_tests.gyp
@@ -54,11 +54,6 @@ 'wgl_api_unittest.cc', ], }], - ['use_ozone==1', { - 'sources': [ - 'gl_image_ozone_native_pixmap_unittest.cc', - ], - }], ], } ],
diff --git a/ui/login/account_picker/screen_account_picker.css b/ui/login/account_picker/screen_account_picker.css index d90210a..66f079e 100644 --- a/ui/login/account_picker/screen_account_picker.css +++ b/ui/login/account_picker/screen_account_picker.css
@@ -8,6 +8,10 @@ height 180ms ease; } +#bubble { + z-index: 1; +} + #signin-banner-container1 { bottom: 100%; margin-bottom: 10px;
diff --git a/ui/ozone/platform/cast/client_native_pixmap_factory_cast.cc b/ui/ozone/platform/cast/client_native_pixmap_factory_cast.cc index a55c3462..3f7100a 100644 --- a/ui/ozone/platform/cast/client_native_pixmap_factory_cast.cc +++ b/ui/ozone/platform/cast/client_native_pixmap_factory_cast.cc
@@ -4,51 +4,12 @@ #include "ui/ozone/platform/cast/client_native_pixmap_factory_cast.h" -#include "base/logging.h" -#include "ui/gfx/buffer_types.h" -#include "ui/ozone/public/client_native_pixmap.h" -#include "ui/ozone/public/client_native_pixmap_factory.h" +#include "ui/ozone/common/stub_client_native_pixmap_factory.h" namespace ui { -namespace { - -// Dummy ClientNativePixmap implementation for Cast ozone. -// Our NativePixmaps are just used to plumb an overlay frame through, -// so they get instantiated, but not used. -class ClientNativePixmapCast : public ClientNativePixmap { - public: - // ClientNativePixmap implementation: - void* Map() override { - NOTREACHED(); - return nullptr; - } - void Unmap() override { NOTREACHED(); } - void GetStride(int* stride) const override { NOTREACHED(); } -}; - -class ClientNativePixmapFactoryCast : public ClientNativePixmapFactory { - public: - // ClientNativePixmapFactoryCast implementation: - void Initialize(base::ScopedFD device_fd) override {} - - bool IsConfigurationSupported(gfx::BufferFormat format, - gfx::BufferUsage usage) const override { - return format == gfx::BufferFormat::RGBA_8888 && - usage == gfx::BufferUsage::SCANOUT; - } - - scoped_ptr<ClientNativePixmap> ImportFromHandle( - const gfx::NativePixmapHandle& handle, - const gfx::Size& size, - gfx::BufferUsage usage) override { - return make_scoped_ptr(new ClientNativePixmapCast()); - } -}; - -} // namespace ClientNativePixmapFactory* CreateClientNativePixmapFactoryCast() { - return new ClientNativePixmapFactoryCast(); + return CreateStubClientNativePixmapFactory(); } } // namespace ui
diff --git a/ui/ozone/platform/cast/surface_factory_cast.cc b/ui/ozone/platform/cast/surface_factory_cast.cc index 1d4bee3b..174dd78 100644 --- a/ui/ozone/platform/cast/surface_factory_cast.cc +++ b/ui/ozone/platform/cast/surface_factory_cast.cc
@@ -69,8 +69,7 @@ void SurfaceFactoryCast::TerminateDisplay() { void* egl_lib_handle = egl_platform_->GetEglLibrary(); - if (!egl_lib_handle) - return; + DCHECK(egl_lib_handle); EGLGetDisplayFn get_display = reinterpret_cast<EGLGetDisplayFn>(dlsym(egl_lib_handle, "eglGetDisplay")); @@ -189,7 +188,7 @@ // TODO(halliwell): try to implement this through CastEglPlatform. return nullptr; } - int GetDmaBufFd() override { return -1; } + int GetDmaBufFd() override { return 0; } int GetDmaBufPitch() override { return 0; } gfx::BufferFormat GetBufferFormat() override { return gfx::BufferFormat::LAST;
diff --git a/ui/ozone/platform/headless/headless_surface_factory.cc b/ui/ozone/platform/headless/headless_surface_factory.cc index 1b7b956c..3262e69 100644 --- a/ui/ozone/platform/headless/headless_surface_factory.cc +++ b/ui/ozone/platform/headless/headless_surface_factory.cc
@@ -16,7 +16,6 @@ #include "ui/gfx/vsync_provider.h" #include "ui/ozone/platform/headless/headless_window.h" #include "ui/ozone/platform/headless/headless_window_manager.h" -#include "ui/ozone/public/native_pixmap.h" #include "ui/ozone/public/surface_ozone_canvas.h" namespace ui { @@ -66,40 +65,6 @@ skia::RefPtr<SkSurface> surface_; }; -class TestPixmap : public ui::NativePixmap { - public: - TestPixmap(gfx::BufferFormat format) : format_(format) {} - - void* GetEGLClientBuffer() override { return nullptr; } - int GetDmaBufFd() override { return -1; } - int GetDmaBufPitch() override { return 0; } - gfx::BufferFormat GetBufferFormat() override { return format_; } - bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, - int plane_z_order, - gfx::OverlayTransform plane_transform, - const gfx::Rect& display_bounds, - const gfx::RectF& crop_rect) override { - return true; - } - void SetProcessingCallback( - const ProcessingCallback& processing_callback) override {} - scoped_refptr<NativePixmap> GetProcessedPixmap( - gfx::Size target_size, - gfx::BufferFormat target_format) override { - return nullptr; - } - gfx::NativePixmapHandle ExportHandle() override { - return gfx::NativePixmapHandle(); - } - - private: - ~TestPixmap() override {} - - gfx::BufferFormat format_; - - DISALLOW_COPY_AND_ASSIGN(TestPixmap); -}; - } // namespace HeadlessSurfaceFactory::HeadlessSurfaceFactory() @@ -123,12 +88,4 @@ return false; } -scoped_refptr<NativePixmap> HeadlessSurfaceFactory::CreateNativePixmap( - gfx::AcceleratedWidget widget, - gfx::Size size, - gfx::BufferFormat format, - gfx::BufferUsage usage) { - return new TestPixmap(format); -} - } // namespace ui
diff --git a/ui/ozone/platform/headless/headless_surface_factory.h b/ui/ozone/platform/headless/headless_surface_factory.h index 1f008ed..b715cbcc 100644 --- a/ui/ozone/platform/headless/headless_surface_factory.h +++ b/ui/ozone/platform/headless/headless_surface_factory.h
@@ -24,11 +24,6 @@ bool LoadEGLGLES2Bindings( AddGLLibraryCallback add_gl_library, SetGLGetProcAddressProcCallback set_gl_get_proc_address) override; - scoped_refptr<NativePixmap> CreateNativePixmap( - gfx::AcceleratedWidget widget, - gfx::Size size, - gfx::BufferFormat format, - gfx::BufferUsage usage) override; private: HeadlessWindowManager* window_manager_;
diff --git a/ui/platform_window/win/win_window.cc b/ui/platform_window/win/win_window.cc index 1c6e4a974..802f2d79 100644 --- a/ui/platform_window/win/win_window.cc +++ b/ui/platform_window/win/win_window.cc
@@ -90,8 +90,8 @@ } void WinWindow::SetCapture() { - DCHECK(::GetCapture() != hwnd()); - ::SetCapture(hwnd()); + if (::GetCapture() != hwnd()) + ::SetCapture(hwnd()); } void WinWindow::ReleaseCapture() {
diff --git a/ui/views/window/dialog_delegate.cc b/ui/views/window/dialog_delegate.cc index ce4cced..ee50da9 100644 --- a/ui/views/window/dialog_delegate.cc +++ b/ui/views/window/dialog_delegate.cc
@@ -7,6 +7,7 @@ #include "base/logging.h" #include "ui/accessibility/ax_view_state.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/gfx/color_palette.h" #include "ui/strings/grit/ui_strings.h" #include "ui/views/bubble/bubble_border.h" #include "ui/views/bubble/bubble_frame_view.h" @@ -199,7 +200,7 @@ const BubbleBorder::Shadow kShadow = BubbleBorder::SMALL_SHADOW; #endif scoped_ptr<BubbleBorder> border( - new BubbleBorder(BubbleBorder::FLOAT, kShadow, SK_ColorRED)); + new BubbleBorder(BubbleBorder::FLOAT, kShadow, gfx::kPlaceholderColor)); border->set_use_theme_background_color(true); frame->SetBubbleBorder(border.Pass()); DialogDelegate* delegate = widget->widget_delegate()->AsDialogDelegate();