diff --git a/DEPS b/DEPS index 2c09039..7e8daa8 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': '57fa241d6f43557e4243a46f8b5a4ed447ccb8d2', + 'skia_revision': '55c86abedc7dcc76f5f04a256e46bb3bb065b2cb', # 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': '64fd98c5283d3004f06c83c35b0ef2f3f81eb35b', + 'v8_revision': '57138f37c1ad44aa79318e75b94fd68efa378847', # 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. @@ -271,7 +271,7 @@ 'src/third_party/catapult': Var('chromium_git') + '/external/github.com/catapult-project/catapult.git' + '@' + - '5bb87c077c8030b35fa344d553ddd7d41b49ba71', + 'f8c1c883c76b236a96836eafc4786e5d9a06c250', 'src/third_party/openh264/src': Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + 'b37cda248234162033e3e11b0335f3131cdfe488',
diff --git a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc index f4d31909..93045f3 100644 --- a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc +++ b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc
@@ -307,7 +307,7 @@ bool AwResourceDispatcherHostDelegate::HandleExternalProtocol( const GURL& url, int child_id, - int route_id, + const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter, bool is_main_frame, ui::PageTransition page_transition, bool has_user_gesture) {
diff --git a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h index 4017ef0..651f6e7 100644 --- a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h +++ b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h
@@ -48,12 +48,14 @@ content::ResourceDispatcherHostLoginDelegate* CreateLoginDelegate( net::AuthChallengeInfo* auth_info, net::URLRequest* request) override; - bool HandleExternalProtocol(const GURL& url, - int child_id, - int route_id, - bool is_main_frame, - ui::PageTransition page_transition, - bool has_user_gesture) override; + bool HandleExternalProtocol( + const GURL& url, + int child_id, + const content::ResourceRequestInfo::WebContentsGetter& + web_contents_getter, + bool is_main_frame, + ui::PageTransition page_transition, + bool has_user_gesture) override; void OnResponseStarted(net::URLRequest* request, content::ResourceContext* resource_context, content::ResourceResponse* response,
diff --git a/base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java b/base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java index b94bed3..3a2b024a0 100644 --- a/base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java +++ b/base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java
@@ -18,6 +18,7 @@ import android.content.res.Resources.NotFoundException; import android.graphics.Bitmap; import android.graphics.Color; +import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.PowerManager; @@ -417,6 +418,20 @@ } /** + * @see android.content.pm.PackageManager#getUserBadgedDrawableForDensity(Drawable drawable, + * UserHandle user, Rect badgeLocation, int badgeDensity). + */ + public static Drawable getUserBadgedDrawableForDensity( + Context context, Drawable drawable, Rect badgeLocation, int density) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + PackageManager packageManager = context.getPackageManager(); + return packageManager.getUserBadgedDrawableForDensity( + drawable, Process.myUserHandle(), badgeLocation, density); + } + return drawable; + } + + /** * @see android.content.res.Resources#getColor(int id). */ @SuppressWarnings("deprecation")
diff --git a/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java b/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java index b5186942..5a6153a5 100644 --- a/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java +++ b/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java
@@ -170,16 +170,30 @@ * detrimental to the startup time. */ public void asyncPrefetchLibrariesToMemory() { - if (!mPrefetchLibraryHasBeenCalled.compareAndSet(false, true)) return; + final boolean coldStart = mPrefetchLibraryHasBeenCalled.compareAndSet(false, true); new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... params) { TraceEvent.begin("LibraryLoader.asyncPrefetchLibrariesToMemory"); - boolean success = nativeForkAndPrefetchNativeLibrary(true); - if (!success) { - Log.w(TAG, "Forking a process to prefetch the native library failed."); + int percentage = nativePercentageOfResidentNativeLibraryCode(); + boolean success = false; + if (coldStart) { + success = nativeForkAndPrefetchNativeLibrary(); + if (!success) { + Log.w(TAG, "Forking a process to prefetch the native library failed."); + } } - RecordHistogram.recordBooleanHistogram("LibraryLoader.PrefetchStatus", success); + // As this runs in a background thread, it can be called before histograms are + // initialized. In this instance, histograms are dropped. + RecordHistogram.initialize(); + if (coldStart) { + RecordHistogram.recordBooleanHistogram("LibraryLoader.PrefetchStatus", success); + } + if (percentage != -1) { + String histogram = "LibraryLoader.PercentageOfResidentCodeBeforePrefetch" + + (coldStart ? "_ColdStartup" : "_WarmStartup"); + RecordHistogram.recordEnumeratedHistogram(histogram, percentage, 101); + } TraceEvent.end("LibraryLoader.asyncPrefetchLibrariesToMemory"); return null; } @@ -451,5 +465,9 @@ // Finds the ranges corresponding to the native library pages, forks a new // process to prefetch these pages and waits for it. The new process then // terminates. This is blocking. - private static native boolean nativeForkAndPrefetchNativeLibrary(boolean isColdStart); + private static native boolean nativeForkAndPrefetchNativeLibrary(); + + // Returns the percentage of the native library code page that are currently reseident in + // memory. + private static native int nativePercentageOfResidentNativeLibraryCode(); }
diff --git a/base/android/library_loader/library_loader_hooks.cc b/base/android/library_loader/library_loader_hooks.cc index 240c809..bbc9935 100644 --- a/base/android/library_loader/library_loader_hooks.cc +++ b/base/android/library_loader/library_loader_hooks.cc
@@ -144,9 +144,14 @@ static jboolean ForkAndPrefetchNativeLibrary( JNIEnv* env, - const JavaParamRef<jclass>& clazz, - jboolean is_cold_start) { - return NativeLibraryPrefetcher::ForkAndPrefetchNativeLibrary(is_cold_start); + const JavaParamRef<jclass>& clazz) { + return NativeLibraryPrefetcher::ForkAndPrefetchNativeLibrary(); +} + +static jint PercentageOfResidentNativeLibraryCode( + JNIEnv* env, + const JavaParamRef<jclass>& clazz) { + return NativeLibraryPrefetcher::PercentageOfResidentNativeLibraryCode(); } bool RegisterLibraryLoaderEntryHook(JNIEnv* env) {
diff --git a/base/android/library_loader/library_prefetcher.cc b/base/android/library_loader/library_prefetcher.cc index f62ed6a..c7ec990f0 100644 --- a/base/android/library_loader/library_prefetcher.cc +++ b/base/android/library_loader/library_prefetcher.cc
@@ -14,7 +14,6 @@ #include <vector> #include "base/macros.h" -#include "base/metrics/histogram_macros.h" #include "base/posix/eintr_wrapper.h" #include "base/strings/string_util.h" @@ -121,7 +120,7 @@ } // static -bool NativeLibraryPrefetcher::ForkAndPrefetchNativeLibrary(bool is_cold_start) { +bool NativeLibraryPrefetcher::ForkAndPrefetchNativeLibrary() { // Avoid forking with cygprofile instrumentation because the latter performs // memory allocations. #if defined(CYGPROFILE_INSTRUMENTATION) @@ -137,19 +136,6 @@ if (!FindRanges(&ranges)) return false; - int percentage = PercentageOfResidentCode(ranges); - if (percentage != -1) { - if (is_cold_start) { - UMA_HISTOGRAM_PERCENTAGE( - "LibraryLoader.PercentageOfResidentCodeBeforePrefetch_ColdStartup", - percentage); - } else { - UMA_HISTOGRAM_PERCENTAGE( - "LibraryLoader.PercentageOfResidentCodeBeforePrefetch_WarmStartup", - percentage); - } - } - pid_t pid = fork(); if (pid == 0) { setpriority(PRIO_PROCESS, 0, kBackgroundPriority); @@ -198,5 +184,13 @@ return static_cast<int>((100 * resident_pages) / total_pages); } +// static +int NativeLibraryPrefetcher::PercentageOfResidentNativeLibraryCode() { + std::vector<AddressRange> ranges; + if (!FindRanges(&ranges)) + return -1; + return PercentageOfResidentCode(ranges); +} + } // namespace android } // namespace base
diff --git a/base/android/library_loader/library_prefetcher.h b/base/android/library_loader/library_prefetcher.h index 7ee4260..44a93e6 100644 --- a/base/android/library_loader/library_prefetcher.h +++ b/base/android/library_loader/library_prefetcher.h
@@ -30,7 +30,10 @@ // Finds the ranges matching the native library, forks a low priority // process pre-fetching these ranges and wait()s for it. // Returns true for success. - static bool ForkAndPrefetchNativeLibrary(bool is_cold_start); + static bool ForkAndPrefetchNativeLibrary(); + // Returns the percentage of the native library code currently resident in + // memory, or -1 in case of error. + static int PercentageOfResidentNativeLibraryCode(); private: using AddressRange = std::pair<uintptr_t, uintptr_t>; @@ -44,8 +47,8 @@ // Returns true for success. static bool FindRanges(std::vector<AddressRange>* ranges); - // Returns the percentage of the given address ranges that are currently - // resident in memory, or -1 in case of error. + // Returns the percentage of the given address ranges currently resident in + // memory, or -1 in case of error. static int PercentageOfResidentCode(const std::vector<AddressRange>& ranges); FRIEND_TEST_ALL_PREFIXES(NativeLibraryPrefetcherTest,
diff --git a/base/test/launcher/test_launcher.cc b/base/test/launcher/test_launcher.cc index 6a0c4bdb..d51d786c 100644 --- a/base/test/launcher/test_launcher.cc +++ b/base/test/launcher/test_launcher.cc
@@ -800,14 +800,14 @@ std::vector<std::string> filter_lines = SplitString( filter, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); - for (size_t i = 0; i < filter_lines.size(); i++) { - if (filter_lines[i].empty()) + for (const std::string& filter_line : filter_lines) { + if (filter_line.empty() || filter_line[0] == '#') continue; - if (filter_lines[i][0] == '-') - negative_test_filter_.push_back(filter_lines[i].substr(1)); + if (filter_line[0] == '-') + negative_test_filter_.push_back(filter_line.substr(1)); else - positive_test_filter_.push_back(filter_lines[i]); + positive_test_filter_.push_back(filter_line); } } else { // Split --gtest_filter at '-', if there is one, to separate into
diff --git a/base/third_party/libevent/BUILD.gn b/base/third_party/libevent/BUILD.gn index 61be1d78..67e326d 100644 --- a/base/third_party/libevent/BUILD.gn +++ b/base/third_party/libevent/BUILD.gn
@@ -29,7 +29,6 @@ } else if (is_linux) { sources += [ "epoll.c" ] include_dirs = [ "linux" ] - libs = [ "rt" ] } else if (is_android) { sources += [ "epoll.c" ] include_dirs = [ "android" ]
diff --git a/build/android/devil/android/device_utils.py b/build/android/devil/android/device_utils.py index 2c77203..e522740e3 100644 --- a/build/android/devil/android/device_utils.py +++ b/build/android/devil/android/device_utils.py
@@ -1121,6 +1121,7 @@ missing_dirs = [] cache_commit_funcs = [] for h, d in host_device_tuples: + assert os.path.isabs(h) and posixpath.isabs(d) changed_files, up_to_date_files, stale_files, cache_commit_func = ( self._GetChangedAndStaleFiles(h, d, delete_device_stale)) all_changed_files += changed_files
diff --git a/build/android/devil/android/logcat_monitor.py b/build/android/devil/android/logcat_monitor.py index 71f0d24..56cac8d 100644 --- a/build/android/devil/android/logcat_monitor.py +++ b/build/android/devil/android/logcat_monitor.py
@@ -151,7 +151,9 @@ until |StopRecording| is called. """ def record_to_file(): - with open(self._record_file.name, 'a') as f: + # Write the log with line buffering so the consumer sees each individual + # line. + with open(self._record_file.name, 'a', 1) as f: for data in self._adb.Logcat(filter_specs=self._filter_specs, logcat_format='threadtime'): if self._stop_recording_event.isSet():
diff --git a/build/android/devil/android/logcat_monitor_test.py b/build/android/devil/android/logcat_monitor_test.py index 19dbd75c8..ffd798b 100755 --- a/build/android/devil/android/logcat_monitor_test.py +++ b/build/android/devil/android/logcat_monitor_test.py
@@ -6,6 +6,7 @@ # pylint: disable=protected-access import itertools +import threading import unittest from devil import devil_env @@ -86,6 +87,31 @@ test_log.Close() @mock.patch('time.sleep', mock.Mock()) + def testWaitFor_buffering(self): + # Simulate an adb log stream which does not complete until the test tells it + # to. This checks that the log matcher can receive individual lines from the + # log reader thread even if adb is not producing enough output to fill an + # entire file io buffer. + finished_lock = threading.Lock() + finished_lock.acquire() + + def LogGenerator(): + for line in type(self)._TEST_THREADTIME_LOGCAT_DATA: + yield line + finished_lock.acquire() + + test_adb = adb_wrapper.AdbWrapper('0123456789abcdef') + test_adb.Logcat = mock.Mock(return_value=LogGenerator()) + test_log = logcat_monitor.LogcatMonitor(test_adb, clear=False) + test_log.Start() + + actual_match = test_log.WaitFor(r'.*last line.*', None) + finished_lock.release() + self.assertTrue(actual_match) + test_log.Stop() + test_log.Close() + + @mock.patch('time.sleep', mock.Mock()) def testFindAll_defaults(self): test_log = _CreateTestLog( raw_logcat=type(self)._TEST_THREADTIME_LOGCAT_DATA)
diff --git a/build/android/gyp/create_device_library_links.py b/build/android/gyp/create_device_library_links.py index 6b0b24d7..0fcd176 100755 --- a/build/android/gyp/create_device_library_links.py +++ b/build/android/gyp/create_device_library_links.py
@@ -66,7 +66,7 @@ mkdir_cmd = ('if [ ! -e %(dir)s ]; then mkdir -p %(dir)s; fi ' % { 'dir': device_dir }) RunShellCommand(device, mkdir_cmd) - device.PushChangedFiles([(options.script_host_path, + device.PushChangedFiles([(os.path.abspath(options.script_host_path), options.script_device_path)]) trigger_cmd = (
diff --git a/build/android/gyp/push_libraries.py b/build/android/gyp/push_libraries.py index 452b873b..e1a01d7d 100755 --- a/build/android/gyp/push_libraries.py +++ b/build/android/gyp/push_libraries.py
@@ -41,7 +41,7 @@ if needs_directory: device.RunShellCommand('mkdir -p ' + options.device_dir) needs_directory[:] = [] # = False - device.PushChangedFiles([(host_path, device_path)]) + device.PushChangedFiles([(os.path.abspath(host_path), device_path)]) record_path = '%s.%s.push.md5.stamp' % (host_path, serial_number) md5_check.CallAndRecordIfStale(
diff --git a/build/common.gypi b/build/common.gypi index dbb7669..e8c7b16 100644 --- a/build/common.gypi +++ b/build/common.gypi
@@ -1943,18 +1943,16 @@ # based on mac_sdk_min will be bypassed entirely. 'conditions': [ ['OS=="ios"', { - 'mac_sdk_min%': '10.8', # The iOS build can use Xcode's clang, and that will complain # about -stdlib=libc++ if the deployment target is not at least # 10.7. 'mac_deployment_target%': '10.7', }, { # else OS!="ios" - 'mac_sdk_min%': '10.10', 'mac_deployment_target%': '10.6', }], ], + 'mac_sdk_min': '10.10', 'mac_sdk_path%': '', - }, 'mac_sdk_min': '<(mac_sdk_min)',
diff --git a/build/config/BUILD.gn b/build/config/BUILD.gn index 195293b..2fde9041f 100644 --- a/build/config/BUILD.gn +++ b/build/config/BUILD.gn
@@ -388,7 +388,10 @@ "Foundation.framework", ] } else if (is_linux) { - libs = [ "dl" ] + libs = [ + "dl", + "rt", + ] } }
diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h index 16a1bb9d..91e34668 100644 --- a/cc/trees/layer_tree_impl.h +++ b/cc/trees/layer_tree_impl.h
@@ -138,7 +138,9 @@ void PushPropertiesTo(LayerTreeImpl* tree_impl); - struct CC_EXPORT ElementLayers { + // TODO(thakis): Consider marking this CC_EXPORT once we understand + // http://crbug.com/575700 better. + struct ElementLayers { // Transform and opacity mutations apply to this layer. LayerImpl* main = nullptr; // Scroll mutations apply to this layer.
diff --git a/chrome/android/java/res/layout/web_notification.xml b/chrome/android/java/res/layout/web_notification.xml index 9036d2e..3c9c33f 100644 --- a/chrome/android/java/res/layout/web_notification.xml +++ b/chrome/android/java/res/layout/web_notification.xml
@@ -42,19 +42,40 @@ android:singleLine="true" style="@style/WebNotificationTime"/> - <TextView - android:id="@+id/body" - android:layout_width="wrap_content" + <RelativeLayout + android:id="@+id/body_container" + android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_toEndOf="@id/icon_frame" - android:layout_alignParentEnd="true" android:layout_below="@id/title" + android:layout_toEndOf="@id/icon_frame" android:layout_marginBottom="-4dp" - android:layout_marginEnd="8dp" - android:layout_marginTop="-4dp" - android:singleLine="true" - android:ellipsize="end" - style="@style/WebNotificationBody"/> + android:layout_marginTop="-4dp"> + + <TextView + android:id="@+id/body" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentStart="true" + android:layout_alignParentTop="true" + android:layout_toStartOf="@+id/work_profile_badge" + android:layout_marginEnd="8dp" + android:singleLine="true" + android:ellipsize="end" + style="@style/WebNotificationBody"/> + + <ImageView + android:id="@id/work_profile_badge" + android:layout_width="16dp" + android:layout_height="16dp" + android:layout_marginEnd="8dp" + android:layout_alignParentEnd="true" + android:layout_alignParentTop="true" + android:layout_marginTop="1dp" + android:scaleType="centerInside" + android:contentDescription="@string/notification_work_profile_badge_content_description" + android:visibility="gone"/> + + </RelativeLayout> <TextView android:id="@+id/origin" @@ -62,7 +83,7 @@ android:layout_height="wrap_content" android:layout_toEndOf="@id/icon_frame" android:layout_toStartOf="@+id/small_icon_footer" - android:layout_below="@id/body" + android:layout_below="@id/body_container" android:layout_marginEnd="8dp" android:singleLine="true" android:ellipsize="start" @@ -76,6 +97,6 @@ android:layout_height="16dp" android:layout_marginEnd="8dp" android:layout_alignParentEnd="true" - android:layout_below="@id/body"/> + android:layout_below="@id/body_container"/> </RelativeLayout>
diff --git a/chrome/android/java/res/layout/web_notification_big.xml b/chrome/android/java/res/layout/web_notification_big.xml index 69ace43..f02f716 100644 --- a/chrome/android/java/res/layout/web_notification_big.xml +++ b/chrome/android/java/res/layout/web_notification_big.xml
@@ -68,15 +68,37 @@ </RelativeLayout> - <TextView - android:id="@+id/body" - android:layout_width="wrap_content" + <RelativeLayout + android:id="@+id/body_container" + android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginBottom="5dp" - android:layout_marginEnd="8dp" - android:layout_marginTop="-2dp" - android:ellipsize="end" - style="@style/WebNotificationBodyBig"/> + android:layout_marginTop="-4dp" + android:layout_marginBottom="5dp"> + + <TextView + android:id="@+id/body" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginEnd="8dp" + android:layout_alignParentStart="true" + android:layout_alignParentTop="true" + android:layout_toStartOf="@+id/work_profile_badge" + android:ellipsize="end" + style="@style/WebNotificationBodyBig"/> + + <ImageView + android:id="@id/work_profile_badge" + android:layout_width="16dp" + android:layout_height="16dp" + android:layout_marginEnd="8dp" + android:layout_alignParentEnd="true" + android:layout_alignParentTop="true" + android:layout_marginTop="1dp" + android:scaleType="centerInside" + android:contentDescription="@string/notification_work_profile_badge_content_description" + android:visibility="gone"/> + + </RelativeLayout> <ImageView android:id="@+id/button_divider"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java index e687991..c77f390 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -87,7 +87,6 @@ import org.chromium.chrome.browser.metrics.LaunchMetrics; import org.chromium.chrome.browser.metrics.StartupMetrics; import org.chromium.chrome.browser.metrics.UmaSessionStats; -import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; import org.chromium.chrome.browser.nfc.BeamController; import org.chromium.chrome.browser.nfc.BeamProvider; import org.chromium.chrome.browser.offlinepages.OfflinePageUtils; @@ -100,14 +99,11 @@ import org.chromium.chrome.browser.printing.TabPrinter; import org.chromium.chrome.browser.share.ShareHelper; import org.chromium.chrome.browser.snackbar.DataUseSnackbarController; -import org.chromium.chrome.browser.snackbar.LoFiBarPopupController; import org.chromium.chrome.browser.snackbar.SnackbarManager; import org.chromium.chrome.browser.snackbar.SnackbarManager.SnackbarManageable; import org.chromium.chrome.browser.sync.ProfileSyncService; import org.chromium.chrome.browser.sync.SyncController; -import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tab.TabObserver; import org.chromium.chrome.browser.tabmodel.ChromeTabCreator; import org.chromium.chrome.browser.tabmodel.EmptyTabModel; import org.chromium.chrome.browser.tabmodel.TabCreatorManager; @@ -211,7 +207,6 @@ private ContextualSearchManager mContextualSearchManager; private ReaderModeManager mReaderModeManager; private SnackbarManager mSnackbarManager; - private LoFiBarPopupController mLoFiBarPopupController; private DataUseSnackbarController mDataUseSnackbarController; private AppMenuPropertiesDelegate mAppMenuPropertiesDelegate; private AppMenuHandler mAppMenuHandler; @@ -259,7 +254,6 @@ .createActivityWindowAndroid(this); mWindowAndroid.restoreInstanceState(getSavedInstanceState()); mSnackbarManager = new SnackbarManager(getWindow()); - mLoFiBarPopupController = new LoFiBarPopupController(this, getSnackbarManager()); mDataUseSnackbarController = new DataUseSnackbarController(this, getSnackbarManager()); mAssistStatusHandler = createAssistStatusHandler(); @@ -478,24 +472,6 @@ && DataUseTabUIManager.checkAndResetDataUseTrackingEnded(tab)) { mDataUseSnackbarController.showDataUseTrackingEndedBar(); } - - if (!tab.isNativePage() && !tab.isIncognito() - && DataReductionProxySettings.getInstance().wasLoFiModeActiveOnMainFrame() - && DataReductionProxySettings.getInstance().canUseDataReductionProxy( - tab.getUrl())) { - if (tab.isHidden()) { - TabObserver tabObserver = new EmptyTabObserver() { - @Override - public void onShown(Tab tab) { - mLoFiBarPopupController.showLoFiBar(tab); - tab.removeObserver(this); - } - }; - tab.addObserver(tabObserver); - return; - } - mLoFiBarPopupController.showLoFiBar(tab); - } } @Override @@ -505,13 +481,11 @@ @Override public void onHidden(Tab tab) { - mLoFiBarPopupController.dismissLoFiBar(); mDataUseSnackbarController.dismissDataUseBar(); } @Override public void onDestroyed(Tab tab) { - mLoFiBarPopupController.dismissLoFiBar(); mDataUseSnackbarController.dismissDataUseBar(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java index 33d93e4..66bafe3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java
@@ -35,6 +35,7 @@ import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.SuppressFBWarnings; import org.chromium.base.library_loader.LibraryLoader; +import org.chromium.base.library_loader.LibraryProcessType; import org.chromium.base.library_loader.ProcessInitException; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeApplication; @@ -162,6 +163,16 @@ private static void initializeBrowser(final Application app) { ThreadUtils.assertOnUiThread(); try { + // Loading the native library may spuriously trigger StrictMode violations when + // running instrumentation tests. This does not happen if full Chrome has + // started before reaching this point. + // crbug.com/574532 + if (!LibraryLoader.isInitialized()) { + StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); + LibraryLoader.get(LibraryProcessType.PROCESS_BROWSER) + .ensureInitialized(app.getApplicationContext()); + StrictMode.setThreadPolicy(oldPolicy); + } ChromeBrowserInitializer.getInstance(app).handleSynchronousStartup(); } catch (ProcessInitException e) { Log.e(TAG, "ProcessInitException while starting the browser process."); @@ -204,21 +215,7 @@ ThreadUtils.postOnUiThread(new Runnable() { @Override public void run() { - if (!initialized) { - // Loading the native library may spuriously trigger StrictMode violations when - // running instrumentation tests. This does not happen if full Chrome has - // started before reaching this point. - // crbug.com/574532 - StrictMode.ThreadPolicy oldPolicy = null; - if (!LibraryLoader.isInitialized()) { - oldPolicy = StrictMode.allowThreadDiskReads(); - } - try { - initializeBrowser(mApplication); - } finally { - if (oldPolicy != null) StrictMode.setThreadPolicy(oldPolicy); - } - } + if (!initialized) initializeBrowser(mApplication); if (mayCreateSpareWebContents && mPrerender == null && !SysUtils.isLowEndDevice()) { createSpareWebContents(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkPromoHeader.java b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkPromoHeader.java index 3b0e3b77..c4e39e8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkPromoHeader.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkPromoHeader.java
@@ -72,6 +72,7 @@ PreferenceManager.getDefaultSharedPreferences(mContext).edit() .putInt(PREF_SIGNIN_PROMO_SHOW_COUNT, promoShowCount).apply(); RecordUserAction.record("Stars_SignInPromoHeader_Displayed"); + RecordUserAction.record("Signin_Impression_FromBookmarkManager"); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkSigninActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkSigninActivity.java index 2d0618d..7912bd04 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkSigninActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/enhancedbookmarks/EnhancedBookmarkSigninActivity.java
@@ -120,11 +120,13 @@ @Override public void onAccountSelectionConfirmed() { RecordUserAction.record("Stars_SignInPromoActivity_SignedIn"); + RecordUserAction.record("Signin_Signin_FromBookmarkManager"); } @Override public void onNewAccount() { RecordUserAction.record("Stars_SignInPromoActivity_NewAccount"); + RecordUserAction.record("Signin_AddAccountToDevice"); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java index 4d69d08..03187835 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
@@ -306,6 +306,7 @@ @Override public void onSigninDialogShown() { RecordUserAction.record("MobileFre.SignInShown"); + RecordUserAction.record("Signin_Impression_FromStartPage"); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunSignInProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunSignInProcessor.java index 888505c0..6ba26366 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunSignInProcessor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunSignInProcessor.java
@@ -15,6 +15,7 @@ import org.chromium.base.CommandLine; import org.chromium.base.Log; import org.chromium.base.VisibleForTesting; +import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.preferences.Preferences; import org.chromium.chrome.browser.preferences.PreferencesLauncher; @@ -91,6 +92,7 @@ } final boolean setUpSync = getFirstRunFlowSignInSetupSync(activity); + RecordUserAction.record("Signin_Signin_FromStartPage"); signinManager.signInToSelectedAccount(activity, account, SigninManager.SIGNIN_TYPE_INTERACTIVE, new SignInFlowObserver() { private void completeSignIn() { @@ -103,6 +105,7 @@ @Override public void onSigninComplete() { + RecordUserAction.record("Signin_Signin_Succeed"); completeSignIn(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilder.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilder.java index c394cec..0c5e0d004 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilder.java
@@ -10,6 +10,8 @@ import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; import android.os.Build; import android.support.v4.app.NotificationCompat; import android.support.v4.app.NotificationCompat.Action; @@ -19,6 +21,7 @@ import android.view.View; import android.widget.RemoteViews; +import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R; import org.chromium.ui.base.LocalizationUtils; @@ -76,6 +79,11 @@ private static final int BUTTON_ICON_PADDING_DP = 8; /** + * The size of the work profile badge (width and height). + */ + private static final int WORK_PROFILE_BADGE_SIZE_DP = 16; + + /** * Material Grey 600 - to be applied to action button icons in the Material theme. */ private static final int BUTTON_ICON_COLOR_MATERIAL = 0xff757575; @@ -128,7 +136,8 @@ view.setTextViewText(R.id.origin, mOrigin); view.setImageViewBitmap(R.id.icon, mLargeIcon); view.setViewPadding(R.id.title, 0, scaledPadding, 0, 0); - view.setViewPadding(R.id.body, 0, scaledPadding, 0, scaledPadding); + view.setViewPadding(R.id.body_container, 0, scaledPadding, 0, scaledPadding); + addWorkProfileBadge(view); } addActionButtons(bigView); @@ -281,6 +290,31 @@ } } + /** + * Shows the work profile badge if it is needed. + */ + private void addWorkProfileBadge(RemoteViews view) { + Resources resources = mContext.getResources(); + DisplayMetrics metrics = resources.getDisplayMetrics(); + int size = dpToPx(WORK_PROFILE_BADGE_SIZE_DP, metrics); + int[] colors = new int[size * size]; + + // Create an immutable bitmap, so that it can not be reused for painting a badge into it. + Bitmap bitmap = Bitmap.createBitmap(colors, size, size, Bitmap.Config.ARGB_8888); + + Drawable inputDrawable = new BitmapDrawable(resources, bitmap); + Drawable outputDrawable = ApiCompatibilityUtils.getUserBadgedDrawableForDensity( + mContext, inputDrawable, null /* badgeLocation */, metrics.densityDpi); + + // The input bitmap is immutable, so the output drawable will be a different instance from + // the input drawable if the work profile badge was applied. + if (inputDrawable != outputDrawable && outputDrawable instanceof BitmapDrawable) { + view.setImageViewBitmap( + R.id.work_profile_badge, ((BitmapDrawable) outputDrawable).getBitmap()); + view.setViewVisibility(R.id.work_profile_badge, View.VISIBLE); + } + } + @Nullable private static CharSequence limitLength(@Nullable CharSequence input) { if (input == null) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java index 6040b59..2b70b63 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsRowAdapter.java
@@ -21,11 +21,13 @@ import android.widget.TextView; import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.R; import org.chromium.chrome.browser.favicon.FaviconHelper.FaviconImageCallback; import org.chromium.chrome.browser.ntp.ForeignSessionHelper.ForeignSession; import org.chromium.chrome.browser.ntp.ForeignSessionHelper.ForeignSessionTab; import org.chromium.chrome.browser.ntp.ForeignSessionHelper.ForeignSessionWindow; +import org.chromium.chrome.browser.ntp.RecentTabsPromoView.UserActionListener; import org.chromium.chrome.browser.ntp.RecentlyClosedBridge.RecentlyClosedTab; import org.chromium.ui.WindowOpenDisposition; import org.chromium.ui.base.DeviceFormFactor; @@ -591,7 +593,20 @@ View getChildView(int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { if (convertView == null) { - convertView = new RecentTabsPromoView(mActivity, mRecentTabsManager, null); + convertView = new RecentTabsPromoView( + mActivity, mRecentTabsManager, new UserActionListener() { + @Override + public void onAccountSelectionConfirmed() { + RecordUserAction.record("Signin_Signin_FromRecentTabs"); + } + @Override + public void onNewAccount() { + RecordUserAction.record("Signin_AddAccountToDevice"); + } + }); + } + if (!mRecentTabsManager.isSignedIn()) { + RecordUserAction.record("Signin_Impression_FromRecentTabs"); } return convertView; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/MainPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/MainPreferences.java index 6e32fd5..76a086a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/MainPreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/MainPreferences.java
@@ -14,6 +14,7 @@ import org.chromium.base.Callback; import org.chromium.base.VisibleForTesting; +import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.R; import org.chromium.chrome.browser.PasswordUIView; import org.chromium.chrome.browser.autofill.PersonalDataManager; @@ -207,6 +208,7 @@ dialog.setListener(new AddGoogleAccountListener() { @Override public void onAddAccountClicked() { + RecordUserAction.record("Signin_AddAccountToDevice"); AccountAdder.getInstance().addAccount( MainPreferences.this, AccountAdder.ADD_ACCOUNT_RESULT); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoScreen.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoScreen.java index c1740ddd..8fff265 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoScreen.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoScreen.java
@@ -13,6 +13,7 @@ import android.view.View; import android.widget.LinearLayout; +import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.R; import org.chromium.chrome.browser.firstrun.AccountFirstRunView; import org.chromium.chrome.browser.firstrun.ProfileDataCache; @@ -89,6 +90,7 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); SigninPromoUma.recordAction(SigninPromoUma.SIGNIN_PROMO_SHOWN); + RecordUserAction.record("Signin_Impression_FromSigninPromo"); } @Override @@ -108,6 +110,7 @@ mAccountFirstRunView.switchToSignedMode(); SigninManager.get(getOwnerActivity()).logInSignedInUser(); SigninPromoUma.recordAction(SigninPromoUma.SIGNIN_PROMO_ACCEPTED); + RecordUserAction.record("Signin_Signin_Succeed"); } @Override @@ -116,6 +119,7 @@ dismiss(); } }; + RecordUserAction.record("Signin_Signin_FromSigninPromo"); SigninManager.get(getOwnerActivity().getApplicationContext()) .signInToSelectedAccount(getOwnerActivity(), account, SigninManager.SIGNIN_TYPE_INTERACTIVE, signInCallback);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/LoFiBarPopupController.java b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/LoFiBarPopupController.java index 3afad97..7b2c003 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/LoFiBarPopupController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/LoFiBarPopupController.java
@@ -11,7 +11,9 @@ import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; import org.chromium.chrome.browser.preferences.datareduction.DataReductionProxyUma; +import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabObserver; /** * Each time a tab loads with Lo-Fi this controller saves that tab id and title to the stack of @@ -26,6 +28,7 @@ private final Context mContext; private final boolean mDisabled; private Tab mTab; + private boolean mLoFiPopupShownForPageLoad = false; /** * Creates an instance of a {@link LoFiBarPopupController}. @@ -39,9 +42,50 @@ } /** + * Called on new page loads to indicate that a Lo-Fi snackbar has not been shown yet. + */ + public void resetLoFiPopupShownForPageLoad() { + mLoFiPopupShownForPageLoad = false; + } + + /** + * If a Lo-Fi snackbar has not been shown for the current page load, creates a Lo-Fi snackbar + * for the given tab and shows it. If the tab is hidden, waits until it is visible to show the + * snackbar. + * + * @param tab The tab to show the snackbar on. + */ + public void maybeCreateLoFiBar(Tab tab) { + if (mLoFiPopupShownForPageLoad) return; + mLoFiPopupShownForPageLoad = true; + if (tab.isHidden()) { + TabObserver tabObserver = new EmptyTabObserver() { + @Override + public void onShown(Tab tab) { + showLoFiBar(tab); + tab.removeObserver(this); + } + + @Override + public void onHidden(Tab tab) { + dismissLoFiBar(); + } + + @Override + public void onDestroyed(Tab tab) { + dismissLoFiBar(); + } + }; + tab.addObserver(tabObserver); + return; + } + showLoFiBar(tab); + } + + /** * @param tab The tab. Saved to reload the page. */ - public void showLoFiBar(Tab tab) { + private void showLoFiBar(Tab tab) { if (mDisabled) return; mTab = tab; mSnackbarManager.showSnackbar(Snackbar.make( @@ -57,7 +101,7 @@ /** * Dismisses the snackbar. */ - public void dismissLoFiBar() { + private void dismissLoFiBar() { if (mSnackbarManager.isShowing()) mSnackbarManager.dismissSnackbars(this); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/ChooseAccountFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/ChooseAccountFragment.java index c6bc48e1..732f36d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/ChooseAccountFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/ChooseAccountFragment.java
@@ -11,6 +11,7 @@ import android.os.Bundle; import android.support.v7.app.AlertDialog; +import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.R; import java.util.List; @@ -39,6 +40,7 @@ } protected void selectAccount(final String account) { + RecordUserAction.record("Signin_Signin_FromSettings"); ConfirmAccountChangeFragment.confirmSyncAccount(account, getActivity()); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/ConfirmAccountChangeFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/ConfirmAccountChangeFragment.java index cfe67e03..140a2e49 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/ConfirmAccountChangeFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/ConfirmAccountChangeFragment.java
@@ -19,9 +19,11 @@ import android.widget.TextView; import org.chromium.base.Callback; +import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.R; import org.chromium.chrome.browser.preferences.PrefServiceBridge; import org.chromium.chrome.browser.signin.SigninManager; +import org.chromium.chrome.browser.signin.SigninManager.SignInFlowObserver; import org.chromium.sync.signin.AccountManagerHelper; import org.chromium.ui.text.SpanApplier; import org.chromium.ui.text.SpanApplier.SpanInfo; @@ -83,6 +85,7 @@ } })); + RecordUserAction.record("Signin_Show_ImportDataPrompt"); textView.setText(messageWithLink); textView.setMovementMethod(LinkMovementMethod.getInstance()); return new AlertDialog.Builder(getActivity(), R.style.AlertDialogTheme) @@ -95,7 +98,10 @@ @Override public void onClick(DialogInterface dialog, int which) { if (which == AlertDialog.BUTTON_POSITIVE) { + RecordUserAction.record("Signin_ImportDataPrompt_ImportData"); signIn(getActivity(), mAccountName); + } else if (which == AlertDialog.BUTTON_NEGATIVE) { + RecordUserAction.record("Signin_ImportDataPrompt_Cancel"); } } @@ -104,6 +110,7 @@ dialogFragment.show(getFragmentManager(), null); // Dismiss the confirmation dialog. dismiss(); + RecordUserAction.record("Signin_ImportDataPrompt_DontImport"); } private static void signIn(final Activity activity, String accountName) { @@ -113,7 +120,14 @@ public void onResult(Account account) { if (account == null) return; SigninManager.get(activity).signInToSelectedAccount(activity, account, - SigninManager.SIGNIN_TYPE_INTERACTIVE, null); + SigninManager.SIGNIN_TYPE_INTERACTIVE, new SignInFlowObserver() { + @Override + public void onSigninComplete() { + RecordUserAction.record("Signin_Signin_Succeed"); + } + @Override + public void onSigninCancelled() {} + }); } }); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java index a9931a7..93bcd93 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -63,6 +63,7 @@ import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.rlz.RevenueStats; import org.chromium.chrome.browser.search_engines.TemplateUrlService; +import org.chromium.chrome.browser.snackbar.LoFiBarPopupController; import org.chromium.chrome.browser.snackbar.SnackbarManager; import org.chromium.chrome.browser.ssl.ConnectionSecurityLevel; import org.chromium.chrome.browser.ssl.SecurityStateModel; @@ -360,6 +361,8 @@ protected Handler mHandler; + private LoFiBarPopupController mLoFiBarPopupController; + private class TabContentViewClient extends ContentViewClient { @Override public void onBackgroundColorChanged(int color) { @@ -553,6 +556,9 @@ activity.getApplicationContext(), ChromeActivity.getThemeId()) : null; mWindowAndroid = window; mLaunchType = type; + if (mActivity != null) { + mLoFiBarPopupController = new LoFiBarPopupController(activity, getSnackbarManager()); + } if (mThemedApplicationContext != null) { Resources resources = mThemedApplicationContext.getResources(); mIdealFaviconSize = resources.getDimensionPixelSize(R.dimen.default_favicon_size); @@ -1413,6 +1419,10 @@ mIsShowingErrorPage = showingErrorPage; + if (mLoFiBarPopupController != null) { + mLoFiBarPopupController.resetLoFiPopupShownForPageLoad(); + } + updateTitle(); removeSadTabIfPresent(); @@ -2581,6 +2591,16 @@ } /** + * If a Lo-Fi snackbar has not been shown yet for this page load, a Lo-Fi snackbar is shown. + */ + @CalledByNative + public void onLoFiResponseReceived() { + if (mLoFiBarPopupController != null) { + mLoFiBarPopupController.maybeCreateLoFiBar(this); + } + } + + /** * Request that this tab receive focus. Currently, this function requests focus for the main * View (usually a ContentView). */
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index 7e24a79..eac7baf0 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -1421,6 +1421,9 @@ <message name="IDS_NOTIFICATION_SITE_SETTINGS_BUTTON" desc="Text of a button shown on notifications, that opens the Site Settings of the website that showed the notification. (If it isn't possible to fit within the char limit, the string will be ellipsized if 3 buttons are shown side by side, so try to ensure that the user can guess the meaning from the first 8 characters). [CHAR-LIMIT=9]"> Settings </message> + <message name="IDS_NOTIFICATION_WORK_PROFILE_BADGE_CONTENT_DESCRIPTION" desc="Content description of the work profile badge in the notification."> + Work profile + </message> <!-- Fullscreen --> <message name="IDS_IMMERSIVE_FULLSCREEN_API_NOTIFICATION" desc="Notification message when a site has entered immersive fullscreen and the directions of how to exit.">
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/overlays/strip/TabStripTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/overlays/strip/TabStripTest.java index 93b69ec5..7b15df9f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/overlays/strip/TabStripTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/overlays/strip/TabStripTest.java
@@ -10,7 +10,6 @@ import android.test.suitebuilder.annotation.LargeTest; import org.chromium.base.ThreadUtils; -import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.Restriction; import org.chromium.chrome.browser.compositor.layouts.components.CompositorButton; @@ -125,13 +124,9 @@ * activates the incognito TabStrip. * @throws InterruptedException */ - /* - * @LargeTest - * @Restriction(RESTRICTION_TYPE_TABLET) - * @Feature({"TabStrip"}) - * Bug crbug.com/258495 - */ - @DisabledTest + @LargeTest + @Restriction(RESTRICTION_TYPE_TABLET) + @Feature({"TabStrip"}) public void testNewIncognitoTabFromMenuAtNormalStrip() throws InterruptedException { getInstrumentation().waitForIdleSync(); assertFalse("Expected normal strip to be selected", @@ -171,23 +166,21 @@ * also check that the visible tab ordering is correct. * @throws InterruptedException */ - /* - * @LargeTest - * @Restriction(RESTRICTION_TYPE_TABLET) - * @Feature({"TabStrip"}) - * Bug crbug.com/258495 - */ - @DisabledTest + @LargeTest + @Restriction(RESTRICTION_TYPE_TABLET) + @Feature({"TabStrip"}) public void testSelectWithManyTabs() throws InterruptedException { ChromeTabUtils.newTabsFromMenu(getInstrumentation(), getActivity(), 4); getInstrumentation().waitForIdleSync(); assertEquals("The last tab is not selected", getActivity().getCurrentTabModel().index(), 4); compareAllTabStripsWithModel(); - selectTab(false, getActivity().getCurrentTabModel().getTabAt(2).getId()); + // Note: if the tab is not visible, this will fail. Currently that's not a problem, because + // the devices we test on are wide enough. + selectTab(false, getActivity().getCurrentTabModel().getTabAt(0).getId()); getInstrumentation().waitForIdleSync(); assertEquals("The middle tab is not selected", - getActivity().getCurrentTabModel().index(), 2); + getActivity().getCurrentTabModel().index(), 0); compareAllTabStripsWithModel(); } @@ -227,8 +220,6 @@ @Restriction(RESTRICTION_TYPE_TABLET) @Feature({"TabStrip"}) public void testCloseTabWithManyTabs() throws InterruptedException { - getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); - ChromeTabUtils.newTabsFromMenu(getInstrumentation(), getActivity(), 4); getInstrumentation().waitForIdleSync(); assertEquals("There are not five tabs present", @@ -236,7 +227,9 @@ assertEquals("The last tab is not selected", getActivity().getCurrentTabModel().index(), 4); int initialSelectedId = getActivity().getActivityTab().getId(); - closeTab(false, getActivity().getCurrentTabModel().getTabAt(2).getId()); + // Note: if the tab is not visible, this will fail. Currently that's not a problem, because + // the devices we test on are wide enough. + closeTab(false, getActivity().getCurrentTabModel().getTabAt(0).getId()); getInstrumentation().waitForIdleSync(); assertEquals("There are not four tabs present", getActivity().getCurrentTabModel().getCount(), 4); @@ -351,13 +344,10 @@ * and normal TabStrips. * @throws InterruptedException */ - /* - * @LargeTest - * @Restriction(RESTRICTION_TYPE_TABLET) - * @Feature({"TabStrip"}) - * Bug crbug.com/258495 - */ - @DisabledTest + + @LargeTest + @Restriction(RESTRICTION_TYPE_TABLET) + @Feature({"TabStrip"}) public void testToggleIncognitoMode() throws InterruptedException { getInstrumentation().waitForIdleSync(); assertFalse("Expected normal strip to be selected",
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 83deca0..f840fb40 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -441,9 +441,6 @@ Did you mean to go to <ph name="SITE">$1<ex>http://intranetsite/</ex></ph>? </message> - <message name="IDS_HISTORY_TITLE" desc="Title for the history tab."> - History - </message> <message name="IDS_DOWNLOAD_TITLE" desc="Title for the downloads tab."> Downloads </message> @@ -454,155 +451,6 @@ Loading... </message> - <message name="IDS_HISTORY_REMOVE_SELECTED_ITEMS" desc="Title of the button that allows the user to remove the selected history items"> - Remove selected items - </message> - <message name="IDS_HISTORY_FILTER_ALLOW_ITEMS" desc="Title of the button that allows the user to allow the selected history items"> - Allow items - </message> - <message name="IDS_HISTORY_FILTER_BLOCK_ITEMS" desc="Title of the button that allows the user to block the selected history items"> - Block items - </message> - <message name="IDS_HISTORY_OPEN_CLEAR_BROWSING_DATA_DIALOG" desc="Title of the button that will open the clear browsing data dialog."> - Clear browsing data... - </message> - <message name="IDS_HISTORY_DELETE_PRIOR_VISITS_CONFIRM_BUTTON" desc="Text for the button used to confirm the dialog asking if they would like to proceed with deletion."> - Remove - </message> - <message name="IDS_HISTORY_DELETE_PRIOR_VISITS_WARNING" desc="Warning shown before deleting visits from the history page (reminding the user they can also use incognito mode, which doesn't store history)"> - Are you sure you want to delete these pages from your history? - -Psst! Incognito mode <ph name="SHORTCUT_KEY">$1<ex>(Ctrl+Shift+N)</ex></ph> may come in handy next time. - </message> - <message name="IDS_HISTORY_DELETE_PRIOR_VISITS_WARNING_NO_INCOGNITO" desc="Warning shown before deleting from the history page"> - Are you sure you want to delete these pages from your history? - </message> - - <!-- History HTML UI --> - <message name="IDS_HISTORY_LOADING" desc="Text shown when we're loading the user's history"> - Loading... - </message> - <message name="IDS_HISTORY_DATE_WITH_RELATIVE_TIME" desc="In the history view, some dates are formatted as 'Today - Wednesday, Nov 7, 2007"> - <ph name="RELATIVE_DATE">$1<ex>Today</ex></ph> - <ph name="FULL_DATE">$2<ex>Wednesday, Nov 7, 2007</ex></ph> - </message> - <message name="IDS_HISTORY_INTERVAL" desc="A history interval shown in the title. The dates are already localized strings."> - <ph name="START_DATE">$1<ex>Wednesday, Aug. 1, 2012</ex></ph> to <ph name="END_DATE">$2<ex>Thursday, Aug. 30, 2012</ex></ph> - </message> - <message name="IDS_HISTORY_NO_SEARCH_RESULTS" desc="Text shown when no history search results have been found"> - No search results found. - </message> - <message name="IDS_HISTORY_NO_RESULTS" desc="Text shown when no history entries are found."> - No history entries found. - </message> - <message name="IDS_HISTORY_SEARCH_BUTTON" desc="Title of the button in the history page that triggers a search"> - Search history - </message> - <message name="IDS_HISTORY_NEWEST" desc="HTML text shown as page navigation tool to take the user to the top of their history"> - Newest - </message> - <message name="IDS_HISTORY_NEWER" desc="HTML text shown as page navigation tool to take the user back to the more recent page"> - Newer - </message> - <message name="IDS_HISTORY_OLDER" desc="HTML text shown as page navigation tool to take the user forward to their older history"> - Older - </message> - <message name="IDS_HISTORY_SEARCHRESULTSFOR" desc="Format string for search results"> - Search results for '<ph name="SEARCH_STRING">$1</ph>' - </message> - <message name="IDS_HISTORY_SEARCH_RESULT" desc="Used when a single result is found."> - search result - </message> - <message name="IDS_HISTORY_SEARCH_RESULTS" desc="Used when plural/multiple results are found."> - search results - </message> - <message name="IDS_HISTORY_FOUND_SEARCH_RESULTS" desc="Message shown when zero or multiple search results are found."> - Found <ph name="NUMBER_OF_RESULTS">$1</ph> <ph name="SEARCH_RESULTS"><ex>search results</ex>$2</ph> for '<ph name="SEARCH_STRING">$3</ph>'. - </message> - <message name="IDS_HISTORY_BROWSERESULTS" desc="Title of browsing results page"> - History - </message> - <message name="IDS_HISTORY_CONTINUED" desc="Shown after the date if the data is continued from the previous page"> - (Cont.) - </message> - <message name="IDS_HISTORY_REMOVE_BOOKMARK" desc="Tooltip shown when hovered over a history entry's bookmark star. When clicked, removes the bookmark."> - Remove bookmark - </message> - <message name="IDS_HISTORY_ACTION_MENU_DESCRIPTION" desc="Text used to identify the history entry drop-down menu for screen readers"> - Actions - </message> - <message name="IDS_HISTORY_REMOVE_PAGE" desc="Command in the history entry drop-down menu. Removes a page from the history."> - Remove from history - </message> - <message name="IDS_HISTORY_MORE_FROM_SITE" desc="Command in the history entry drop-down menu. Shows more history entries from the same site."> - More from this site - </message> - <message name="IDS_GROUP_BY_DOMAIN_LABEL" desc="Label for the checkbox that toggles the mode to group history visits by domain."> - Group domains - </message> - <message name="IDS_HISTORY_RANGE_LABEL" desc="Label for the combo box that selects the time range."> - Show - </message> - <message name="IDS_HISTORY_RANGE_ALL_TIME" desc="Option in the history range button group. Shows results a page at a time, without grouping them by domain."> - All - </message> - <message name="IDS_HISTORY_RANGE_WEEK" desc="Option in the history range button group. Shows results grouped by week."> - Week - </message> - <message name="IDS_HISTORY_RANGE_MONTH" desc="Option in the history range button group. Shows results grouped by month."> - Month - </message> - <message name="IDS_HISTORY_RANGE_TODAY" desc="The text on the button that sets the current time range back to today."> - Today - </message> - <message name="IDS_HISTORY_RANGE_NEXT" desc="The alt text on the button that moves the current time range forward."> - Next - </message> - <message name="IDS_HISTORY_RANGE_PREVIOUS" desc="The alt text on the button that moves the current time range backwards."> - Previous - </message> - <message name="IDS_HISTORY_NUMBER_VISITS" desc="Format string for the number of visits of a site."> - (<ph name="NUMBER_VISITS">$1<ex>3</ex></ph>) - </message> - <message name="IDS_HISTORY_FILTER_ALLOWED" desc="Text that shows that an entry is allowed."> - Allowed - </message> - <message name="IDS_HISTORY_FILTER_BLOCKED" desc="Text that shows that an entry is blocked."> - Blocked - </message> - <message name="IDS_HISTORY_IN_CONTENT_PACK" desc="Text that shows that an entry is in a content pack."> - In content pack - </message> - <message name="IDS_HISTORY_BLOCKED_VISIT_TEXT" desc="Text that describes an attempted visit."> - Blocked attempt <ph name="BEGIN_LINK"><a target="_top" href="$1" id="$2"></ph> to visit a page on <ph name="DOMAIN">$3<ex>google.com</ex></ph><ph name="END_LINK"></a><ex></a></ex></ph>. - </message> - <message name="IDS_HISTORY_HAS_SYNCED_RESULTS" desc="The notification at the top of the history page indicating that it is showing visits synced from other devices."> - Showing history from your signed-in devices. <ph name="BEGIN_LINK"><a href="https://support.google.com/chrome/?p=sync_history&hl=[GRITLANGCODE]"></ph>Learn more<ph name="END_LINK"></a><ex></a></ex></ph> - </message> - <message name="IDS_HISTORY_NO_SYNCED_RESULTS" desc="The notification at the top of the history page indicating that it does not include visits from other devices."> - Showing history from this device. <ph name="BEGIN_LINK"><a href="https://support.google.com/chrome/?p=sync_history&hl=[GRITLANGCODE]"></ph>Learn more<ph name="END_LINK"></a><ex></a></ex></ph> - </message> - <message name="IDS_HISTORY_UNKNOWN_DEVICE" desc="On the dropdown menu for a history entry, the text that is shown instead of a device name, when the device name is not known."> - Unknown device - </message> - <message name="IDS_HISTORY_ENTRY_BOOKMARKED" desc="Whether a history entry is bookmarked."> - Bookmarked - </message> - <message name="IDS_HISTORY_ENTRY_SUMMARY" desc="Summary of all the fields in a history entry (time, whether the entry is bookmarked, title, and domain)."> - <ph name="TIME"><ex>3:14</ex>$1</ph> <ph name="BOOKMARKED"><ex>bookmarked</ex>$2</ph> <ph name="TITLE"><ex>PI: The Magical Number</ex>$3</ph> <ph name="DOMAIN"><ex>pi.com</ex>$4</ph> - </message> - <message name="IDS_HISTORY_OTHER_SESSIONS_OPEN_ALL" desc="In the 'Other Sessions' menu on the history page, the label for the command to open all tabs and windows from a session."> - Open all - </message> - <message name="IDS_HISTORY_OTHER_DEVICES_X_MORE" desc="In the 'Other Sessions' section of the history page, the label for showing that X more tabs are available for a session."> - <ph name="NUM_TABS_MORE">$1<ex>42</ex></ph> more... - </message> - <message name="IDS_HISTORY_OTHER_SESSIONS_COLLAPSE_SESSION" desc="In the 'Other Sessions' menu on the history page, the label for the command to collapse (hide) the list of windows and tabs in a session."> - Collapse list - </message> - <message name="IDS_HISTORY_OTHER_SESSIONS_EXPAND_SESSION" desc="In the 'Other Sessions' menu on the history page, the label for the command to expand (uncollapse) the list of windows and tabs in a session."> - Expand list - </message> - <!-- Generic terms --> <message name="IDS_ADD" desc="Used for Add on buttons"> Add
diff --git a/chrome/app/theme/chromium/mac/app.icns b/chrome/app/theme/chromium/mac/app.icns index 055e46b..6a3143a 100644 --- a/chrome/app/theme/chromium/mac/app.icns +++ b/chrome/app/theme/chromium/mac/app.icns Binary files differ
diff --git a/chrome/app/theme/chromium/mac/document.icns b/chrome/app/theme/chromium/mac/document.icns index 0f458bb..995a3a5c 100644 --- a/chrome/app/theme/chromium/mac/document.icns +++ b/chrome/app/theme/chromium/mac/document.icns Binary files differ
diff --git a/chrome/browser/android/tab_android.cc b/chrome/browser/android/tab_android.cc index b67860c..d98d9b16 100644 --- a/chrome/browser/android/tab_android.cc +++ b/chrome/browser/android/tab_android.cc
@@ -825,6 +825,11 @@ web_contents()->GetController().LoadURLWithParams(load_params); } +void TabAndroid::OnLoFiResponseReceived() { + JNIEnv* env = base::android::AttachCurrentThread(); + Java_Tab_onLoFiResponseReceived(env, weak_java_tab_.get(env).obj()); +} + jboolean TabAndroid::HasOfflineCopy(JNIEnv* env, const JavaParamRef<jobject>& obj) { GURL url = dom_distiller::url_utils::GetOriginalUrlFromDistillerUrl(
diff --git a/chrome/browser/android/tab_android.h b/chrome/browser/android/tab_android.h index fa088e3..db2d1c3 100644 --- a/chrome/browser/android/tab_android.h +++ b/chrome/browser/android/tab_android.h
@@ -128,6 +128,8 @@ void ShowOfflinePages(); void LoadOfflineCopy(const GURL& url); + void OnLoFiResponseReceived(); + // Overridden from CoreTabHelperDelegate: void SwapTabContents(content::WebContents* old_contents, content::WebContents* new_contents,
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index ffbd2ad..b7986bf8 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc
@@ -794,6 +794,9 @@ // Record collected startup metrics. startup_metric_utils::RecordBrowserMainMessageLoopStart( base::TimeTicks::Now(), is_first_run); + + startup_metric_utils::RecordTimeSinceLastStartup( + g_browser_process->local_state()); } // -----------------------------------------------------------------------------
diff --git a/chrome/browser/extensions/api/messaging/extension_message_port.cc b/chrome/browser/extensions/api/messaging/extension_message_port.cc index a22568f9..5015246 100644 --- a/chrome/browser/extensions/api/messaging/extension_message_port.cc +++ b/chrome/browser/extensions/api/messaging/extension_message_port.cc
@@ -200,7 +200,12 @@ } void ExtensionMessagePort::RegisterFrame(content::RenderFrameHost* rfh) { - frames_.insert(rfh); + // Only register a RenderFrameHost whose RenderFrame has been created, to + // ensure that we are notified of frame destruction. Without this check, + // |frames_| can eventually contain a stale pointer because RenderFrameDeleted + // is not triggered for |rfh|. + if (rfh->IsRenderFrameLive()) + frames_.insert(rfh); } void ExtensionMessagePort::UnregisterFrame(content::RenderFrameHost* rfh) {
diff --git a/chrome/browser/extensions/api/messaging/message_service.cc b/chrome/browser/extensions/api/messaging/message_service.cc index e936b7d..11ec6922 100644 --- a/chrome/browser/extensions/api/messaging/message_service.cc +++ b/chrome/browser/extensions/api/messaging/message_service.cc
@@ -440,6 +440,8 @@ new ExtensionMessagePort(weak_factory_.GetWeakPtr(), GET_OPPOSITE_PORT_ID(receiver_port_id), source_extension_id, source, false)); + if (!channel->opener->IsValidPort()) + return; // Get handle of the native view and pass it to the native messaging host. gfx::NativeView native_view = source ? source->GetNativeView() : nullptr; @@ -560,11 +562,15 @@ return; } - MessageChannel* channel(new MessageChannel); - channel->opener.reset( + scoped_ptr<MessagePort> opener( new ExtensionMessagePort(weak_factory_.GetWeakPtr(), GET_OPPOSITE_PORT_ID(params->receiver_port_id), params->source_extension_id, source, false)); + if (!opener->IsValidPort()) + return; + + MessageChannel* channel(new MessageChannel()); + channel->opener.reset(opener.release()); channel->receiver.reset(params->receiver.release()); AddChannel(channel, params->receiver_port_id); @@ -976,6 +982,8 @@ ExtensionMessagePort port(weak_factory_.GetWeakPtr(), GET_OPPOSITE_PORT_ID(port_id), "", source, false); + if (!port.IsValidPort()) + return; port.DispatchOnDisconnect(error_message); }
diff --git a/chrome/browser/first_run/first_run.cc b/chrome/browser/first_run/first_run.cc index c46651ae..61874cf 100644 --- a/chrome/browser/first_run/first_run.cc +++ b/chrome/browser/first_run/first_run.cc
@@ -282,15 +282,18 @@ int items_to_import) { const importer::SourceProfile& source_profile = importer_list->GetSourceProfileAt(0); + // If no items to import then skip entirely. + if (!items_to_import) + return; // Ensure that importers aren't requested to import items that they do not // support. If there is no overlap, skip. items_to_import &= source_profile.services_supported; - if (items_to_import == 0) - return; + if (items_to_import) { + ImportFromSourceProfile(importer_host, source_profile, profile, + items_to_import); + } - ImportFromSourceProfile(importer_host, source_profile, profile, - items_to_import); g_auto_import_state |= first_run::AUTO_IMPORT_PROFILE_IMPORTED; }
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_io_data.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_io_data.cc index ed1449a4..def66ab 100644 --- a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_io_data.cc +++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_io_data.cc
@@ -6,19 +6,24 @@ #include <utility> +#include "base/bind.h" #include "base/prefs/pref_service.h" #include "build/build_config.h" #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h" #include "chrome/common/chrome_content_client.h" #include "chrome/common/pref_names.h" #include "components/data_reduction_proxy/content/browser/content_lofi_decider.h" +#include "components/data_reduction_proxy/content/browser/content_lofi_ui_service.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config_retrieval_params.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_experiments_stats.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/web_contents.h" #if defined(OS_ANDROID) #include "base/android/build_info.h" +#include "chrome/browser/android/tab_android.h" #endif #if defined(ENABLE_DATA_REDUCTION_PROXY_DEBUGGING) @@ -33,6 +38,22 @@ using data_reduction_proxy::DataReductionProxyParams; +namespace { + +// For Android builds, notifies the TabAndroid associated with |web_contents| +// that a Lo-Fi response has been received. The TabAndroid then handles showing +// Lo-Fi UI if this is the first Lo-Fi response for a page load. +void OnLoFiResponseReceivedOnUI(content::WebContents* web_contents) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); +#if defined(OS_ANDROID) + TabAndroid* tab = TabAndroid::FromWebContents(web_contents); + if (tab) + tab->OnLoFiResponseReceived(); +#endif +} + +} // namespace + scoped_ptr<data_reduction_proxy::DataReductionProxyIOData> CreateDataReductionProxyChromeIOData( net::NetLog* net_log, @@ -71,6 +92,10 @@ data_reduction_proxy_io_data->set_lofi_decider( make_scoped_ptr(new data_reduction_proxy::ContentLoFiDecider())); + data_reduction_proxy_io_data->set_lofi_ui_service( + make_scoped_ptr(new data_reduction_proxy::ContentLoFiUIService( + ui_task_runner, + base::Bind(&OnLoFiResponseReceivedOnUI)))); #if defined(ENABLE_DATA_REDUCTION_PROXY_DEBUGGING) scoped_ptr<data_reduction_proxy::ContentDataReductionProxyDebugUIService>
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index 8847e775..a3c3aeb 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -84,6 +84,7 @@ #include "components/rappor/rappor_service.h" #include "components/search_engines/template_url_prepopulate_data.h" #include "components/ssl_config/ssl_config_service_manager.h" +#include "components/startup_metric_utils/browser/startup_metric_utils.h" #include "components/sync_driver/sync_prefs.h" #include "components/syncable_prefs/pref_service_syncable.h" #include "components/translate/core/browser/translate_prefs.h" @@ -275,6 +276,7 @@ RegisterScreenshotPrefs(registry); SigninManagerFactory::RegisterPrefs(registry); ssl_config::SSLConfigServiceManager::RegisterPrefs(registry); + startup_metric_utils::RegisterPrefs(registry); web_resource::PromoResourceService::RegisterPrefs(registry); #if defined(ENABLE_AUTOFILL_DIALOG)
diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc index d078088..07666557 100644 --- a/chrome/browser/profiles/profile.cc +++ b/chrome/browser/profiles/profile.cc
@@ -150,6 +150,13 @@ #if defined(OS_ANDROID) registry->RegisterBooleanPref(prefs::kClickedUpdateMenuItem, false); #endif + +#if defined(ENABLE_MEDIA_ROUTER) + registry->RegisterBooleanPref( + prefs::kMediaRouterFirstRunFlowAcknowledged, + false, + user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); +#endif } std::string Profile::GetDebugName() {
diff --git a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc index 95186d9..a7fbe76 100644 --- a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc +++ b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc
@@ -219,13 +219,12 @@ void LaunchURL( const GURL& url, int render_process_id, - int render_view_id, + const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter, ui::PageTransition page_transition, bool has_user_gesture) { // If there is no longer a WebContents, the request may have raced with tab // closing. Don't fire the external request. (It may have been a prerender.) - content::WebContents* web_contents = - tab_util::GetWebContentsByID(render_process_id, render_view_id); + content::WebContents* web_contents = web_contents_getter.Run(); if (!web_contents) return; @@ -239,12 +238,8 @@ } ExternalProtocolHandler::LaunchUrlWithDelegate( - url, - render_process_id, - render_view_id, - page_transition, - has_user_gesture, - g_external_protocol_handler_delegate); + url, render_process_id, web_contents->GetRoutingID(), page_transition, + has_user_gesture, g_external_protocol_handler_delegate); } #if !defined(DISABLE_NACL) @@ -453,7 +448,7 @@ bool ChromeResourceDispatcherHostDelegate::HandleExternalProtocol( const GURL& url, int child_id, - int route_id, + const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter, bool is_main_frame, ui::PageTransition page_transition, bool has_user_gesture) { @@ -475,10 +470,9 @@ #endif // defined(ANDROID) BrowserThread::PostTask( - BrowserThread::UI, - FROM_HERE, - base::Bind(&LaunchURL, url, child_id, route_id, page_transition, - has_user_gesture)); + BrowserThread::UI, FROM_HERE, + base::Bind(&LaunchURL, url, child_id, web_contents_getter, + page_transition, has_user_gesture)); return true; }
diff --git a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h index 345cd7f..25b26f1 100644 --- a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h +++ b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h
@@ -56,12 +56,14 @@ content::ResourceDispatcherHostLoginDelegate* CreateLoginDelegate( net::AuthChallengeInfo* auth_info, net::URLRequest* request) override; - bool HandleExternalProtocol(const GURL& url, - int child_id, - int route_id, - bool is_main_frame, - ui::PageTransition page_transition, - bool has_user_gesture) override; + bool HandleExternalProtocol( + const GURL& url, + int child_id, + const content::ResourceRequestInfo::WebContentsGetter& + web_contents_getter, + bool is_main_frame, + ui::PageTransition page_transition, + bool has_user_gesture) override; bool ShouldForceDownloadResource(const GURL& url, const std::string& mime_type) override; bool ShouldInterceptResourceAsStream(net::URLRequest* request,
diff --git a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.html b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.html index d8138f9..57baf51 100644 --- a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.html +++ b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.html
@@ -14,7 +14,7 @@ <link rel="import" type="css" href="../../media_router_common.css"> <link rel="import" type="css" href="media_router_container.css"> <template> - <template is="dom-if" if="[[showFirstRunFlow_]]"> + <template is="dom-if" if="[[showFirstRunFlow]]"> <div id="first-run-flow"> <div id="first-run-title">[[firstRunFlowTitle_]]</div> <div id="first-run-text">[[firstRunFlowText_]]</div>
diff --git a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js index 9de6201..07e7b08a 100644 --- a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js +++ b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js
@@ -202,9 +202,9 @@ /** * Whether to show the first run flow. - * @private {boolean} + * @type {boolean} */ - showFirstRunFlow_: { + showFirstRunFlow: { type: Boolean, value: false, }, @@ -287,12 +287,13 @@ }, /** - * Fires an acknowledge-first-run-flow event. This is call when the first run - * flow button is clicked. + * Fires an acknowledge-first-run-flow event and hides the first run flow. + * This is call when the first run flow button is clicked. * * @private */ acknowledgeFirstRunFlow_: function() { + this.showFirstRunFlow = false; this.fire('acknowledge-first-run-flow'); },
diff --git a/chrome/browser/resources/media_router/media_router.js b/chrome/browser/resources/media_router/media_router.js index 5907457..090aea3 100644 --- a/chrome/browser/resources/media_router/media_router.js +++ b/chrome/browser/resources/media_router/media_router.js
@@ -22,6 +22,8 @@ container = $('media-router-container'); media_router.ui.setContainer(container); + container.addEventListener('acknowledge-first-run-flow', + onAcknowledgeFirstRunFlow); container.addEventListener('back-click', onNavigateToSinkList); container.addEventListener('cast-mode-selected', onCastModeSelected); container.addEventListener('close-button-click', onCloseDialogEvent); @@ -51,6 +53,15 @@ } /** + * Updates the preference that the user has seen the first run flow. + * Called when the user clicks on the acknowledgement button on the first run + * flow. + */ + function onAcknowledgeFirstRunFlow() { + media_router.browserApi.acknowledgeFirstRunFlow(); + } + + /** * Closes the dialog. * Called when the user clicks the close button on the dialog. */
diff --git a/chrome/browser/resources/media_router/media_router_ui_interface.js b/chrome/browser/resources/media_router/media_router_ui_interface.js index b40c620..ab744992 100644 --- a/chrome/browser/resources/media_router/media_router_ui_interface.js +++ b/chrome/browser/resources/media_router/media_router_ui_interface.js
@@ -53,7 +53,8 @@ * @param {deviceMissingUrl: string, * sinks: !Array<!media_router.Sink>, * routes: !Array<!media_router.Route>, - * castModes: !Array<!media_router.CastMode>} data + * castModes: !Array<!media_router.CastMode>, + * wasFirstRunFlowAcknowledged: boolean} data * Parameters in data: * deviceMissingUrl - url to be opened on "Device missing?" clicked. * sinks - list of sinks to be displayed. @@ -65,6 +66,7 @@ container.castModeList = data['castModes']; container.allSinks = data['sinks']; container.routeList = data['routes']; + container.showFirstRunFlow = !data['wasFirstRunFlowAcknowledged']; container.maybeShowRouteDetailsOnOpen(); media_router.browserApi.onInitialDataReceived(); } @@ -114,6 +116,13 @@ 'use strict'; /** + * Indicates that the user has acknowledged the first run flow. + */ + function acknowledgeFirstRunFlow() { + chrome.send('acknowledgeFirstRunFlow'); + } + + /** * Acts on the given issue. * * @param {string} issueId @@ -214,6 +223,7 @@ } return { + acknowledgeFirstRunFlow: acknowledgeFirstRunFlow, actOnIssue: actOnIssue, closeDialog: closeDialog, closeRoute: closeRoute,
diff --git a/chrome/browser/resources/options/compiled_resources.gyp b/chrome/browser/resources/options/compiled_resources.gyp index 757bf43..242ff67 100644 --- a/chrome/browser/resources/options/compiled_resources.gyp +++ b/chrome/browser/resources/options/compiled_resources.gyp
@@ -49,6 +49,7 @@ '../../../../third_party/closure_compiler/externs/bluetooth.js', '../../../../third_party/closure_compiler/externs/bluetooth_private.js', '../../../../third_party/closure_compiler/externs/management.js', + '../../../../third_party/closure_compiler/externs/metrics_private.js', '../../../../third_party/closure_compiler/externs/networking_private.js', '../../../../third_party/closure_compiler/externs/chrome_send.js', '../../../../ui/webui/resources/cr_elements/network/cr_network_icon_externs.js',
diff --git a/chrome/browser/resources/options/search_page.js b/chrome/browser/resources/options/search_page.js index 981ae76b..8a45a08 100644 --- a/chrome/browser/resources/options/search_page.js +++ b/chrome/browser/resources/options/search_page.js
@@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -147,6 +147,13 @@ __proto__: Page.prototype, /** + * Only send the time of first search once. + * @type {boolean} + * @private + */ + hasSentFirstSearchTime_: false, + + /** * A boolean to prevent recursion. Used by setSearchText_(). * @type {boolean} * @private @@ -157,6 +164,9 @@ initializePage: function() { Page.prototype.initializePage.call(this); + // Record the start time for use in reporting metrics. + this.createdTimestamp_ = Date.now(); + this.searchField = $('search-field'); // Handle search events. (No need to throttle, WebKit's search field @@ -303,6 +313,12 @@ return; } + if (!this.hasSentFirstSearchTime_) { + this.hasSentFirstSearchTime_ = true; + chrome.metricsPrivate.recordMediumTime('Settings.TimeToFirstSearch', + Date.now() - this.createdTimestamp_); + } + // Toggle the search page if necessary. Otherwise, update the hash. var hash = '#' + encodeURIComponent(text); if (this.searchActive_) {
diff --git a/chrome/browser/resources/settings/bluetooth_page/bluetooth_pair_device_dialog.js b/chrome/browser/resources/settings/bluetooth_page/bluetooth_pair_device_dialog.js index 9ee5e6a8..fe28674 100644 --- a/chrome/browser/resources/settings/bluetooth_page/bluetooth_pair_device_dialog.js +++ b/chrome/browser/resources/settings/bluetooth_page/bluetooth_pair_device_dialog.js
@@ -172,6 +172,8 @@ /** @private */ onCancelTap_: function() { this.sendResponse_(chrome.bluetoothPrivate.PairingResponse.CANCEL); + // Close the dialog immediately. + this.fire('close-dialog', ''); }, /** @private */
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.html b/chrome/browser/resources/settings/privacy_page/privacy_page.html index 7d32b89..254e197 100644 --- a/chrome/browser/resources/settings/privacy_page/privacy_page.html +++ b/chrome/browser/resources/settings/privacy_page/privacy_page.html
@@ -9,6 +9,7 @@ <link rel="import" href="chrome://md-settings/controls/settings_checkbox.html"> <link rel="import" href="chrome://md-settings/settings_page/settings_animated_pages.html"> <link rel="import" href="chrome://md-settings/settings_page/settings_subheader.html"> +<link rel="import" href="chrome://md-settings/site_settings/constants.html"> <link rel="import" href="chrome://md-settings/site_settings_page/site_settings_page.html"> <dom-module id="settings-privacy-page"> @@ -99,17 +100,92 @@ <settings-subheader i18n-values="page-title:siteSettings"> </settings-subheader> <settings-site-settings-page current-route="{{currentRoute}}" - prefs="{{prefs}}" category-selected="{{categorySelected}}"> + prefs="{{prefs}}"> </settings-site-settings-page> </neon-animatable> - <neon-animatable id="site-settings-category"> + + <neon-animatable id="site-settings-category-camera"> <settings-subheader i18n-values="page-title:siteSettings"> </settings-subheader> <site-settings-category selected-origin="{{originSelected}}" prefs="{{prefs}}" - current-route="{{currentRoute}}" category="{{categorySelected}}"> + current-route="{{currentRoute}}" + category="{{ContentSettingsTypes.CAMERA}}"> </site-settings-category> </neon-animatable> + <neon-animatable id="site-settings-category-cookies"> + <settings-subheader i18n-values="page-title:siteSettings"> + </settings-subheader> + <site-settings-category + selected-origin="{{originSelected}}" prefs="{{prefs}}" + current-route="{{currentRoute}}" + category="{{ContentSettingsTypes.COOKIES}}"> + </site-settings-category> + </neon-animatable> + <neon-animatable id="site-settings-category-fullscreen"> + <settings-subheader i18n-values="page-title:siteSettings"> + </settings-subheader> + <site-settings-category + selected-origin="{{originSelected}}" prefs="{{prefs}}" + current-route="{{currentRoute}}" + category="{{ContentSettingsTypes.FULLSCREEN}}"> + </site-settings-category> + </neon-animatable> + <neon-animatable id="site-settings-category-images"> + <settings-subheader i18n-values="page-title:siteSettings"> + </settings-subheader> + <site-settings-category + selected-origin="{{originSelected}}" prefs="{{prefs}}" + current-route="{{currentRoute}}" + category="{{ContentSettingsTypes.IMAGES}}"> + </site-settings-category> + </neon-animatable> + <neon-animatable id="site-settings-category-location"> + <settings-subheader i18n-values="page-title:siteSettings"> + </settings-subheader> + <site-settings-category + selected-origin="{{originSelected}}" prefs="{{prefs}}" + current-route="{{currentRoute}}" + category="{{ContentSettingsTypes.GEOLOCATION}}"> + </site-settings-category> + </neon-animatable> + <neon-animatable id="site-settings-category-javascript"> + <settings-subheader i18n-values="page-title:siteSettings"> + </settings-subheader> + <site-settings-category + selected-origin="{{originSelected}}" prefs="{{prefs}}" + current-route="{{currentRoute}}" + category="{{ContentSettingsTypes.JAVASCRIPT}}"> + </site-settings-category> + </neon-animatable> + <neon-animatable id="site-settings-category-microphone"> + <settings-subheader i18n-values="page-title:siteSettings"> + </settings-subheader> + <site-settings-category + selected-origin="{{originSelected}}" prefs="{{prefs}}" + current-route="{{currentRoute}}" + category="{{ContentSettingsTypes.MIC}}"> + </site-settings-category> + </neon-animatable> + <neon-animatable id="site-settings-category-notifications"> + <settings-subheader i18n-values="page-title:siteSettings"> + </settings-subheader> + <site-settings-category + selected-origin="{{originSelected}}" prefs="{{prefs}}" + current-route="{{currentRoute}}" + category="{{ContentSettingsTypes.NOTIFICATIONS}}"> + </site-settings-category> + </neon-animatable> + <neon-animatable id="site-settings-category-popups"> + <settings-subheader i18n-values="page-title:siteSettings"> + </settings-subheader> + <site-settings-category + selected-origin="{{originSelected}}" prefs="{{prefs}}" + current-route="{{currentRoute}}" + category="{{ContentSettingsTypes.POPUPS}}"> + </site-settings-category> + </neon-animatable> + <neon-animatable id="site-details"> <site-details prefs="{{prefs}}" origin="{{originSelected}}"> </site-details>
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.js b/chrome/browser/resources/settings/privacy_page/privacy_page.js index 4896061..d5b122b 100644 --- a/chrome/browser/resources/settings/privacy_page/privacy_page.js +++ b/chrome/browser/resources/settings/privacy_page/privacy_page.js
@@ -47,6 +47,10 @@ } }, + ready: function() { + this.ContentSettingsTypes = settings.ContentSettingsTypes; + }, + /** @private */ onManageCertificatesTap_: function() { this.$.pages.setSubpageChain(['manage-certificates']);
diff --git a/chrome/browser/resources/settings/settings_page/settings_router.js b/chrome/browser/resources/settings/settings_page/settings_router.js index 5c9c5681..f7cdb78 100644 --- a/chrome/browser/resources/settings/settings_page/settings_router.js +++ b/chrome/browser/resources/settings/settings_page/settings_router.js
@@ -172,11 +172,67 @@ subpageTitles: ['siteSettings'], }, { - url: '/siteSettings/category', + url: '/siteSettings/category/camera', page: 'advanced', section: 'privacy', - subpage: ['site-settings', 'site-settings-category'], - subpageTitles: ['siteSettings', 'siteSettingsCategoryPageTitle'], + subpage: ['site-settings', 'site-settings-category-camera'], + subpageTitles: ['siteSettings', 'siteSettingsCamera'], + }, + { + url: '/siteSettings/category/cookies', + page: 'advanced', + section: 'privacy', + subpage: ['site-settings', 'site-settings-category-cookies'], + subpageTitles: ['siteSettings', 'siteSettingsCategoryCookies'], + }, + { + url: '/siteSettings/category/fullscreen', + page: 'advanced', + section: 'privacy', + subpage: ['site-settings', 'site-settings-category-fullscreen'], + subpageTitles: ['siteSettings', 'siteSettingsCategoryFullscreen'], + }, + { + url: '/siteSettings/category/images', + page: 'advanced', + section: 'privacy', + subpage: ['site-settings', 'site-settings-category-images'], + subpageTitles: ['siteSettings', 'siteSettingsCategoryImages'], + }, + { + url: '/siteSettings/category/location', + page: 'advanced', + section: 'privacy', + subpage: ['site-settings', 'site-settings-category-location'], + subpageTitles: ['siteSettings', 'siteSettingsCategoryLocation'], + }, + { + url: '/siteSettings/category/javascript', + page: 'advanced', + section: 'privacy', + subpage: ['site-settings', 'site-settings-category-javascript'], + subpageTitles: ['siteSettings', 'siteSettingsCategoryJavascript'], + }, + { + url: '/siteSettings/category/microphone', + page: 'advanced', + section: 'privacy', + subpage: ['site-settings', 'site-settings-category-microphone'], + subpageTitles: ['siteSettings', 'siteSettingsCategoryMicrophone'], + }, + { + url: '/siteSettings/category/notifications', + page: 'advanced', + section: 'privacy', + subpage: ['site-settings', 'site-settings-category-notifications'], + subpageTitles: ['siteSettings', 'siteSettingsCategoryNotifications'], + }, + { + url: '/siteSettings/category/popups', + page: 'advanced', + section: 'privacy', + subpage: ['site-settings', 'site-settings-category-popups'], + subpageTitles: ['siteSettings', 'siteSettingsCategoryPopups'], }, { url: '/siteSettings/category/details',
diff --git a/chrome/browser/resources/settings/site_settings/constants.js b/chrome/browser/resources/settings/site_settings/constants.js index 909db1a..c0de36a2 100644 --- a/chrome/browser/resources/settings/site_settings/constants.js +++ b/chrome/browser/resources/settings/site_settings/constants.js
@@ -17,7 +17,7 @@ JAVASCRIPT: 2, POPUPS: 4, GEOLOCATION: 5, - NOTIFICATION: 6, + NOTIFICATIONS: 6, FULLSCREEN: 8, MIC: 12, CAMERA: 13,
diff --git a/chrome/browser/resources/settings/site_settings/site_details.js b/chrome/browser/resources/settings/site_settings/site_details.js index cc6d5616..a6a8db7 100644 --- a/chrome/browser/resources/settings/site_settings/site_details.js +++ b/chrome/browser/resources/settings/site_settings/site_details.js
@@ -47,7 +47,7 @@ this.$.javascript.category = settings.ContentSettingsTypes.JAVASCRIPT; this.$.popups.category = settings.ContentSettingsTypes.POPUPS; this.$.geolocation.category = settings.ContentSettingsTypes.GEOLOCATION; - this.$.notification.category = settings.ContentSettingsTypes.NOTIFICATION; + this.$.notification.category = settings.ContentSettingsTypes.NOTIFICATIONS; this.$.fullscreen.category = settings.ContentSettingsTypes.FULLSCREEN; this.$.camera.category = settings.ContentSettingsTypes.CAMERA; this.$.mic.category = settings.ContentSettingsTypes.MIC;
diff --git a/chrome/browser/resources/settings/site_settings/site_list.js b/chrome/browser/resources/settings/site_settings/site_list.js index 0948e8aa..e8f03f09 100644 --- a/chrome/browser/resources/settings/site_settings/site_list.js +++ b/chrome/browser/resources/settings/site_settings/site_list.js
@@ -100,7 +100,8 @@ }, observers: [ - 'onCategoryChanged_(prefs.profile.content_settings.exceptions.*, category)', + 'onCategoryChanged_(prefs.profile.content_settings.exceptions.*, ' + + 'category, categorySubtype)', ], ready: function() {
diff --git a/chrome/browser/resources/settings/site_settings/site_settings_behavior.js b/chrome/browser/resources/settings/site_settings/site_settings_behavior.js index b46f6f3..4cfadfa 100644 --- a/chrome/browser/resources/settings/site_settings/site_settings_behavior.js +++ b/chrome/browser/resources/settings/site_settings/site_settings_behavior.js
@@ -70,6 +70,37 @@ }, /** + * A utility function to lookup a category name from its enum. + * @param {number} category The category ID to look up. + * @return {string} The category found or blank string if not found. + * @protected + */ + computeCategoryTextId: function(category) { + switch (category) { + case settings.ContentSettingsTypes.CAMERA: + return 'camera'; + case settings.ContentSettingsTypes.COOKIES: + return 'cookies'; + case settings.ContentSettingsTypes.FULLSCREEN: + return 'fullscreen'; + case settings.ContentSettingsTypes.GEOLOCATION: + return 'location'; + case settings.ContentSettingsTypes.IMAGES: + return 'images'; + case settings.ContentSettingsTypes.JAVASCRIPT: + return 'javascript'; + case settings.ContentSettingsTypes.MIC: + return 'microphone'; + case settings.ContentSettingsTypes.NOTIFICATIONS: + return 'notifications'; + case settings.ContentSettingsTypes.POPUPS: + return 'popups'; + default: + return ''; + } + }, + + /** * A utility function to compute the icon to use for the category. * @param {number} category The category to show the icon for. * @return {string} The id of the icon for the given category. @@ -91,7 +122,7 @@ return 'icons:input'; case settings.ContentSettingsTypes.MIC: return 'av:mic'; - case settings.ContentSettingsTypes.NOTIFICATION: + case settings.ContentSettingsTypes.NOTIFICATIONS: return 'social:notifications'; case settings.ContentSettingsTypes.POPUPS: return 'icons:open-in-new'; @@ -123,7 +154,7 @@ return loadTimeData.getString('siteSettingsJavascript'); case settings.ContentSettingsTypes.MIC: return loadTimeData.getString('siteSettingsMic'); - case settings.ContentSettingsTypes.NOTIFICATION: + case settings.ContentSettingsTypes.NOTIFICATIONS: return loadTimeData.getString('siteSettingsNotifications'); case settings.ContentSettingsTypes.POPUPS: return loadTimeData.getString('siteSettingsPopups'); @@ -179,7 +210,7 @@ return 'javascript'; case settings.ContentSettingsTypes.MIC: return 'media_stream_mic'; - case settings.ContentSettingsTypes.NOTIFICATION: + case settings.ContentSettingsTypes.NOTIFICATIONS: return 'notifications'; case settings.ContentSettingsTypes.POPUPS: return 'popups'; @@ -216,7 +247,7 @@ return showRecommendation ? loadTimeData.getString('siteSettingsBlockedRecommended') : loadTimeData.getString('siteSettingsBlocked'); - case settings.ContentSettingsTypes.NOTIFICATION: + case settings.ContentSettingsTypes.NOTIFICATIONS: // "Ask before sending (recommended)" vs "Blocked". if (!categoryEnabled) { return loadTimeData.getString('siteSettingsBlocked');
diff --git a/chrome/browser/resources/settings/site_settings/site_settings_category.js b/chrome/browser/resources/settings/site_settings/site_settings_category.js index 01b764c..22a3347 100644 --- a/chrome/browser/resources/settings/site_settings/site_settings_category.js +++ b/chrome/browser/resources/settings/site_settings/site_settings_category.js
@@ -35,9 +35,7 @@ * example, the Location category can be set to Block/Ask so false, in that * case, represents Block and true represents Ask. */ - categoryEnabled: { - type: Boolean, - }, + categoryEnabled: Boolean, /** * The origin that was selected by the user in the dropdown list. @@ -62,9 +60,6 @@ ], ready: function() { - // TODO(finnur): Handle dynamic routes, so that we can link directly into - // individual categories without having to first stop by the site settings - // page to select a category. this.$.blockList.categorySubtype = settings.PermissionValues.BLOCK; this.$.allowList.categorySubtype = settings.PermissionValues.ALLOW; }, @@ -84,7 +79,7 @@ settings.PermissionValues.ALLOW : settings.PermissionValues.BLOCK); break; - case settings.ContentSettingsTypes.NOTIFICATION: + case settings.ContentSettingsTypes.NOTIFICATIONS: case settings.ContentSettingsTypes.GEOLOCATION: case settings.ContentSettingsTypes.CAMERA: case settings.ContentSettingsTypes.MIC:
diff --git a/chrome/browser/resources/settings/site_settings_page/site_settings_page.js b/chrome/browser/resources/settings/site_settings_page/site_settings_page.js index b737540..17ab458 100644 --- a/chrome/browser/resources/settings/site_settings_page/site_settings_page.js +++ b/chrome/browser/resources/settings/site_settings_page/site_settings_page.js
@@ -39,14 +39,6 @@ type: Object, notify: true, }, - - /** - * The category selected by the user. - */ - categorySelected: { - type: Number, - notify: true, - }, }, ready: function() { @@ -59,7 +51,7 @@ this.addCategory(settings.ContentSettingsTypes.JAVASCRIPT); this.addCategory(settings.ContentSettingsTypes.POPUPS); this.addCategory(settings.ContentSettingsTypes.FULLSCREEN); - this.addCategory(settings.ContentSettingsTypes.NOTIFICATION); + this.addCategory(settings.ContentSettingsTypes.NOTIFICATIONS); this.addCategory(settings.ContentSettingsTypes.IMAGES); }.bind(this)); }, @@ -100,12 +92,12 @@ */ onTapCategory: function(event) { var description = event.currentTarget.querySelector('.flex').innerText; - this.categorySelected = this.computeCategoryFromDesc(description); - + var page = this.computeCategoryTextId( + this.computeCategoryFromDesc(description)); this.currentRoute = { page: this.currentRoute.page, section: 'privacy', - subpage: ['site-settings', 'site-settings-category'], + subpage: ['site-settings', 'site-settings-category-' + page], }; }, });
diff --git a/chrome/browser/ui/views/toolbar/chevron_menu_button.cc b/chrome/browser/ui/views/toolbar/chevron_menu_button.cc index 31baf8b..baa9e13 100644 --- a/chrome/browser/ui/views/toolbar/chevron_menu_button.cc +++ b/chrome/browser/ui/views/toolbar/chevron_menu_button.cc
@@ -197,22 +197,9 @@ views::View::ConvertPointToScreen(owner_, &screen_loc); bounds.set_x(screen_loc.x()); bounds.set_y(screen_loc.y()); - - if (menu_runner_->RunMenuAt(window, - owner_, - bounds, - views::MENU_ANCHOR_TOPRIGHT, - ui::MENU_SOURCE_NONE) == - views::MenuRunner::MENU_DELETED) - return; - - if (!for_drop_) { - // Give the context menu (if any) a chance to execute the user-selected - // command. - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&ChevronMenuButton::MenuDone, - owner_->weak_factory_.GetWeakPtr())); - } + ignore_result(menu_runner_->RunMenuAt(window, owner_, bounds, + views::MENU_ANCHOR_TOPRIGHT, + ui::MENU_SOURCE_NONE)); } void ChevronMenuButton::MenuController::CloseMenu() { @@ -338,7 +325,14 @@ void ChevronMenuButton::MenuController::OnMenuClosed( views::MenuItemView* menu, views::MenuRunner::RunResult result) { - owner_->MenuDone(); + if (result == views::MenuRunner::MENU_DELETED) + return; + + // Give the context menu (if any) a chance to execute the user-selected + // command. + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(&ChevronMenuButton::MenuDone, + owner_->weak_factory_.GetWeakPtr())); } bool ChevronMenuButton::MenuController::CanDrag(views::MenuItemView* menu) {
diff --git a/chrome/browser/ui/webui/browsing_history_handler.cc b/chrome/browser/ui/webui/browsing_history_handler.cc index 253a80c9..fbcdc981 100644 --- a/chrome/browser/ui/webui/browsing_history_handler.cc +++ b/chrome/browser/ui/webui/browsing_history_handler.cc
@@ -32,7 +32,6 @@ #include "chrome/browser/ui/webui/favicon_source.h" #include "chrome/common/features.h" #include "chrome/common/pref_names.h" -#include "chrome/grit/generated_resources.h" #include "components/bookmarks/browser/bookmark_model.h" #include "components/bookmarks/browser/bookmark_utils.h" #include "components/browser_sync/browser/profile_sync_service.h" @@ -46,6 +45,7 @@ #include "components/url_formatter/url_formatter.h" #include "content/public/browser/url_data_source.h" #include "content/public/browser/web_ui.h" +#include "grit/components_strings.h" #include "sync/protocol/history_delete_directive_specifics.pb.h" #include "sync/protocol/sync_enums.pb.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/ui/webui/history_ui.cc b/chrome/browser/ui/webui/history_ui.cc index c59fe442..16ff4878 100644 --- a/chrome/browser/ui/webui/history_ui.cc +++ b/chrome/browser/ui/webui/history_ui.cc
@@ -107,7 +107,8 @@ IDS_HISTORY_ACTION_MENU_DESCRIPTION); source->AddLocalizedString("removeFromHistory", IDS_HISTORY_REMOVE_PAGE); source->AddLocalizedString("moreFromSite", IDS_HISTORY_MORE_FROM_SITE); - source->AddLocalizedString("groupByDomainLabel", IDS_GROUP_BY_DOMAIN_LABEL); + source->AddLocalizedString("groupByDomainLabel", + IDS_HISTORY_GROUP_BY_DOMAIN_LABEL); source->AddLocalizedString("rangeLabel", IDS_HISTORY_RANGE_LABEL); source->AddLocalizedString("rangeAllTime", IDS_HISTORY_RANGE_ALL_TIME); source->AddLocalizedString("rangeWeek", IDS_HISTORY_RANGE_WEEK);
diff --git a/chrome/browser/ui/webui/log_web_ui_url_browsertest.cc b/chrome/browser/ui/webui/log_web_ui_url_browsertest.cc index bdd37018..c443f279 100644 --- a/chrome/browser/ui/webui/log_web_ui_url_browsertest.cc +++ b/chrome/browser/ui/webui/log_web_ui_url_browsertest.cc
@@ -19,6 +19,7 @@ #include "chrome/test/base/ui_test_utils.h" #include "content/public/common/url_constants.h" #include "content/public/test/browser_test_utils.h" +#include "grit/components_strings.h" #include "grit/generated_resources.h" #include "testing/gmock/include/gmock/gmock.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/ui/webui/md_history_ui.cc b/chrome/browser/ui/webui/md_history_ui.cc index 31c7ecd5..f7084edb 100644 --- a/chrome/browser/ui/webui/md_history_ui.cc +++ b/chrome/browser/ui/webui/md_history_ui.cc
@@ -9,11 +9,11 @@ #include "chrome/browser/ui/webui/browsing_history_handler.h" #include "chrome/browser/ui/webui/metrics_handler.h" #include "chrome/common/url_constants.h" -#include "chrome/grit/generated_resources.h" #include "components/search/search.h" #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_data_source.h" #include "grit/browser_resources.h" +#include "grit/components_strings.h" #include "grit/theme_resources.h" #include "ui/base/resource/resource_bundle.h"
diff --git a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc index b99a049..0840de6 100644 --- a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc +++ b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc
@@ -10,9 +10,12 @@ #include "base/metrics/histogram_macros.h" #include "base/metrics/sparse_histogram.h" #include "base/metrics/user_metrics.h" +#include "base/prefs/pref_service.h" #include "base/strings/stringprintf.h" #include "chrome/browser/media/router/issue.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/media_router/media_router_ui.h" +#include "chrome/common/pref_names.h" #include "chrome/grit/generated_resources.h" #include "extensions/common/constants.h" #include "ui/base/l10n/l10n_util.h" @@ -27,6 +30,7 @@ // Message names. const char kRequestInitialData[] = "requestInitialData"; const char kCreateRoute[] = "requestRoute"; +const char kAcknowledgeFirstRunFlow[] = "acknowledgeFirstRunFlow"; const char kActOnIssue[] = "actOnIssue"; const char kCloseRoute[] = "closeRoute"; const char kJoinRoute[] = "joinRoute"; @@ -248,6 +252,10 @@ base::Bind(&MediaRouterWebUIMessageHandler::OnCreateRoute, base::Unretained(this))); web_ui()->RegisterMessageCallback( + kAcknowledgeFirstRunFlow, + base::Bind(&MediaRouterWebUIMessageHandler::OnAcknowledgeFirstRunFlow, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( kActOnIssue, base::Bind(&MediaRouterWebUIMessageHandler::OnActOnIssue, base::Unretained(this))); @@ -309,6 +317,12 @@ media_router_ui_->GetPresentationRequestSourceName())); initial_data.Set("castModes", cast_modes_list.release()); + bool first_run_flow_acknowledged = + Profile::FromWebUI(web_ui())->GetPrefs()->GetBoolean( + prefs::kMediaRouterFirstRunFlowAcknowledged); + initial_data.SetBoolean("wasFirstRunFlowAcknowledged", + first_run_flow_acknowledged); + web_ui()->CallJavascriptFunction(kSetInitialData, initial_data); media_router_ui_->UIInitialized(); } @@ -364,6 +378,13 @@ } } +void MediaRouterWebUIMessageHandler::OnAcknowledgeFirstRunFlow( + const base::ListValue* args) { + DVLOG(1) << "OnAcknowledgeFirstRunFlow"; + Profile::FromWebUI(web_ui())->GetPrefs()->SetBoolean( + prefs::kMediaRouterFirstRunFlowAcknowledged, true); +} + void MediaRouterWebUIMessageHandler::OnActOnIssue( const base::ListValue* args) { DVLOG(1) << "OnActOnIssue";
diff --git a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.h b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.h index 91a2573..f8cb1f4 100644 --- a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.h +++ b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.h
@@ -56,6 +56,7 @@ // See media_router_ui_interface.js for documentation on parameters. void OnRequestInitialData(const base::ListValue* args); void OnCreateRoute(const base::ListValue* args); + void OnAcknowledgeFirstRunFlow(const base::ListValue* args); void OnActOnIssue(const base::ListValue* args); void OnCloseRoute(const base::ListValue* args); void OnJoinRoute(const base::ListValue* args);
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc index f35481c..c0e7de82 100644 --- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -655,12 +655,26 @@ } void AddSiteSettingsStrings(content::WebUIDataSource* html_source) { - html_source->AddLocalizedString("siteSettingsPageTitle", - IDS_SETTINGS_SITE_SETTINGS); - // TODO(finnur): Would be nice to show 'Location'/'Camera' instead of hard- - // coding this. html_source->AddLocalizedString("siteSettingsCategoryPageTitle", IDS_SETTINGS_SITE_SETTINGS_CATEGORY); + html_source->AddLocalizedString("siteSettingsCategoryCamera", + IDS_SETTINGS_SITE_SETTINGS_CAMERA); + html_source->AddLocalizedString("siteSettingsCategoryCookies", + IDS_SETTINGS_SITE_SETTINGS_COOKIES); + html_source->AddLocalizedString("siteSettingsCategoryFullscreen", + IDS_SETTINGS_SITE_SETTINGS_FULLSCREEN); + html_source->AddLocalizedString("siteSettingsCategoryImages", + IDS_SETTINGS_SITE_SETTINGS_IMAGES); + html_source->AddLocalizedString("siteSettingsCategoryLocation", + IDS_SETTINGS_SITE_SETTINGS_LOCATION); + html_source->AddLocalizedString("siteSettingsCategoryJavascript", + IDS_SETTINGS_SITE_SETTINGS_JAVASCRIPT); + html_source->AddLocalizedString("siteSettingsCategoryMicrophone", + IDS_SETTINGS_SITE_SETTINGS_MIC); + html_source->AddLocalizedString("siteSettingsCategoryNotifications", + IDS_SETTINGS_SITE_SETTINGS_NOTIFICATIONS); + html_source->AddLocalizedString("siteSettingsCategoryPopups", + IDS_SETTINGS_SITE_SETTINGS_POPUPS); html_source->AddLocalizedString("siteSettingsSiteDetailsPageTitle", IDS_SETTINGS_SITE_SETTINGS_SITE_DETAILS); html_source->AddLocalizedString("siteSettingsAllSites",
diff --git a/chrome/browser/ui/webui/uber/uber_ui.cc b/chrome/browser/ui/webui/uber/uber_ui.cc index 0164799..8b4159c 100644 --- a/chrome/browser/ui/webui/uber/uber_ui.cc +++ b/chrome/browser/ui/webui/uber/uber_ui.cc
@@ -27,6 +27,7 @@ #include "extensions/browser/extension_registry.h" #include "extensions/common/extension_set.h" #include "grit/browser_resources.h" +#include "grit/components_strings.h" using content::NavigationController; using content::NavigationEntry;
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 5ba64137f..68370c5 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi
@@ -3545,7 +3545,7 @@ ], 'sources': [ '<@(chrome_browser_plugins_sources)' ], }], - ['safe_browsing != 0', { + ['safe_browsing != 0 and OS != "ios"', { 'sources': [ '<@(chrome_browser_safe_browsing_basic_sources)' ], 'dependencies': [ 'safe_browsing_chunk_proto', @@ -3566,7 +3566,7 @@ }], ], }], - ['safe_browsing == 2 and OS != "ios"', { + ['safe_browsing == 2', { 'sources': [ '<@(chrome_browser_safe_browsing_mobile_sources)' ], 'dependencies': [ 'safe_browsing_proto',
diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi index c38649a..8eaafa07 100644 --- a/chrome/chrome_browser_chromeos.gypi +++ b/chrome/chrome_browser_chromeos.gypi
@@ -1270,6 +1270,7 @@ ['use_ozone == 1', { 'dependencies': [ '../ui/ozone/ozone.gyp:ozone', + '../ui/ozone/ozone.gyp:ozone_base', ], }], ],
diff --git a/chrome/common/extensions/api/_api_features.json b/chrome/common/extensions/api/_api_features.json index 46a19825..3f78f831 100644 --- a/chrome/common/extensions/api/_api_features.json +++ b/chrome/common/extensions/api/_api_features.json
@@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -594,10 +594,18 @@ "dependencies": ["permission:mediaPlayerPrivate"], "contexts": ["blessed_extension"] }, - "metricsPrivate": { + "metricsPrivate": [{ "dependencies": ["permission:metricsPrivate"], "contexts": ["blessed_extension"] - }, + }, { + "channel": "trunk", + "contexts": ["webui"], + "matches": [ + "chrome://md-settings/*", + "chrome://settings/*", + "chrome://settings-frame/*" + ] + }], "mdns": { "dependencies": ["permission:mdns"], "contexts": ["blessed_extension"]
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 3e5d7ce..86aecec 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -2175,4 +2175,11 @@ const char kClickedUpdateMenuItem[] = "omaha.clicked_update_menu_item"; #endif +#if defined(ENABLE_MEDIA_ROUTER) +// Whether or not the Media Router first run flow has been acknowledged by the +// user. +const char kMediaRouterFirstRunFlowAcknowledged[] = + "media_router.firstrunflow.acknowledged"; +#endif + } // namespace prefs
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 69930944..a49a2b2 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -792,6 +792,10 @@ extern const char kClickedUpdateMenuItem[]; #endif +#if defined(ENABLE_MEDIA_ROUTER) +extern const char kMediaRouterFirstRunFlowAcknowledged[]; +#endif + } // namespace prefs #endif // CHROME_COMMON_PREF_NAMES_H_
diff --git a/chrome/telemetry_unittests.isolate b/chrome/telemetry_unittests.isolate index 14b5d8a..e42cf0a 100644 --- a/chrome/telemetry_unittests.isolate +++ b/chrome/telemetry_unittests.isolate
@@ -15,6 +15,10 @@ '../testing/scripts/common.py', '../testing/scripts/run_telemetry_as_googletest.py', ], + } + }], + ['OS=="mac"', { + 'variables': { 'command': [ '../testing/scripts/run_telemetry_as_googletest.py', '../tools/telemetry/run_tests', @@ -24,5 +28,20 @@ ], }, }], + ['OS=="win"', { + 'variables': { + 'command': [ + '../testing/scripts/run_telemetry_as_googletest.py', + '../tools/telemetry/run_tests', + '-v', + '--chrome-root', + '..', + # crbug.com/570955 + # TODO(nednguyen): Remove --jobs=1 once the bug is fixed to speed up + # the test run. + '--job=1', + ], + }, + }], ] }
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 58b218b..8f93afed 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2138,9 +2138,6 @@ "../app/delay_load_hook_win.cc", "../app/delay_load_hook_win.h", "../app/resources/resources_unittest.cc", - "../app/signature_validator_win.cc", - "../app/signature_validator_win.h", - "../app/signature_validator_win_unittest.cc", "../common/crash_keys.cc", "../common/crash_keys.h", ]
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/TabStripUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/TabStripUtils.java index 947ecc4..22903a4f 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/TabStripUtils.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/TabStripUtils.java
@@ -4,8 +4,6 @@ package org.chromium.chrome.test.util; -import android.view.View; - import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.compositor.layouts.components.CompositorButton; import org.chromium.chrome.browser.compositor.overlays.strip.StripLayoutHelper; @@ -14,7 +12,6 @@ import org.chromium.chrome.test.ChromeTabbedActivityTestBase; import org.chromium.content.browser.test.util.Criteria; import org.chromium.content.browser.test.util.CriteriaHelper; -import org.chromium.content.browser.test.util.TestTouchUtils; /** * A utility class that contains methods generic to all TabStrip test classes. @@ -72,19 +69,24 @@ } /** - * Click a compositor tab strip tab; + * Click a compositor tab strip tab. * @param tab The tab to click. * @param base The ChromeTabbedActivityTestBase where we're calling this from. */ public static void clickTab(StripLayoutTab tab, ChromeTabbedActivityTestBase base) { - View view = base.getActivity().getTabsView(); - final float x = tab.getDrawX() + tab.getWidth() / 2; - final float y = tab.getDrawY() + tab.getHeight() / 2; - TestTouchUtils.singleClickView(base.getInstrumentation(), view, (int) x, (int) y); + final StripLayoutHelperManager manager = getStripLayoutHelperManager(base.getActivity()); + final float x = (tab.getDrawX() + tab.getWidth() / 2); + final float y = (tab.getDrawY() + tab.getHeight() / 2); + base.getInstrumentation().runOnMainSync(new Runnable() { + @Override + public void run() { + manager.click(0, x, y, false, 0); + } + }); } /** - * Click a compositor button; + * Click a compositor button. * @param button The button to click. * @param base The ChromeTabbedActivityTestBase where we're calling this from. */
diff --git a/chrome/test/data/webui/media_router/media_router_container_tests.js b/chrome/test/data/webui/media_router/media_router_container_tests.js index 95a80341..7610fd3 100644 --- a/chrome/test/data/webui/media_router/media_router_container_tests.js +++ b/chrome/test/data/webui/media_router/media_router_container_tests.js
@@ -56,6 +56,7 @@ 'cast-mode-list', 'container-header', 'device-missing', + 'first-run-flow', 'issue-banner', 'route-details', 'sink-list', @@ -169,7 +170,7 @@ // Tests for 'acknowledge-first-run-flow' event firing when the // 'first-run-button' button is clicked. test('first run button click', function(done) { - container.showFirstRunFlow_ = true; + container.showFirstRunFlow = true; setTimeout(function() { container.addEventListener('acknowledge-first-run-flow', function() { @@ -456,6 +457,23 @@ }); }); + // Tests for the expected visible UI when interacting with the first run + // flow. + test('first run button visibility', function(done) { + container.showFirstRunFlow = true; + + setTimeout(function() { + checkElementVisibleWithId(true, 'first-run-flow'); + MockInteractions.tap(container.shadowRoot.getElementById( + 'first-run-button')); + + setTimeout(function() { + checkElementVisibleWithId(false, 'first-run-flow'); + done(); + }); + }); + }); + // Tests for expected visible UI when the view is ROUTE_DETAILS. test('route details visibility', function(done) { container.showRouteDetails_();
diff --git a/chrome/test/data/webui/settings/bluetooth_page_browsertest_chromeos.js b/chrome/test/data/webui/settings/bluetooth_page_browsertest_chromeos.js index 9d31c55..52e57e4 100644 --- a/chrome/test/data/webui/settings/bluetooth_page_browsertest_chromeos.js +++ b/chrome/test/data/webui/settings/bluetooth_page_browsertest_chromeos.js
@@ -86,11 +86,16 @@ name: 'FakeUnPairedDevice1', paired: false, }, + { + address: '00:00:00:00:00:02', + name: 'FakeUnPairedDevice2', + paired: false, + }, ]; suite('SettingsBluetoothPage', function() { test('enable', function() { - assertFalse(self.bluetoothApi_.enabled); + assertFalse(self.bluetoothApi_.adapterState.powered); var bluetoothSection = self.getSection(advanced, 'bluetooth'); assertTrue(!!bluetoothSection); var bluetooth = @@ -103,10 +108,10 @@ // Test that tapping the enable checkbox changes its value and calls // bluetooth.setAdapterState with powered = false. MockInteractions.tap(enable); - expectTrue(enable.checked); - expectTrue(self.bluetoothApi_.enabled); - // Confirm that 'bluetoothEnabled' remains set to true. Polymer.dom.flush(); + expectTrue(enable.checked); + expectTrue(self.bluetoothApi_.adapterState.powered); + // Confirm that 'bluetoothEnabled' remains set to true. expectTrue(bluetooth.bluetoothEnabled); // Set 'bluetoothEnabled' directly and confirm that the checkbox // toggles. @@ -123,8 +128,7 @@ var deviceList = bluetooth.$.deviceList; assertTrue(!!deviceList); // Set enabled, with default (empty) device list. - self.bluetoothApi_.enabled = true; - bluetooth.bluetoothEnabled = true; + self.bluetoothApi_.setEnabled(true); Polymer.dom.flush(); // Ensure that initially the 'device list empty' span is visible. expectFalse(deviceList.hidden); @@ -144,6 +148,48 @@ assertFalse(devices[1].device.connected); assertTrue(devices[1].device.connecting); }); + + test('device dialog', function() { + var bluetoothSection = self.getSection(advanced, 'bluetooth'); + var bluetooth = + bluetoothSection.querySelector('settings-bluetooth-page'); + assertTrue(!!bluetooth); + self.bluetoothApi_.setEnabled(true); + + // Tap the 'add device' button. + MockInteractions.tap(bluetooth.$.addDevice); + Polymer.dom.flush(); + // Ensure the dialog appears. + var dialog = bluetooth.$.deviceDialog; + assertTrue(!!dialog); + assertTrue(dialog.opened); + var addDialog = bluetooth.$$('settings-bluetooth-add-device-dialog'); + assertTrue(!!addDialog); + // Ensure the dialog has the expected devices. + var devicesDiv = addDialog.$.dialogDeviceList; + var devices = devicesDiv.querySelectorAll('bluetooth-device-list-item'); + assertEquals(2, devices.length); + + // Select a device. + MockInteractions.tap(devices[0].$$('div')); + Polymer.dom.flush(); + // Ensure the pairing dialog is shown. + var pairDialog = bluetooth.$$('settings-bluetooth-pair-device-dialog'); + assertTrue(!!pairDialog); + // Ensure the device is connected to. + expectEquals(1, self.bluetoothPrivateApi_.connectedDevices_.size); + var deviceAddress = + self.bluetoothPrivateApi_.connectedDevices_.keys().next().value; + + // Close the dialog. + MockInteractions.tap(pairDialog.$.close); + Polymer.dom.flush(); + expectFalse(dialog.opened); + var response = self.bluetoothPrivateApi_.pairingResponses_[deviceAddress]; + assertTrue(!!response); + expectEquals(chrome.bluetoothPrivate.PairingResponse.CANCEL, + response.response); + }); }); // Run all registered tests.
diff --git a/chrome/test/data/webui/settings/fake_bluetooth.js b/chrome/test/data/webui/settings/fake_bluetooth.js index 64e646eb..06f5923a 100644 --- a/chrome/test/data/webui/settings/fake_bluetooth.js +++ b/chrome/test/data/webui/settings/fake_bluetooth.js
@@ -12,7 +12,13 @@ * @implements {Bluetooth} */ function FakeBluetooth() { - /** @type {boolean} */ this.enabled = false; + /** @type {!chrome.bluettoth.AdapterState} */ this.adapterState = { + address: '00:11:22:33:44:55:66', + name: 'Fake Adapter', + powered: false, + available: true, + discovering: false + }; /** @type {!Array<!chrome.bluetooth.Device>} */ this.devices = []; } @@ -20,6 +26,14 @@ FakeBluetooth.prototype = { // Public testing methods. /** + * @param {boolean} enabled + */ + setEnabled: function(enabled) { + this.adapterState.powered = enabled; + this.onAdapterStateChanged.callListeners(this.adapterState); + }, + + /** * @param {!Array<!chrome.bluetooth.Device>} devices */ setDevicesForTest: function(devices) { @@ -34,13 +48,7 @@ /** @override */ getAdapterState: function(callback) { setTimeout(function() { - callback({ - address: '00:11:22:33:44:55:66', - name: 'Fake Adapter', - powered: this.enabled, - available: true, - discovering: false - }); + callback(this.adapterState); }.bind(this)); },
diff --git a/chrome/test/data/webui/settings/fake_bluetooth_private.js b/chrome/test/data/webui/settings/fake_bluetooth_private.js index 7b91b1d..7367da9 100644 --- a/chrome/test/data/webui/settings/fake_bluetooth_private.js +++ b/chrome/test/data/webui/settings/fake_bluetooth_private.js
@@ -14,18 +14,27 @@ */ function FakeBluetoothPrivate(bluetoothApi) { /** @private {!Bluetooth} */ this.bluetoothApi_ = bluetoothApi; + + /** @type {!Set<string>} */ this.connectedDevices_ = new Set(); + + /** @type {!Object<!chrome.bluetoothPrivate.SetPairingResponseOptions>} */ + this.pairingResponses_ = {}; } FakeBluetoothPrivate.prototype = { /** @override */ setAdapterState: function(state, opt_callback) { - this.bluetoothApi_.enabled = state.powered; + this.bluetoothApi_.adapterState = state; if (opt_callback) setTimeout(opt_callback); }, /** @override */ - setPairingResponse: assertNotReached, + setPairingResponse: function(options, opt_callback) { + this.pairingResponses_[options.device.address] = options; + if (opt_callback) + setTimeout(opt_callback); + }, /** @override */ disconnectAll: assertNotReached, @@ -37,7 +46,11 @@ setDiscoveryFilter: assertNotReached, /** @override */ - connect: assertNotReached, + connect: function(address, opt_callback) { + this.connectedDevices_.add(address); + if (opt_callback) + setTimeout(opt_callback); + }, /** @override */ pair: assertNotReached,
diff --git a/chrome/test/data/webui/settings/site_settings_category_tests.js b/chrome/test/data/webui/settings/site_settings_category_tests.js index 5c06d57..c82f668 100644 --- a/chrome/test/data/webui/settings/site_settings_category_tests.js +++ b/chrome/test/data/webui/settings/site_settings_category_tests.js
@@ -64,6 +64,32 @@ MockInteractions.tap(testElement.$.toggle); assertTrue(testElement.categoryEnabled); }); + + test('basic category tests', function() { + for (var key in settings.ContentSettingsTypes) { + var category = settings.ContentSettingsTypes[key]; + + // All categories have a textId, an icon, a title, and pref names. + assertNotEquals('', testElement.computeCategoryTextId(category)); + assertNotEquals( + '', testElement.computeIconForContentCategory(category)); + assertNotEquals( + '', testElement.computeTitleForContentCategory(category)); + assertNotEquals( + '', testElement.computeCategoryPrefName(category)); + assertNotEquals( + '', testElement.computeCategoryExceptionsPrefName(category)); + + assertNotEquals( + '', testElement.computeCategoryDesc(category, true, true)); + assertNotEquals( + '', testElement.computeCategoryDesc(category, true, false)); + assertNotEquals( + '', testElement.computeCategoryDesc(category, false, true)); + assertNotEquals( + '', testElement.computeCategoryDesc(category, false, false)); + } + }); }); }
diff --git a/components/components.gyp b/components/components.gyp index c83d0aa..8fef224 100644 --- a/components/components.gyp +++ b/components/components.gyp
@@ -74,7 +74,6 @@ 'query_parser.gypi', 'rappor.gypi', 'renderer_context_menu.gypi', - 'safe_browsing_db.gypi', 'search.gypi', 'search_engines.gypi', 'search_provider_logos.gypi', @@ -126,6 +125,7 @@ 'packed_ct_ev_whitelist.gypi', 'page_load_metrics.gypi', 'power.gypi', + 'safe_browsing_db.gypi', 'safe_json.gypi', 'visitedlink.gypi', 'wallpaper.gypi',
diff --git a/components/components_strings.grd b/components/components_strings.grd index 5603eda2..67c13574 100644 --- a/components/components_strings.grd +++ b/components/components_strings.grd
@@ -194,6 +194,7 @@ <part file="enhanced_bookmarks_strings.grdp" /> <part file="error_page_strings.grdp" /> <part file="flags_ui_strings.grdp" /> + <part file="history_ui_strings.grdp" /> <part file="omnibox_strings.grdp" /> <part file="password_manager_strings.grdp" /> <part file="pdf_strings.grdp" />
diff --git a/components/components_tests.gyp b/components/components_tests.gyp index f716178..e1654c94 100644 --- a/components/components_tests.gyp +++ b/components/components_tests.gyp
@@ -136,6 +136,7 @@ ], 'data_reduction_proxy_unittest_sources': [ 'data_reduction_proxy/content/browser/content_lofi_decider_unittest.cc', + 'data_reduction_proxy/content/browser/content_lofi_ui_service_unittest.cc', 'data_reduction_proxy/content/browser/data_reduction_proxy_message_filter_unittest.cc', 'data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol_unittest.cc', 'data_reduction_proxy/core/browser/data_reduction_proxy_bypass_stats_unittest.cc',
diff --git a/components/crash/content/browser/crash_handler_host_linux.cc b/components/crash/content/browser/crash_handler_host_linux.cc index ec4ae2f..b97b92c 100644 --- a/components/crash/content/browser/crash_handler_host_linux.cc +++ b/components/crash/content/browser/crash_handler_host_linux.cc
@@ -91,7 +91,7 @@ dumps_path_(dumps_path), upload_(upload), shutting_down_(false), - worker_pool_token_(BrowserThread::GetBlockingPool()->GetSequenceToken()) { + worker_pool_token_(base::SequencedWorkerPool::GetSequenceToken()) { int fds[2]; // We use SOCK_SEQPACKET rather than SOCK_DGRAM to prevent the process from // sending datagrams to other sockets on the system. The sandbox may prevent
diff --git a/components/data_reduction_proxy.gypi b/components/data_reduction_proxy.gypi index 9ff6000..67266c63 100644 --- a/components/data_reduction_proxy.gypi +++ b/components/data_reduction_proxy.gypi
@@ -81,6 +81,8 @@ 'data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h', 'data_reduction_proxy/core/common/data_reduction_proxy_switches.cc', 'data_reduction_proxy/core/common/data_reduction_proxy_switches.h', + 'data_reduction_proxy/core/common/lofi_decider.h', + 'data_reduction_proxy/core/common/lofi_ui_service.h', ], }, 'conditions': [ @@ -132,7 +134,6 @@ 'dependencies': [ '../base/base.gyp:base', '../content/content.gyp:content_browser', - '../skia/skia.gyp:skia', '../ui/base/ui_base.gyp:ui_base', 'components_resources.gyp:components_resources', 'components_strings.gyp:components_strings', @@ -175,12 +176,15 @@ 'dependencies': [ '../content/content.gyp:content_common', '../ipc/ipc.gyp:ipc', + '../skia/skia.gyp:skia', 'data_reduction_proxy_content_common', ], 'include_dirs': [ '..', ], 'sources': [ + 'data_reduction_proxy/content/browser/content_lofi_ui_service.cc', + 'data_reduction_proxy/content/browser/content_lofi_ui_service.h', 'data_reduction_proxy/content/browser/content_lofi_decider.cc', 'data_reduction_proxy/content/browser/content_lofi_decider.h', 'data_reduction_proxy/content/browser/data_reduction_proxy_message_filter.cc',
diff --git a/components/data_reduction_proxy/content/browser/BUILD.gn b/components/data_reduction_proxy/content/browser/BUILD.gn index fdc5ad9..13f0084 100644 --- a/components/data_reduction_proxy/content/browser/BUILD.gn +++ b/components/data_reduction_proxy/content/browser/BUILD.gn
@@ -6,6 +6,8 @@ sources = [ "content_lofi_decider.cc", "content_lofi_decider.h", + "content_lofi_ui_service.cc", + "content_lofi_ui_service.h", "data_reduction_proxy_message_filter.cc", "data_reduction_proxy_message_filter.h", ] @@ -46,6 +48,7 @@ testonly = true sources = [ "content_lofi_decider_unittest.cc", + "content_lofi_ui_service_unittest.cc", "data_reduction_proxy_message_filter_unittest.cc", ]
diff --git a/components/data_reduction_proxy/content/browser/content_lofi_ui_service.cc b/components/data_reduction_proxy/content/browser/content_lofi_ui_service.cc new file mode 100644 index 0000000..55229557 --- /dev/null +++ b/components/data_reduction_proxy/content/browser/content_lofi_ui_service.cc
@@ -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. + +#include "components/data_reduction_proxy/content/browser/content_lofi_ui_service.h" + +#include "base/bind.h" +#include "base/location.h" +#include "base/single_thread_task_runner.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/resource_request_info.h" +#include "content/public/browser/web_contents.h" +#include "net/url_request/url_request.h" + +namespace data_reduction_proxy { + +ContentLoFiUIService::ContentLoFiUIService( + const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner, + const OnLoFiResponseReceivedCallback& + notify_lofi_response_received_callback) + : ui_task_runner_(ui_task_runner), + on_lofi_response_received_callback_( + notify_lofi_response_received_callback) { + DCHECK(!on_lofi_response_received_callback_.is_null()); +} + +ContentLoFiUIService::~ContentLoFiUIService() {} + +void ContentLoFiUIService::OnLoFiReponseReceived( + const net::URLRequest& request) { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + int render_process_id = -1; + int render_frame_id = -1; + if (content::ResourceRequestInfo::GetRenderFrameForRequest( + &request, &render_process_id, &render_frame_id)) { + ui_task_runner_->PostTask( + FROM_HERE, + base::Bind(&ContentLoFiUIService::OnLoFiResponseReceivedOnUIThread, + base::Unretained(this), render_process_id, render_frame_id)); + } +} + +void ContentLoFiUIService::OnLoFiResponseReceivedOnUIThread( + int render_process_id, + int render_frame_id) { + DCHECK(ui_task_runner_->BelongsToCurrentThread()); + content::RenderFrameHost* frame = + content::RenderFrameHost::FromID(render_process_id, render_frame_id); + if (frame) { + DCHECK(!on_lofi_response_received_callback_.is_null()); + content::WebContents* web_contents = + content::WebContents::FromRenderFrameHost(frame); + on_lofi_response_received_callback_.Run(web_contents); + } +} + +} // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/content/browser/content_lofi_ui_service.h b/components/data_reduction_proxy/content/browser/content_lofi_ui_service.h new file mode 100644 index 0000000..c41779b --- /dev/null +++ b/components/data_reduction_proxy/content/browser/content_lofi_ui_service.h
@@ -0,0 +1,60 @@ +// 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_DATA_REDUCTION_PROXY_CONTENT_BROWSER_CONTENT_LOFI_UI_SERVICE_H_ +#define COMPONENTS_DATA_REDUCTION_PROXY_CONTENT_BROWSER_CONTENT_LOFI_UI_SERVICE_H_ + +#include "base/callback.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "components/data_reduction_proxy/core/common/lofi_ui_service.h" + +namespace base { +class SingleThreadTaskRunner; +} + +namespace content { +class WebContents; +} + +namespace net { +class URLRequest; +} + +namespace data_reduction_proxy { + +typedef base::Callback<void(content::WebContents* web_contents)> + OnLoFiResponseReceivedCallback; + +// Passes notifications to the UI thread that a Lo-Fi response has been +// received. These notifications may be used to show Lo-Fi UI. This object lives +// on the IO thread and OnLoFiReponseReceived should be called from there. +class ContentLoFiUIService : public LoFiUIService { + public: + ContentLoFiUIService( + const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner, + const OnLoFiResponseReceivedCallback& on_lofi_response_received_callback); + ~ContentLoFiUIService() override; + + // LoFiUIService implementation: + void OnLoFiReponseReceived(const net::URLRequest& request) override; + + private: + // Using the |render_process_id| and |render_frame_id|, gets the associated + // WebContents if it exists and runs the + // |notify_lofi_response_received_callback_|. + void OnLoFiResponseReceivedOnUIThread(int render_process_id, + int render_frame_id); + + // A task runner to post calls to OnLoFiReponseReceivedOnUI on the UI + // thread. + const scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; + const OnLoFiResponseReceivedCallback on_lofi_response_received_callback_; + + DISALLOW_COPY_AND_ASSIGN(ContentLoFiUIService); +}; + +} // namespace data_reduction_proxy + +#endif // COMPONENTS_DATA_REDUCTION_PROXY_CONTENT_BROWSER_CONTENT_LOFI_UI_SERVICE_H_
diff --git a/components/data_reduction_proxy/content/browser/content_lofi_ui_service_unittest.cc b/components/data_reduction_proxy/content/browser/content_lofi_ui_service_unittest.cc new file mode 100644 index 0000000..3ed2f3c4 --- /dev/null +++ b/components/data_reduction_proxy/content/browser/content_lofi_ui_service_unittest.cc
@@ -0,0 +1,111 @@ +// 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/data_reduction_proxy/content/browser/content_lofi_ui_service.h" + +#include <stddef.h> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/resource_request_info.h" +#include "content/public/browser/web_contents.h" +#include "content/public/test/test_renderer_host.h" +#include "net/socket/socket_test_util.h" +#include "net/url_request/url_request.h" +#include "net/url_request/url_request_test_util.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace data_reduction_proxy { + +class ContentLoFiUIServiceTest : public content::RenderViewHostTestHarness { + public: + ContentLoFiUIServiceTest() : callback_called_(false) { + // Cannot use IO_MAIN_LOOP with RenderViewHostTestHarness. + SetThreadBundleOptions(content::TestBrowserThreadBundle::REAL_IO_THREAD); + } + + void RunTestOnIOThread(base::RunLoop* ui_run_loop) { + ASSERT_TRUE(ui_run_loop); + EXPECT_TRUE( + content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); + + net::TestURLRequestContext context(true); + net::MockClientSocketFactory mock_socket_factory; + net::TestDelegate delegate; + context.set_client_socket_factory(&mock_socket_factory); + context.Init(); + + content_lofi_ui_service_.reset(new ContentLoFiUIService( + content::BrowserThread::GetMessageLoopProxyForThread( + content::BrowserThread::UI), + base::Bind(&ContentLoFiUIServiceTest::OnLoFiResponseReceivedCallback, + base::Unretained(this)))); + + scoped_ptr<net::URLRequest> request = CreateRequest(context, &delegate); + + content_lofi_ui_service_->OnLoFiReponseReceived(*request); + + content::BrowserThread::PostTask( + content::BrowserThread::UI, FROM_HERE, + base::Bind(&base::RunLoop::Quit, base::Unretained(ui_run_loop))); + } + + scoped_ptr<net::URLRequest> CreateRequest( + const net::TestURLRequestContext& context, + net::TestDelegate* delegate) { + EXPECT_TRUE( + content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); + + scoped_ptr<net::URLRequest> request = context.CreateRequest( + GURL("http://www.google.com/"), net::IDLE, delegate); + + content::ResourceRequestInfo::AllocateForTesting( + request.get(), content::RESOURCE_TYPE_SUB_FRAME, NULL, + web_contents()->GetMainFrame()->GetProcess()->GetID(), -1, + web_contents()->GetMainFrame()->GetRoutingID(), + false, // is_main_frame + false, // parent_is_main_frame + false, // allow_download + false, // is_async + true); // is_using_lofi + + return request; + } + + void OnLoFiResponseReceivedCallback(content::WebContents* web_contents) { + EXPECT_TRUE( + content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + callback_called_ = true; + } + + void VerifyOnLoFiResponseReceivedCallback() { + EXPECT_TRUE( + content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + EXPECT_TRUE(callback_called_); + } + + private: + scoped_ptr<ContentLoFiUIService> content_lofi_ui_service_; + bool callback_called_; +}; + +TEST_F(ContentLoFiUIServiceTest, OnLoFiResponseReceived) { + base::RunLoop ui_run_loop; + content::BrowserThread::PostTask( + content::BrowserThread::IO, FROM_HERE, + base::Bind(&ContentLoFiUIServiceTest::RunTestOnIOThread, + base::Unretained(this), &ui_run_loop)); + ui_run_loop.Run(); + base::MessageLoop::current()->RunUntilIdle(); + VerifyOnLoFiResponseReceivedCallback(); +} + +} // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc index 38662322..d096c17 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc
@@ -4,7 +4,6 @@ #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h" -#include <string> #include <utility> #include <vector> @@ -14,7 +13,6 @@ #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "base/metrics/histogram_macros.h" -#include "base/prefs/pref_change_registrar.h" #include "base/prefs/pref_service.h" #include "base/prefs/scoped_user_pref_update.h" #include "base/strings/string_number_conversions.h" @@ -75,31 +73,10 @@ void AddInt64ToListPref(size_t index, int64_t length, base::ListValue* list_update) { - int64_t value = 0; - std::string old_string_value; - bool rv = list_update->GetString(index, &old_string_value); - DCHECK(rv); - if (rv) { - rv = base::StringToInt64(old_string_value, &value); - DCHECK(rv); - } - value += length; + int64_t value = GetInt64PrefValue(*list_update, index) + length; list_update->Set(index, new base::StringValue(base::Int64ToString(value))); } -int64_t ListPrefInt64Value(const base::ListValue& list_update, size_t index) { - std::string string_value; - if (!list_update.GetString(index, &string_value)) { - NOTREACHED(); - return 0; - } - - int64_t value = 0; - bool rv = base::StringToInt64(string_value, &value); - DCHECK(rv); - return value; -} - // DailyContentLengthUpdate maintains a data saving pref. The pref is a list // of |kNumDaysInHistory| elements of daily total content lengths for the past // |kNumDaysInHistory| days. @@ -246,30 +223,48 @@ } } -class DailyContentLengthUpdate { - public: - DailyContentLengthUpdate(base::ListValue* update) - : update_(update) {} +} // namespace - void UpdateForDataChange(int days_since_last_update) { - // New empty lists may have been created. Maintain the invariant that - // there should be exactly |kNumDaysInHistory| days in the histories. - MaintainContentLengthPrefsWindow(update_, kNumDaysInHistory); +class DataReductionProxyCompressionStats::DailyContentLengthUpdate { + public: + DailyContentLengthUpdate( + DataReductionProxyCompressionStats* compression_stats, + const char* pref_path) + : update_(nullptr), + compression_stats_(compression_stats), + pref_path_(pref_path) {} + + void UpdateForDateChange(int days_since_last_update) { if (days_since_last_update) { + MaybeInitialize(); MaintainContentLengthPrefForDateChange(days_since_last_update); } } // Update the lengths for the current day. void Add(int64_t content_length) { - AddInt64ToListPref(kNumDaysInHistory - 1, content_length, update_); + if (content_length != 0) { + MaybeInitialize(); + AddInt64ToListPref(kNumDaysInHistory - 1, content_length, update_); + } } int64_t GetListPrefValue(size_t index) { - return ListPrefInt64Value(*update_, index); + MaybeInitialize(); + return GetInt64PrefValue(*update_, index); } private: + void MaybeInitialize() { + if (update_) + return; + + update_ = compression_stats_->GetList(pref_path_); + // New empty lists may have been created. Maintain the invariant that + // there should be exactly |kNumDaysInHistory| days in the histories. + MaintainContentLengthPrefsWindow(update_, kNumDaysInHistory); + } + // Update the list for date change and ensure the list has exactly |length| // elements. The last entry in the list will be for the current day after // the update. @@ -304,7 +299,14 @@ MaintainContentLengthPrefsWindow(update_, kNumDaysInHistory); } + // Non-owned. Lazily initialized, set to nullptr until initialized. base::ListValue* update_; + // Non-owned pointer. + DataReductionProxyCompressionStats* compression_stats_; + // The path of the content length pref for |this|. + const char* pref_path_; + + DISALLOW_COPY_AND_ASSIGN(DailyContentLengthUpdate); }; // DailyDataSavingUpdate maintains a pair of data saving prefs, original_update_ @@ -312,16 +314,17 @@ // of daily total original content lengths for the past |kNumDaysInHistory| // days. pref_received is the corresponding list of the daily total received // content lengths. -class DailyDataSavingUpdate { +class DataReductionProxyCompressionStats::DailyDataSavingUpdate { public: - DailyDataSavingUpdate(base::ListValue* original, - base::ListValue* received) - : original_(original), - received_(received) {} + DailyDataSavingUpdate(DataReductionProxyCompressionStats* compression_stats, + const char* original_pref_path, + const char* received_pref_path) + : original_(compression_stats, original_pref_path), + received_(compression_stats, received_pref_path) {} - void UpdateForDataChange(int days_since_last_update) { - original_.UpdateForDataChange(days_since_last_update); - received_.UpdateForDataChange(days_since_last_update); + void UpdateForDateChange(int days_since_last_update) { + original_.UpdateForDateChange(days_since_last_update); + received_.UpdateForDateChange(days_since_last_update); } // Update the lengths for the current day. @@ -340,10 +343,9 @@ private: DailyContentLengthUpdate original_; DailyContentLengthUpdate received_; -}; -// Report UMA metrics for daily data reductions. -} // namespace + DISALLOW_COPY_AND_ASSIGN(DailyDataSavingUpdate); +}; DataReductionProxyCompressionStats::DataReductionProxyCompressionStats( DataReductionProxyService* service, @@ -352,7 +354,6 @@ : service_(service), pref_service_(prefs), delay_(delay), - pref_change_registrar_(new PrefChangeRegistrar()), data_usage_map_is_dirty_(false), current_data_usage_load_status_(NOT_LOADED), weak_factory_(this) { @@ -371,7 +372,7 @@ net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this); WritePrefs(); - pref_change_registrar_->RemoveAll(); + pref_change_registrar_.RemoveAll(); } void DataReductionProxyCompressionStats::Init() { @@ -447,8 +448,9 @@ ClearDataSavingStatistics(); } - pref_change_registrar_->Init(pref_service_); - pref_change_registrar_->Add(prefs::kUpdateDailyReceivedContentLengths, + pref_change_registrar_.Init(pref_service_); + pref_change_registrar_.Add( + prefs::kUpdateDailyReceivedContentLengths, base::Bind(&DataReductionProxyCompressionStats::OnUpdateContentLengths, weak_factory_.GetWeakPtr())); } @@ -472,16 +474,11 @@ DCHECK(thread_checker_.CalledOnValidThread()); TRACE_EVENT0("loader", "DataReductionProxyCompressionStats::UpdateContentLengths") - int64_t total_received = - GetInt64(data_reduction_proxy::prefs::kHttpReceivedContentLength); - int64_t total_original = - GetInt64(data_reduction_proxy::prefs::kHttpOriginalContentLength); - total_received += data_used; - total_original += original_size; - SetInt64(data_reduction_proxy::prefs::kHttpReceivedContentLength, - total_received); - SetInt64(data_reduction_proxy::prefs::kHttpOriginalContentLength, - total_original); + + IncreaseInt64Pref(data_reduction_proxy::prefs::kHttpReceivedContentLength, + data_used); + IncreaseInt64Pref(data_reduction_proxy::prefs::kHttpOriginalContentLength, + original_size); RecordDataUsage(data_usage_host, data_used, original_size, base::Time::Now()); RecordRequestSizePrefs(data_used, original_size, data_reduction_proxy_enabled, @@ -518,10 +515,10 @@ pref_map_[pref_path] = pref_value; } -void DataReductionProxyCompressionStats::IncrementInt64Pref( +void DataReductionProxyCompressionStats::IncreaseInt64Pref( const char* pref_path, - int64_t pref_increment) { - SetInt64(pref_path, GetInt64(pref_path) + pref_increment); + int64_t delta) { + SetInt64(pref_path, GetInt64(pref_path) + delta); } base::ListValue* DataReductionProxyCompressionStats::GetList( @@ -674,8 +671,8 @@ // requiring a data migration. DCHECK(data_usage->connection_usage_size() == 0 || data_usage->connection_usage_size() == 1); - for (auto connection_usage : data_usage->connection_usage()) { - for (auto site_usage : connection_usage.site_usage()) { + for (const auto& connection_usage : data_usage->connection_usage()) { + for (const auto& site_usage : connection_usage.site_usage()) { data_usage_map_.set(site_usage.hostname(), make_scoped_ptr(new PerSiteDataUsage(site_usage))); } @@ -726,25 +723,7 @@ const base::ListValue& from_list, base::ListValue* to_list) { to_list->Clear(); - for (size_t i = 0; i < from_list.GetSize(); ++i) { - to_list->Set(i, new base::StringValue(base::Int64ToString( - GetListPrefInt64Value(from_list, i)))); - } -} - -int64_t DataReductionProxyCompressionStats::GetListPrefInt64Value( - const base::ListValue& list, - size_t index) { - std::string string_value; - if (!list.GetString(index, &string_value)) { - NOTREACHED(); - return 0; - } - - int64_t value = 0; - bool rv = base::StringToInt64(string_value, &value); - DCHECK(rv); - return value; + from_list.CreateDeepCopy()->Swap(to_list); } void DataReductionProxyCompressionStats::RecordRequestSizePrefs( @@ -779,36 +758,29 @@ base::Time midnight = now.LocalMidnight(); DailyDataSavingUpdate total( - GetList(data_reduction_proxy::prefs::kDailyHttpOriginalContentLength), - GetList(data_reduction_proxy::prefs::kDailyHttpReceivedContentLength)); - + this, data_reduction_proxy::prefs::kDailyHttpOriginalContentLength, + data_reduction_proxy::prefs::kDailyHttpReceivedContentLength); DailyDataSavingUpdate proxy_enabled( - GetList(data_reduction_proxy::prefs:: - kDailyOriginalContentLengthWithDataReductionProxyEnabled), - GetList(data_reduction_proxy::prefs:: - kDailyContentLengthWithDataReductionProxyEnabled)); - + this, data_reduction_proxy::prefs:: + kDailyOriginalContentLengthWithDataReductionProxyEnabled, + data_reduction_proxy::prefs:: + kDailyContentLengthWithDataReductionProxyEnabled); DailyDataSavingUpdate via_proxy( - GetList(data_reduction_proxy::prefs:: - kDailyOriginalContentLengthViaDataReductionProxy), - GetList(data_reduction_proxy::prefs:: - kDailyContentLengthViaDataReductionProxy)); - + this, data_reduction_proxy::prefs:: + kDailyOriginalContentLengthViaDataReductionProxy, + data_reduction_proxy::prefs::kDailyContentLengthViaDataReductionProxy); DailyContentLengthUpdate https( - GetList(data_reduction_proxy::prefs:: - kDailyContentLengthHttpsWithDataReductionProxyEnabled)); - + this, data_reduction_proxy::prefs:: + kDailyContentLengthHttpsWithDataReductionProxyEnabled); DailyContentLengthUpdate short_bypass( - GetList(data_reduction_proxy::prefs:: - kDailyContentLengthShortBypassWithDataReductionProxyEnabled)); - + this, data_reduction_proxy::prefs:: + kDailyContentLengthShortBypassWithDataReductionProxyEnabled); DailyContentLengthUpdate long_bypass( - GetList(data_reduction_proxy::prefs:: - kDailyContentLengthLongBypassWithDataReductionProxyEnabled)); - + this, data_reduction_proxy::prefs:: + kDailyContentLengthLongBypassWithDataReductionProxyEnabled); DailyContentLengthUpdate unknown( - GetList(data_reduction_proxy::prefs:: - kDailyContentLengthUnknownWithDataReductionProxyEnabled)); + this, data_reduction_proxy::prefs:: + kDailyContentLengthUnknownWithDataReductionProxyEnabled); int days_since_last_update = (midnight - then_midnight).InDays(); if (days_since_last_update) { @@ -985,13 +957,14 @@ 0); } } - total.UpdateForDataChange(days_since_last_update); - proxy_enabled.UpdateForDataChange(days_since_last_update); - via_proxy.UpdateForDataChange(days_since_last_update); - https.UpdateForDataChange(days_since_last_update); - short_bypass.UpdateForDataChange(days_since_last_update); - long_bypass.UpdateForDataChange(days_since_last_update); - unknown.UpdateForDataChange(days_since_last_update); + + total.UpdateForDateChange(days_since_last_update); + proxy_enabled.UpdateForDateChange(days_since_last_update); + via_proxy.UpdateForDateChange(days_since_last_update); + https.UpdateForDateChange(days_since_last_update); + short_bypass.UpdateForDateChange(days_since_last_update); + long_bypass.UpdateForDateChange(days_since_last_update); + unknown.UpdateForDateChange(days_since_last_update); total.Add(original_size, data_used); if (with_data_reduction_proxy_enabled) { @@ -1082,17 +1055,17 @@ bool via_data_reduction_proxy, const char* original_size_via_proxy_pref, const char* received_size_via_proxy_pref) { - IncrementInt64Pref(original_size_pref, original_size); - IncrementInt64Pref(received_size_pref, received_size); + IncreaseInt64Pref(original_size_pref, original_size); + IncreaseInt64Pref(received_size_pref, received_size); if (data_reduction_proxy_enabled) { - IncrementInt64Pref(original_size_with_proxy_enabled_pref, original_size); - IncrementInt64Pref(recevied_size_with_proxy_enabled_pref, received_size); + IncreaseInt64Pref(original_size_with_proxy_enabled_pref, original_size); + IncreaseInt64Pref(recevied_size_with_proxy_enabled_pref, received_size); } if (via_data_reduction_proxy) { - IncrementInt64Pref(original_size_via_proxy_pref, original_size); - IncrementInt64Pref(received_size_via_proxy_pref, received_size); + IncreaseInt64Pref(original_size_via_proxy_pref, original_size); + IncreaseInt64Pref(received_size_via_proxy_pref, received_size); } }
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h index bea6d32..3aa182a 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h
@@ -14,7 +14,9 @@ #include "base/containers/scoped_ptr_hash_map.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/prefs/pref_change_registrar.h" #include "base/prefs/pref_member.h" #include "base/threading/thread_checker.h" #include "base/time/time.h" @@ -25,7 +27,6 @@ #include "components/data_reduction_proxy/proto/data_store.pb.h" #include "net/base/network_change_notifier.h" -class PrefChangeRegistrar; class PrefService; namespace base { @@ -33,20 +34,6 @@ class Value; } -// Custom std::hash for |ConnectionType| so that it can be used as a key in -// |ScopedPtrHashMap|. -namespace BASE_HASH_NAMESPACE { - -template <> -struct hash<data_reduction_proxy::ConnectionType> { - std::size_t operator()( - const data_reduction_proxy::ConnectionType& type) const { - return hash<int>()(type); - } -}; - -} // namespace BASE_HASH_NAMESPACE - namespace data_reduction_proxy { class DataReductionProxyService; @@ -144,6 +131,9 @@ typedef base::ScopedPtrHashMap<const char*, scoped_ptr<base::ListValue>> DataReductionProxyListPrefMap; + class DailyContentLengthUpdate; + class DailyDataSavingUpdate; + // Loads all data_reduction_proxy::prefs into the |pref_map_| and // |list_pref_map_|. void Init(); @@ -165,9 +155,9 @@ // The pref is later written to |pref service_|. void SetInt64(const char* pref_path, int64_t pref_value); - // Increments the pref value in the |DataReductionProxyPrefMap| map. + // Increases the pref value in the |DataReductionProxyPrefMap| map. // The pref is later written to |pref service_|. - void IncrementInt64Pref(const char* pref_path, int64_t pref_increment); + void IncreaseInt64Pref(const char* pref_path, int64_t delta); // Gets the pref list at |pref_path| from the |DataReductionProxyPrefMap|. base::ListValue* GetList(const char* pref_path); @@ -185,11 +175,6 @@ void TransferList(const base::ListValue& from_list, base::ListValue* to_list); - // Gets an int64_t, stored as a string, in a ListPref at the specified - // index. - int64_t GetListPrefInt64Value(const base::ListValue& list_update, - size_t index); - // Records content length updates to prefs. void RecordRequestSizePrefs(int64_t compressed_size, int64_t original_size, @@ -252,7 +237,7 @@ const base::TimeDelta delay_; DataReductionProxyPrefMap pref_map_; DataReductionProxyListPrefMap list_pref_map_; - scoped_ptr<PrefChangeRegistrar> pref_change_registrar_; + PrefChangeRegistrar pref_change_registrar_; BooleanPrefMember data_usage_reporting_enabled_; ConnectionType connection_type_;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h index 2d96ea2..de383f4 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h
@@ -21,6 +21,7 @@ #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_storage_delegate.h" #include "components/data_reduction_proxy/core/common/lofi_decider.h" +#include "components/data_reduction_proxy/core/common/lofi_ui_service.h" namespace base { class Value; @@ -176,6 +177,13 @@ lofi_decider_ = std::move(lofi_decider); } + LoFiUIService* lofi_ui_service() const { return lofi_ui_service_.get(); } + + // Takes ownership of |lofi_ui_service|. + void set_lofi_ui_service(scoped_ptr<LoFiUIService> lofi_ui_service) const { + lofi_ui_service_ = std::move(lofi_ui_service); + } + private: friend class TestDataReductionProxyIOData; FRIEND_TEST_ALL_PREFIXES(DataReductionProxyIODataTest, TestConstruction); @@ -216,6 +224,9 @@ // Handles getting if a request is in Lo-Fi mode. mutable scoped_ptr<LoFiDecider> lofi_decider_; + // Handles showing Lo-Fi UI when a Lo-Fi response is received. + mutable scoped_ptr<LoFiUIService> lofi_ui_service_; + // Creates Data Reduction Proxy-related events for logging. scoped_ptr<DataReductionProxyEventCreator> event_creator_;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc index f998339..0222d8c 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc
@@ -202,6 +202,13 @@ if (data_reduction_proxy_bypass_stats_) data_reduction_proxy_bypass_stats_->OnUrlRequestCompleted(request, started); + if (data_reduction_proxy_io_data_ && request->response_info().headers && + request->response_headers()->HasHeaderValue( + chrome_proxy_header(), chrome_proxy_lo_fi_directive())) { + data_reduction_proxy_io_data_->lofi_ui_service()->OnLoFiReponseReceived( + *request); + } + // For better accuracy, we use the actual bytes read instead of the length // specified with the Content-Length header, which may be inaccurate, // or missing, as is the case with chunked encoding.
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc index 440053c9..20d9861 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
@@ -111,6 +111,21 @@ bool should_request_lofi_resource_; }; +class TestLoFiUIService : public LoFiUIService { + public: + TestLoFiUIService() : on_lofi_response_(false) {} + ~TestLoFiUIService() override {} + + bool DidNotifyLoFiResponse() const { return on_lofi_response_; } + + void OnLoFiReponseReceived(const net::URLRequest& request) override { + on_lofi_response_ = true; + } + + private: + bool on_lofi_response_; +}; + } // namespace class DataReductionProxyNetworkDelegateTest : public testing::Test { @@ -142,6 +157,10 @@ scoped_ptr<TestLoFiDecider> lofi_decider(new TestLoFiDecider()); lofi_decider_ = lofi_decider.get(); io_data()->set_lofi_decider(std::move(lofi_decider)); + + scoped_ptr<TestLoFiUIService> lofi_ui_service(new TestLoFiUIService()); + lofi_ui_service_ = lofi_ui_service.get(); + io_data()->set_lofi_ui_service(std::move(lofi_ui_service)); } const net::ProxyConfig& GetProxyConfig() const { return config_; } @@ -165,6 +184,10 @@ test_context_->settings()->WasLoFiModeActiveOnMainFrame()); } + void VerifyDidNotifyLoFiResponse(bool lofi_response) { + EXPECT_EQ(lofi_response, lofi_ui_service_->DidNotifyLoFiResponse()); + } + int64_t total_received_bytes() { return data_reduction_proxy_network_delegate_->total_received_bytes_; } @@ -238,6 +261,7 @@ net::ProxyConfig config_; net::NetworkDelegate* network_delegate_; TestLoFiDecider* lofi_decider_; + TestLoFiUIService* lofi_ui_service_; scoped_ptr<DataReductionProxyTestContext> test_context_; scoped_ptr<DataReductionProxyBypassStats> bypass_stats_; }; @@ -680,4 +704,40 @@ total_original_received_bytes()); } +TEST_F(DataReductionProxyNetworkDelegateTest, OnCompletedInternalLoFi) { + const int64_t kResponseContentLength = 140; + const int64_t kOriginalContentLength = 200; + + set_network_delegate(data_reduction_proxy_network_delegate_.get()); + + // Enable Lo-Fi. + const struct { + bool lofi_response; + } tests[] = { + {false}, {true}, + }; + + for (size_t i = 0; i < arraysize(tests); ++i) { + std::string raw_headers = + "HTTP/1.1 200 OK\n" + "Date: Wed, 28 Nov 2007 09:40:09 GMT\n" + "Expires: Mon, 24 Nov 2014 12:45:26 GMT\n" + "Via: 1.1 Chrome-Compression-Proxy\n" + "x-original-content-length: " + + base::Int64ToString(kOriginalContentLength) + "\n"; + + if (tests[i].lofi_response) + raw_headers += "Chrome-Proxy: q=low\n"; + + HeadersToRaw(&raw_headers); + std::string response_headers = + net::HttpUtil::ConvertHeadersBackToHTTPResponse(raw_headers); + + FetchURLRequest(GURL("http://www.google.com/"), response_headers, + kResponseContentLength); + + VerifyDidNotifyLoFiResponse(tests[i].lofi_response); + } +} + } // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/common/BUILD.gn b/components/data_reduction_proxy/core/common/BUILD.gn index 5a9abc9..b1951ad3 100644 --- a/components/data_reduction_proxy/core/common/BUILD.gn +++ b/components/data_reduction_proxy/core/common/BUILD.gn
@@ -27,6 +27,8 @@ "data_reduction_proxy_pref_names.h", "data_reduction_proxy_switches.cc", "data_reduction_proxy_switches.h", + "lofi_decider.h", + "lofi_ui_service.h", ] public_deps = [
diff --git a/components/data_reduction_proxy/core/common/lofi_ui_service.h b/components/data_reduction_proxy/core/common/lofi_ui_service.h new file mode 100644 index 0000000..656dab4d --- /dev/null +++ b/components/data_reduction_proxy/core/common/lofi_ui_service.h
@@ -0,0 +1,28 @@ +// 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_DATA_REDUCTION_PROXY_CORE_BROWSER_LOFI_UI_SERVICE_H_ +#define COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_LOFI_UI_SERVICE_H_ + +#include "base/macros.h" + +namespace net { +class URLRequest; +} + +namespace data_reduction_proxy { + +// Passes notifications to the UI thread that a Lo-Fi response has been +// received. These notifications may be used to show Lo-Fi UI. +class LoFiUIService { + public: + virtual ~LoFiUIService() {} + + // Notifies the UI thread that |request| has a Lo-Fi response. + virtual void OnLoFiReponseReceived(const net::URLRequest& request) = 0; +}; + +} // namespace data_reduction_proxy + +#endif // COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_LOFI_UI_SERVICE_H_
diff --git a/components/history_ui_strings.grdp b/components/history_ui_strings.grdp new file mode 100644 index 0000000..b36bf0c --- /dev/null +++ b/components/history_ui_strings.grdp
@@ -0,0 +1,155 @@ +<?xml version="1.0" encoding="utf-8"?> +<grit-part> + + <!-- History UI --> + <message name="IDS_HISTORY_ACTION_MENU_DESCRIPTION" desc="Text used to identify the history entry drop-down menu for screen readers"> + Actions + </message> + <message name="IDS_HISTORY_BLOCKED_VISIT_TEXT" desc="Text that describes an attempted visit."> + Blocked attempt <ph name="BEGIN_LINK"><a target="_top" href="$1" id="$2"></ph> to visit a page on <ph name="DOMAIN">$3<ex>google.com</ex></ph><ph name="END_LINK"></a><ex></a></ex></ph>. + </message> + <message name="IDS_HISTORY_BROWSERESULTS" desc="Title of browsing results page"> + History + </message> + <message name="IDS_HISTORY_CONTINUED" desc="Shown after the date if the data is continued from the previous page"> + (Cont.) + </message> + <message name="IDS_HISTORY_DATE_WITH_RELATIVE_TIME" desc="In the history view, some dates are formatted as 'Today - Wednesday, Nov 7, 2007"> + <ph name="RELATIVE_DATE">$1<ex>Today</ex></ph> - <ph name="FULL_DATE">$2<ex>Wednesday, Nov 7, 2007</ex></ph> + </message> + <message name="IDS_HISTORY_DELETE_PRIOR_VISITS_CONFIRM_BUTTON" desc="Text for the button used to confirm the dialog asking if they would like to proceed with deletion."> + Remove + </message> + <message name="IDS_HISTORY_DELETE_PRIOR_VISITS_WARNING" desc="Warning shown before deleting visits from the history page (reminding the user they can also use incognito mode, which doesn't store history)"> + Are you sure you want to delete these pages from your history? + +Psst! Incognito mode <ph name="SHORTCUT_KEY">$1<ex>(Ctrl+Shift+N)</ex></ph> may come in handy next time. + </message> + <message name="IDS_HISTORY_DELETE_PRIOR_VISITS_WARNING_NO_INCOGNITO" desc="Warning shown before deleting from the history page"> + Are you sure you want to delete these pages from your history? + </message> + <message name="IDS_HISTORY_ENTRY_BOOKMARKED" desc="Whether a history entry is bookmarked."> + Bookmarked + </message> + <message name="IDS_HISTORY_ENTRY_SUMMARY" desc="Summary of all the fields in a history entry (time, whether the entry is bookmarked, title, and domain)."> + <ph name="TIME"><ex>3:14</ex>$1</ph> <ph name="BOOKMARKED"><ex>bookmarked</ex>$2</ph> <ph name="TITLE"><ex>PI: The Magical Number</ex>$3</ph> <ph name="DOMAIN"><ex>pi.com</ex>$4</ph> + </message> + <message name="IDS_HISTORY_FILTER_ALLOW_ITEMS" desc="Title of the button that allows the user to allow the selected history items"> + Allow items + </message> + <message name="IDS_HISTORY_FILTER_ALLOWED" desc="Text that shows that an entry is allowed."> + Allowed + </message> + <message name="IDS_HISTORY_FILTER_BLOCK_ITEMS" desc="Title of the button that allows the user to block the selected history items"> + Block items + </message> + <message name="IDS_HISTORY_FILTER_BLOCKED" desc="Text that shows that an entry is blocked."> + Blocked + </message> + <message name="IDS_HISTORY_FOUND_SEARCH_RESULTS" desc="Message shown when zero or multiple search results are found."> + Found <ph name="NUMBER_OF_RESULTS">$1</ph> <ph name="SEARCH_RESULTS"><ex>search results</ex>$2</ph> for '<ph name="SEARCH_STRING">$3</ph>'. + </message> + <message name="IDS_HISTORY_GROUP_BY_DOMAIN_LABEL" desc="Label for the checkbox that toggles the mode to group history visits by domain."> + Group domains + </message> + <message name="IDS_HISTORY_HAS_SYNCED_RESULTS" desc="The notification at the top of the history page indicating that it is showing visits synced from other devices."> + Showing history from your signed-in devices. <ph name="BEGIN_LINK"><a href="https://support.google.com/chrome/?p=sync_history&hl=[GRITLANGCODE]"></ph>Learn more<ph name="END_LINK"></a><ex></a></ex></ph> + </message> + <message name="IDS_HISTORY_IN_CONTENT_PACK" desc="Text that shows that an entry is in a content pack."> + In content pack + </message> + <message name="IDS_HISTORY_INTERVAL" desc="A history interval shown in the title. The dates are already localized strings."> + <ph name="START_DATE">$1<ex>Wednesday, Aug. 1, 2012</ex></ph> to <ph name="END_DATE">$2<ex>Thursday, Aug. 30, 2012</ex></ph> + </message> + <message name="IDS_HISTORY_LOADING" desc="Text shown when we're loading the user's history"> + Loading... + </message> + <message name="IDS_HISTORY_MORE_FROM_SITE" desc="Command in the history entry drop-down menu. Shows more history entries from the same site."> + More from this site + </message> + <message name="IDS_HISTORY_NEWER" desc="HTML text shown as page navigation tool to take the user back to the more recent page"> + Newer + </message> + <message name="IDS_HISTORY_NEWEST" desc="HTML text shown as page navigation tool to take the user to the top of their history"> + Newest + </message> + <message name="IDS_HISTORY_NO_RESULTS" desc="Text shown when no history entries are found."> + No history entries found. + </message> + <message name="IDS_HISTORY_NO_SEARCH_RESULTS" desc="Text shown when no history search results have been found"> + No search results found. + </message> + <message name="IDS_HISTORY_NO_SYNCED_RESULTS" desc="The notification at the top of the history page indicating that it does not include visits from other devices."> + Showing history from this device. <ph name="BEGIN_LINK"><a href="https://support.google.com/chrome/?p=sync_history&hl=[GRITLANGCODE]"></ph>Learn more<ph name="END_LINK"></a><ex></a></ex></ph> + </message> + <message name="IDS_HISTORY_NUMBER_VISITS" desc="Format string for the number of visits of a site."> + (<ph name="NUMBER_VISITS">$1<ex>3</ex></ph>) + </message> + <message name="IDS_HISTORY_OLDER" desc="HTML text shown as page navigation tool to take the user forward to their older history"> + Older + </message> + <message name="IDS_HISTORY_OPEN_CLEAR_BROWSING_DATA_DIALOG" desc="Title of the button that will open the clear browsing data dialog."> + Clear browsing data... + </message> + <message name="IDS_HISTORY_OTHER_DEVICES_X_MORE" desc="In the 'Other Sessions' section of the history page, the label for showing that X more tabs are available for a session."> + <ph name="NUM_TABS_MORE">$1<ex>42</ex></ph> more... + </message> + <message name="IDS_HISTORY_OTHER_SESSIONS_COLLAPSE_SESSION" desc="In the 'Other Sessions' menu on the history page, the label for the command to collapse (hide) the list of windows and tabs in a session."> + Collapse list + </message> + <message name="IDS_HISTORY_OTHER_SESSIONS_EXPAND_SESSION" desc="In the 'Other Sessions' menu on the history page, the label for the command to expand (uncollapse) the list of windows and tabs in a session."> + Expand list + </message> + <message name="IDS_HISTORY_OTHER_SESSIONS_OPEN_ALL" desc="In the 'Other Sessions' menu on the history page, the label for the command to open all tabs and windows from a session."> + Open all + </message> + <message name="IDS_HISTORY_RANGE_ALL_TIME" desc="Option in the history range button group. Shows results a page at a time, without grouping them by domain."> + All + </message> + <message name="IDS_HISTORY_RANGE_LABEL" desc="Label for the combo box that selects the time range."> + Show + </message> + <message name="IDS_HISTORY_RANGE_MONTH" desc="Option in the history range button group. Shows results grouped by month."> + Month + </message> + <message name="IDS_HISTORY_RANGE_NEXT" desc="The alt text on the button that moves the current time range forward."> + Next + </message> + <message name="IDS_HISTORY_RANGE_PREVIOUS" desc="The alt text on the button that moves the current time range backwards."> + Previous + </message> + <message name="IDS_HISTORY_RANGE_TODAY" desc="The text on the button that sets the current time range back to today."> + Today + </message> + <message name="IDS_HISTORY_RANGE_WEEK" desc="Option in the history range button group. Shows results grouped by week."> + Week + </message> + <message name="IDS_HISTORY_REMOVE_BOOKMARK" desc="Tooltip shown when hovered over a history entry's bookmark star. When clicked, removes the bookmark."> + Remove bookmark + </message> + <message name="IDS_HISTORY_REMOVE_PAGE" desc="Command in the history entry drop-down menu. Removes a page from the history."> + Remove from history + </message> + <message name="IDS_HISTORY_REMOVE_SELECTED_ITEMS" desc="Title of the button that allows the user to remove the selected history items"> + Remove selected items + </message> + <message name="IDS_HISTORY_SEARCH_BUTTON" desc="Title of the button in the history page that triggers a search"> + Search history + </message> + <message name="IDS_HISTORY_SEARCH_RESULT" desc="Used when a single result is found."> + search result + </message> + <message name="IDS_HISTORY_SEARCH_RESULTS" desc="Used when plural/multiple results are found."> + search results + </message> + <message name="IDS_HISTORY_SEARCHRESULTSFOR" desc="Format string for search results"> + Search results for '<ph name="SEARCH_STRING">$1</ph>' + </message> + <message name="IDS_HISTORY_TITLE" desc="Title for the history tab."> + History + </message> + <message name="IDS_HISTORY_UNKNOWN_DEVICE" desc="On the dropdown menu for a history entry, the text that is shown instead of a device name, when the device name is not known."> + Unknown device + </message> + +</grit-part>
diff --git a/components/mus/common/BUILD.gn b/components/mus/common/BUILD.gn index 45e56ed..d0cc5d71 100644 --- a/components/mus/common/BUILD.gn +++ b/components/mus/common/BUILD.gn
@@ -9,6 +9,7 @@ "transient_window_utils.h", "types.h", "util.h", + "window_tracker.h", ] deps = [ "//components/mus/public/interfaces",
diff --git a/components/mus/common/window_tracker.h b/components/mus/common/window_tracker.h new file mode 100644 index 0000000..bc94b8e --- /dev/null +++ b/components/mus/common/window_tracker.h
@@ -0,0 +1,68 @@ +// Copyright 2016 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_MUS_COMMON_WINDOW_TRACKER_H_ +#define COMPONENTS_MUS_COMMON_WINDOW_TRACKER_H_ + +#include <vector> + +#include "base/stl_util.h" +#include "mojo/public/cpp/system/macros.h" + +namespace mus { + +template <class T, class TObserver> +class WindowTrackerTemplate : public TObserver { + public: + // A vector<> is used for tracking the windows (instead of a set<>) because + // the user may want to know about the order of the windows that have been + // added. + using WindowList = std::vector<T*>; + + WindowTrackerTemplate() {} + ~WindowTrackerTemplate() override { + for (T* window : windows_) + window->RemoveObserver(this); + } + + // Returns the set of windows being observed. + const WindowList& windows() const { return windows_; } + + // Adds |window| to the set of Windows being tracked. + void Add(T* window) { + if (ContainsValue(windows_, window)) + return; + + window->AddObserver(this); + windows_.push_back(window); + } + + // Removes |window| from the set of windows being tracked. + void Remove(T* window) { + auto iter = std::find(windows_.begin(), windows_.end(), window); + if (iter != windows_.end()) { + window->RemoveObserver(this); + windows_.erase(iter); + } + } + + // Returns true if |window| was previously added and has not been removed or + // deleted. + bool Contains(T* window) const { return ContainsValue(windows_, window); } + + // Observer overrides: + void OnWindowDestroying(T* window) override { + DCHECK(Contains(window)); + Remove(window); + } + + private: + WindowList windows_; + + MOJO_DISALLOW_COPY_AND_ASSIGN(WindowTrackerTemplate); +}; + +} // namespace mus + +#endif // COMPONENTS_MUS_COMMON_WINDOW_TRACKER_H_
diff --git a/components/mus/public/cpp/BUILD.gn b/components/mus/public/cpp/BUILD.gn index c172d32..59ca9bee 100644 --- a/components/mus/public/cpp/BUILD.gn +++ b/components/mus/public/cpp/BUILD.gn
@@ -32,7 +32,6 @@ "window_property.h", "window_surface.h", "window_surface_client.h", - "window_tracker.cc", "window_tracker.h", "window_tree_connection.h", "window_tree_connection_observer.h",
diff --git a/components/mus/public/cpp/lib/window.cc b/components/mus/public/cpp/lib/window.cc index 9d6157f..46291b0 100644 --- a/components/mus/public/cpp/lib/window.cc +++ b/components/mus/public/cpp/lib/window.cc
@@ -196,6 +196,13 @@ LocalSetBounds(bounds_, bounds); } +gfx::Rect Window::GetBoundsInRoot() const { + gfx::Vector2d offset; + for (const Window* w = parent(); w != nullptr; w = w->parent()) + offset += w->bounds().OffsetFromOrigin(); + return bounds() + offset; +} + void Window::SetClientArea( const gfx::Insets& client_area, const std::vector<gfx::Rect>& additional_client_areas) {
diff --git a/components/mus/public/cpp/window.h b/components/mus/public/cpp/window.h index 53df7dba..ef042d2 100644 --- a/components/mus/public/cpp/window.h +++ b/components/mus/public/cpp/window.h
@@ -68,10 +68,13 @@ // Configuration. Id id() const { return id_; } - // Geometric disposition. + // Geometric disposition relative to parent window. const gfx::Rect& bounds() const { return bounds_; } void SetBounds(const gfx::Rect& bounds); + // Geometric disposition relative to root window. + gfx::Rect GetBoundsInRoot() const; + const gfx::Insets& client_area() const { return client_area_; } const std::vector<gfx::Rect>& additional_client_areas() { return additional_client_areas_;
diff --git a/components/mus/public/cpp/window_tracker.cc b/components/mus/public/cpp/window_tracker.cc deleted file mode 100644 index 1fa1a4c..0000000 --- a/components/mus/public/cpp/window_tracker.cc +++ /dev/null
@@ -1,40 +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 "components/mus/public/cpp/window_tracker.h" - -namespace mus { - -WindowTracker::WindowTracker() {} - -WindowTracker::~WindowTracker() { - for (Windows::iterator i = windows_.begin(); i != windows_.end(); ++i) - (*i)->RemoveObserver(this); -} - -void WindowTracker::Add(Window* window) { - if (windows_.count(window)) - return; - - window->AddObserver(this); - windows_.insert(window); -} - -void WindowTracker::Remove(Window* window) { - if (windows_.count(window)) { - windows_.erase(window); - window->RemoveObserver(this); - } -} - -bool WindowTracker::Contains(Window* window) { - return windows_.count(window) > 0; -} - -void WindowTracker::OnWindowDestroying(Window* window) { - DCHECK_GT(windows_.count(window), 0u); - Remove(window); -} - -} // namespace mus
diff --git a/components/mus/public/cpp/window_tracker.h b/components/mus/public/cpp/window_tracker.h index b203c8a..38ea000 100644 --- a/components/mus/public/cpp/window_tracker.h +++ b/components/mus/public/cpp/window_tracker.h
@@ -9,39 +9,13 @@ #include <set> #include "base/macros.h" +#include "components/mus/common/window_tracker.h" #include "components/mus/public/cpp/window_observer.h" #include "mojo/public/cpp/system/macros.h" namespace mus { -class WindowTracker : public WindowObserver { - public: - using Windows = std::set<Window*>; - - WindowTracker(); - ~WindowTracker() override; - - // Returns the set of windows being observed. - const std::set<Window*>& windows() const { return windows_; } - - // Adds |window| to the set of Windows being tracked. - void Add(Window* window); - - // Removes |window| from the set of windows being tracked. - void Remove(Window* window); - - // Returns true if |window| was previously added and has not been removed or - // deleted. - bool Contains(Window* window); - - // WindowObserver overrides: - void OnWindowDestroying(Window* window) override; - - private: - Windows windows_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(WindowTracker); -}; +using WindowTracker = WindowTrackerTemplate<Window, WindowObserver>; } // namespace mus
diff --git a/components/mus/ws/BUILD.gn b/components/mus/ws/BUILD.gn index f49255c..9312a0c 100644 --- a/components/mus/ws/BUILD.gn +++ b/components/mus/ws/BUILD.gn
@@ -44,6 +44,7 @@ "server_window_surface.h", "server_window_surface_manager.cc", "server_window_surface_manager.h", + "server_window_tracker.h", "window_coordinate_conversions.cc", "window_coordinate_conversions.h", "window_finder.cc",
diff --git a/components/mus/ws/connection_manager.cc b/components/mus/ws/connection_manager.cc index c5cc71c..b520f04 100644 --- a/components/mus/ws/connection_manager.cc +++ b/components/mus/ws/connection_manager.cc
@@ -92,7 +92,7 @@ // Notify remaining connections so that they can cleanup. for (auto& pair : connection_map_) - pair.second->service()->OnWillDestroyWindowTreeImpl(connection->service()); + pair.second->service()->OnWindowDestroyingTreeImpl(connection->service()); // Notify the hosts, taking care to only notify each host once. std::set<WindowTreeHostImpl*> hosts_notified;
diff --git a/components/mus/ws/server_window.cc b/components/mus/ws/server_window.cc index 8a2c086..41e0126 100644 --- a/components/mus/ws/server_window.cc +++ b/components/mus/ws/server_window.cc
@@ -43,8 +43,7 @@ } ServerWindow::~ServerWindow() { - FOR_EACH_OBSERVER(ServerWindowObserver, observers_, - OnWillDestroyWindow(this)); + FOR_EACH_OBSERVER(ServerWindowObserver, observers_, OnWindowDestroying(this)); if (transient_parent_) transient_parent_->RemoveTransientWindow(this);
diff --git a/components/mus/ws/server_window_drawn_tracker.cc b/components/mus/ws/server_window_drawn_tracker.cc index 798a9de..cdbca8c 100644 --- a/components/mus/ws/server_window_drawn_tracker.cc +++ b/components/mus/ws/server_window_drawn_tracker.cc
@@ -54,7 +54,7 @@ windows_.clear(); } -void ServerWindowDrawnTracker::OnWillDestroyWindow(ServerWindow* window) { +void ServerWindowDrawnTracker::OnWindowDestroying(ServerWindow* window) { if (!drawn_) return; observer_->OnDrawnStateWillChange(window->parent(), window_, false);
diff --git a/components/mus/ws/server_window_drawn_tracker.h b/components/mus/ws/server_window_drawn_tracker.h index 6c0d337..36f2de2 100644 --- a/components/mus/ws/server_window_drawn_tracker.h +++ b/components/mus/ws/server_window_drawn_tracker.h
@@ -38,7 +38,7 @@ void RemoveObservers(); // ServerWindowObserver: - void OnWillDestroyWindow(ServerWindow* window) override; + void OnWindowDestroying(ServerWindow* window) override; void OnWindowDestroyed(ServerWindow* window) override; void OnWillChangeWindowHierarchy(ServerWindow* window, ServerWindow* new_parent,
diff --git a/components/mus/ws/server_window_observer.h b/components/mus/ws/server_window_observer.h index 6282b55..8c2e628 100644 --- a/components/mus/ws/server_window_observer.h +++ b/components/mus/ws/server_window_observer.h
@@ -31,7 +31,7 @@ public: // Invoked when a window is about to be destroyed; before any of the children // have been removed and before the window has been removed from its parent. - virtual void OnWillDestroyWindow(ServerWindow* window) {} + virtual void OnWindowDestroying(ServerWindow* window) {} // Invoked at the end of the window's destructor (after it has been removed // from the hierarchy.
diff --git a/components/mus/ws/server_window_tracker.h b/components/mus/ws/server_window_tracker.h new file mode 100644 index 0000000..f86831f --- /dev/null +++ b/components/mus/ws/server_window_tracker.h
@@ -0,0 +1,25 @@ +// Copyright 2016 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_MUS_WS_SERVER_WINDOW_TRACKER_H_ +#define COMPONENTS_MUS_WS_SERVER_WINDOW_TRACKER_H_ + +#include <stdint.h> +#include <set> + +#include "base/macros.h" +#include "components/mus/common/window_tracker.h" +#include "components/mus/ws/server_window.h" +#include "components/mus/ws/server_window_observer.h" + +namespace mus { +namespace ws { + +using ServerWindowTracker = + WindowTrackerTemplate<ServerWindow, ServerWindowObserver>; + +} // namespace ws +} // namespace mus + +#endif // COMPONENTS_MUS_WS_SERVER_WINDOW_TRACKER_H_
diff --git a/components/mus/ws/window_tree_impl.cc b/components/mus/ws/window_tree_impl.cc index 9bf699d..fe12b26 100644 --- a/components/mus/ws/window_tree_impl.cc +++ b/components/mus/ws/window_tree_impl.cc
@@ -127,7 +127,7 @@ : nullptr; } -void WindowTreeImpl::OnWillDestroyWindowTreeImpl(WindowTreeImpl* connection) { +void WindowTreeImpl::OnWindowDestroyingTreeImpl(WindowTreeImpl* connection) { // Notify our client if |connection| was embedded in any of our views. for (const auto* connection_root : connection->roots_) { const bool owns_connection_root =
diff --git a/components/mus/ws/window_tree_impl.h b/components/mus/ws/window_tree_impl.h index 4b70dde..967b9e4 100644 --- a/components/mus/ws/window_tree_impl.h +++ b/components/mus/ws/window_tree_impl.h
@@ -78,7 +78,7 @@ } // Invoked when a connection is about to be destroyed. - void OnWillDestroyWindowTreeImpl(WindowTreeImpl* connection); + void OnWindowDestroyingTreeImpl(WindowTreeImpl* connection); void OnWillDestroyWindowTreeHost(WindowTreeHostImpl* tree_host);
diff --git a/components/nacl/renderer/plugin/pnacl_translate_thread.cc b/components/nacl/renderer/plugin/pnacl_translate_thread.cc index e671916c2..2c052459 100644 --- a/components/nacl/renderer/plugin/pnacl_translate_thread.cc +++ b/components/nacl/renderer/plugin/pnacl_translate_thread.cc
@@ -12,7 +12,6 @@ #include "base/logging.h" #include "components/nacl/renderer/plugin/plugin.h" #include "components/nacl/renderer/plugin/plugin_error.h" -#include "components/nacl/renderer/plugin/srpc_params.h" #include "components/nacl/renderer/plugin/temporary_file.h" #include "components/nacl/renderer/plugin/utility.h" #include "content/public/common/sandbox_init.h" @@ -74,6 +73,7 @@ nexe_file_(NULL), coordinator_error_info_(NULL), coordinator_(NULL), + compiler_channel_peer_pid_(base::kNullProcessId), ld_channel_peer_pid_(base::kNullProcessId) { NaClXMutexCtor(&subprocess_mu_); NaClXMutexCtor(&cond_mu_); @@ -114,12 +114,18 @@ DCHECK(compiler_subprocess_->service_runtime()); compiler_subprocess_active_ = true; - // Free this IPC channel now to make sure that it does not get freed on - // the child thread when the child thread calls Shutdown(). - // TODO(mseaborn): Convert DoCompile() to using Chrome IPC instead of SRPC, - // the same way DoLink() has been converted. Then we will use this IPC - // channel instead of just freeing it here. - compiler_subprocess_->service_runtime()->TakeTranslatorChannel(); + // Take ownership of this IPC channel to make sure that it does not get + // freed on the child thread when the child thread calls Shutdown(). + compiler_channel_ = + compiler_subprocess_->service_runtime()->TakeTranslatorChannel(); + // compiler_channel_ is a IPC::SyncChannel, which is not thread-safe and + // cannot be used directly by the child thread, so create a + // SyncMessageFilter which can be used by the child thread. + compiler_channel_filter_ = compiler_channel_->CreateSyncMessageFilter(); + // Make a copy of the process ID, again to avoid any thread-safety issues + // involved in accessing compiler_subprocess_ on the child thread. + compiler_channel_peer_pid_ = + compiler_subprocess_->service_runtime()->get_process_id(); compile_finished_callback_ = compile_finished_callback; translate_thread_.reset(new NaClThread); @@ -177,7 +183,7 @@ void PnaclTranslateThread::PutBytes(const void* bytes, int32_t count) { CHECK(bytes != NULL); NaClXMutexLock(&cond_mu_); - data_buffers_.push_back(std::vector<char>()); + data_buffers_.push_back(std::string()); data_buffers_.back().insert(data_buffers_.back().end(), static_cast<const char*>(bytes), static_cast<const char*>(bytes) + count); @@ -193,13 +199,13 @@ } ppapi::proxy::SerializedHandle PnaclTranslateThread::GetHandleForSubprocess( - TempFile* file, int32_t open_flags) { + TempFile* file, int32_t open_flags, base::ProcessId peer_pid) { IPC::PlatformFileForTransit file_for_transit; #if defined(OS_WIN) if (!content::BrokerDuplicateHandle( file->GetFileHandle(), - ld_channel_peer_pid_, + peer_pid, &file_for_transit, 0, // desired_access is 0 since we're using DUPLICATE_SAME_ACCESS. DUPLICATE_SAME_ACCESS)) { @@ -230,29 +236,19 @@ // and now, just leave now. if (!compiler_subprocess_active_) return; - // Now that we are in helper thread, we can do the the blocking - // StartSrpcServices operation. - if (!compiler_subprocess_->StartSrpcServices()) { - TranslateFailed( - PP_NACL_ERROR_SRPC_CONNECTION_FAIL, - "SRPC connection failure for " + compiler_subprocess_->description()); - return; - } } - SrpcParams params; - std::vector<nacl::DescWrapper*> compile_out_files; - size_t i; - for (i = 0; i < obj_files_->size(); i++) - compile_out_files.push_back((*obj_files_)[i]->write_wrapper()); - for (; i < PnaclCoordinator::kMaxTranslatorObjectFiles; i++) - compile_out_files.push_back(invalid_desc_wrapper_); + std::vector<ppapi::proxy::SerializedHandle> compiler_output_files; + for (TempFile* obj_file : *obj_files_) { + compiler_output_files.push_back( + GetHandleForSubprocess(obj_file, PP_FILEOPENFLAG_WRITE, + compiler_channel_peer_pid_)); + } PLUGIN_PRINTF(("DoCompile using subzero: %d\n", pnacl_options_->use_subzero)); pp::Core* core = pp::Module::Get()->core(); int64_t do_compile_start_time = NaClGetTimeOfDayMicroseconds(); - bool init_success; std::vector<std::string> args; if (pnacl_options_->use_subzero) { @@ -266,34 +262,20 @@ architecture_attributes_); } - std::vector<char> split_args; - for (const std::string& arg : args) { - std::copy(arg.begin(), arg.end(), std::back_inserter(split_args)); - split_args.push_back('\x00'); + bool success = false; + std::string error_str; + if (!compiler_channel_filter_->Send( + new PpapiMsg_PnaclTranslatorCompileInit( + num_threads_, compiler_output_files, args, &success, &error_str))) { + TranslateFailed(PP_NACL_ERROR_PNACL_LLC_INTERNAL, + "Compile stream init failed: " + "reply not received from PNaCl translator " + "(it probably crashed)"); + return; } - - init_success = compiler_subprocess_->InvokeSrpcMethod( - "StreamInitWithSplit", "ihhhhhhhhhhhhhhhhC", ¶ms, num_threads_, - compile_out_files[0]->desc(), compile_out_files[1]->desc(), - compile_out_files[2]->desc(), compile_out_files[3]->desc(), - compile_out_files[4]->desc(), compile_out_files[5]->desc(), - compile_out_files[6]->desc(), compile_out_files[7]->desc(), - compile_out_files[8]->desc(), compile_out_files[9]->desc(), - compile_out_files[10]->desc(), compile_out_files[11]->desc(), - compile_out_files[12]->desc(), compile_out_files[13]->desc(), - compile_out_files[14]->desc(), compile_out_files[15]->desc(), - &split_args[0], split_args.size()); - if (!init_success) { - if (compiler_subprocess_->srpc_client()->GetLastError() == - NACL_SRPC_RESULT_APP_ERROR) { - // The error message is only present if the error was returned from llc - TranslateFailed(PP_NACL_ERROR_PNACL_LLC_INTERNAL, - std::string("Stream init failed: ") + - std::string(params.outs()[0]->arrays.str)); - } else { - TranslateFailed(PP_NACL_ERROR_PNACL_LLC_INTERNAL, - "Stream init internal error"); - } + if (!success) { + TranslateFailed(PP_NACL_ERROR_PNACL_LLC_INTERNAL, + std::string("Stream init failed: ") + error_str); return; } PLUGIN_PRINTF(("PnaclCoordinator: StreamInit successful\n")); @@ -308,50 +290,48 @@ ")\n", done_, data_buffers_.size())); if (data_buffers_.size() > 0) { - std::vector<char> data; + std::string data; data.swap(data_buffers_.front()); data_buffers_.pop_front(); NaClXMutexUnlock(&cond_mu_); PLUGIN_PRINTF(("StreamChunk\n")); - if (!compiler_subprocess_->InvokeSrpcMethod("StreamChunk", "C", ¶ms, - &data[0], data.size())) { - if (compiler_subprocess_->srpc_client()->GetLastError() != - NACL_SRPC_RESULT_APP_ERROR) { - // If the error was reported by the translator, then we fall through - // and call StreamEnd, which returns a string describing the error, - // which we can then send to the Javascript console. Otherwise just - // fail here, since the translator has probably crashed or asserted. - TranslateFailed(PP_NACL_ERROR_PNACL_LLC_INTERNAL, - "Compile stream chunk failed. " - "The PNaCl translator has probably crashed."); - return; - } - break; - } else { - PLUGIN_PRINTF(("StreamChunk Successful\n")); - core->CallOnMainThread( - 0, - coordinator_->GetCompileProgressCallback(data.size()), - PP_OK); + + if (!compiler_channel_filter_->Send( + new PpapiMsg_PnaclTranslatorCompileChunk(data, &success))) { + TranslateFailed(PP_NACL_ERROR_PNACL_LLC_INTERNAL, + "Compile stream chunk failed: " + "reply not received from PNaCl translator " + "(it probably crashed)"); + return; } + if (!success) { + // If the error was reported by the translator, then we fall through + // and call PpapiMsg_PnaclTranslatorCompileEnd, which returns a string + // describing the error, which we can then send to the Javascript + // console. + break; + } + PLUGIN_PRINTF(("StreamChunk Successful\n")); + core->CallOnMainThread( + 0, + coordinator_->GetCompileProgressCallback(data.size()), + PP_OK); } else { NaClXMutexUnlock(&cond_mu_); } } PLUGIN_PRINTF(("PnaclTranslateThread done with chunks\n")); // Finish llc. - if (!compiler_subprocess_->InvokeSrpcMethod("StreamEnd", std::string(), - ¶ms)) { - PLUGIN_PRINTF(("PnaclTranslateThread StreamEnd failed\n")); - if (compiler_subprocess_->srpc_client()->GetLastError() == - NACL_SRPC_RESULT_APP_ERROR) { - // The error string is only present if the error was sent back from llc. - TranslateFailed(PP_NACL_ERROR_PNACL_LLC_INTERNAL, - params.outs()[3]->arrays.str); - } else { - TranslateFailed(PP_NACL_ERROR_PNACL_LLC_INTERNAL, - "Compile StreamEnd internal error"); - } + if (!compiler_channel_filter_->Send( + new PpapiMsg_PnaclTranslatorCompileEnd(&success, &error_str))) { + TranslateFailed(PP_NACL_ERROR_PNACL_LLC_INTERNAL, + "Compile stream end failed: " + "reply not received from PNaCl translator " + "(it probably crashed)"); + return; + } + if (!success) { + TranslateFailed(PP_NACL_ERROR_PNACL_LLC_INTERNAL, error_str); return; } compile_time_ = NaClGetTimeOfDayMicroseconds() - do_compile_start_time; @@ -399,11 +379,13 @@ } ppapi::proxy::SerializedHandle nexe_file = - GetHandleForSubprocess(nexe_file_, PP_FILEOPENFLAG_WRITE); + GetHandleForSubprocess(nexe_file_, PP_FILEOPENFLAG_WRITE, + ld_channel_peer_pid_); std::vector<ppapi::proxy::SerializedHandle> ld_input_files; for (TempFile* obj_file : *obj_files_) { ld_input_files.push_back( - GetHandleForSubprocess(obj_file, PP_FILEOPENFLAG_READ)); + GetHandleForSubprocess(obj_file, PP_FILEOPENFLAG_READ, + ld_channel_peer_pid_)); } int64_t link_start_time = NaClGetTimeOfDayMicroseconds();
diff --git a/components/nacl/renderer/plugin/pnacl_translate_thread.h b/components/nacl/renderer/plugin/pnacl_translate_thread.h index cbb0ed0..18f10a4 100644 --- a/components/nacl/renderer/plugin/pnacl_translate_thread.h +++ b/components/nacl/renderer/plugin/pnacl_translate_thread.h
@@ -85,8 +85,8 @@ bool started() const { return coordinator_ != NULL; } private: - ppapi::proxy::SerializedHandle GetHandleForSubprocess(TempFile* file, - int32_t open_flags); + ppapi::proxy::SerializedHandle GetHandleForSubprocess( + TempFile* file, int32_t open_flags, base::ProcessId peer_pid); // Helper thread entry point for compilation. Takes a pointer to // PnaclTranslateThread and calls DoCompile(). @@ -137,7 +137,7 @@ struct NaClMutex cond_mu_; // Data buffers from FileDownloader are enqueued here to pass from the // main thread to the SRPC thread. Protected by cond_mu_ - std::deque<std::vector<char> > data_buffers_; + std::deque<std::string> data_buffers_; // Whether all data has been downloaded and copied to translation thread. // Associated with buffer_cond_ bool done_; @@ -154,12 +154,15 @@ std::string architecture_attributes_; PnaclCoordinator* coordinator_; - // This IPC::SyncChannel can only be used and freed by the parent thread. + // These IPC::SyncChannels can only be used and freed by the parent thread. + scoped_ptr<IPC::SyncChannel> compiler_channel_; scoped_ptr<IPC::SyncChannel> ld_channel_; - // This IPC::SyncMessageFilter can be used by the child thread. + // These IPC::SyncMessageFilters can be used by the child thread. + scoped_refptr<IPC::SyncMessageFilter> compiler_channel_filter_; scoped_refptr<IPC::SyncMessageFilter> ld_channel_filter_; - // PID of the subprocess, needed for copying handles to the subprocess on - // Windows. This is used by the child thread. + // PIDs of the subprocesses, needed for copying handles to the subprocess + // on Windows. These are used by the child thread. + base::ProcessId compiler_channel_peer_pid_; base::ProcessId ld_channel_peer_pid_; private:
diff --git a/components/password_manager/sync/browser/password_manager_setting_migrator_service.cc b/components/password_manager/sync/browser/password_manager_setting_migrator_service.cc index 1af5ba3..e543146 100644 --- a/components/password_manager/sync/browser/password_manager_setting_migrator_service.cc +++ b/components/password_manager/sync/browser/password_manager_setting_migrator_service.cc
@@ -57,10 +57,10 @@ void TrackInitialAndFinalValues(PrefService* prefs, bool initial_new_pref_value, bool initial_legacy_pref_value) { - bool final_new_pref_value = - prefs->GetBoolean(password_manager::prefs::kCredentialsEnableService); - bool final_legacy_pref_value = - prefs->GetBoolean(password_manager::prefs::kPasswordManagerSavingEnabled); + bool final_new_pref_value = GetBooleanUserOrDefaultPrefValue( + prefs, password_manager::prefs::kCredentialsEnableService); + bool final_legacy_pref_value = GetBooleanUserOrDefaultPrefValue( + prefs, password_manager::prefs::kPasswordManagerSavingEnabled); const int kMaxInitValue = 0x10; int value_to_log = 0; const int kInitialNewValueMask = 0x8;
diff --git a/components/startup_metric_utils.gypi b/components/startup_metric_utils.gypi index 452de896..3fcd4a8 100644 --- a/components/startup_metric_utils.gypi +++ b/components/startup_metric_utils.gypi
@@ -14,6 +14,7 @@ 'type': 'static_library', 'dependencies': [ '../base/base.gyp:base', + '../base/base.gyp:base_prefs', 'components.gyp:variations', ], 'include_dirs': [
diff --git a/components/startup_metric_utils/browser/BUILD.gn b/components/startup_metric_utils/browser/BUILD.gn index 1bd6c3b..64f0dd28 100644 --- a/components/startup_metric_utils/browser/BUILD.gn +++ b/components/startup_metric_utils/browser/BUILD.gn
@@ -25,6 +25,7 @@ deps = [ "//base", + "//base:prefs", "//components/variations", ] }
diff --git a/components/startup_metric_utils/browser/startup_metric_utils.cc b/components/startup_metric_utils/browser/startup_metric_utils.cc index 6594376..b2ee445 100644 --- a/components/startup_metric_utils/browser/startup_metric_utils.cc +++ b/components/startup_metric_utils/browser/startup_metric_utils.cc
@@ -11,6 +11,9 @@ #include "base/lazy_instance.h" #include "base/logging.h" #include "base/metrics/histogram_macros.h" +#include "base/prefs/pref_registry_simple.h" +#include "base/prefs/pref_service.h" +#include "base/process/process_info.h" #include "base/strings/string_number_conversions.h" #include "base/sys_info.h" #include "base/threading/platform_thread.h" @@ -27,6 +30,9 @@ namespace { +const char kLastStartupTimestampPref[] = + "startup_metric.last_startup_timestamp"; + // Mark as volatile to defensively make sure usage is thread-safe. // Note that at the time of this writing, access is only on the UI thread. volatile bool g_non_browser_ui_displayed = false; @@ -96,6 +102,9 @@ SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG); #endif // defined(OS_WIN) +#define UMA_HISTOGRAM_TIME_IN_MINUTES_MONTH_RANGE(name, sample) \ + UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, \ + base::TimeDelta::FromDays(30).InMinutes(), 50) // Helper macro for splitting out an UMA histogram based on cold or warm start. // |type| is the histogram type, and corresponds to an UMA macro like @@ -382,6 +391,11 @@ } #endif // defined(OS_WIN) +void RegisterPrefs(PrefRegistrySimple* registry) { + DCHECK(registry); + registry->RegisterInt64Pref(kLastStartupTimestampPref, 0); +} + bool WasNonBrowserUIDisplayed() { return g_non_browser_ui_displayed; } @@ -477,6 +491,39 @@ } } +void RecordTimeSinceLastStartup(PrefService* pref_service) { +#if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_LINUX) + DCHECK(pref_service); + + // Get the timestamp of the current startup. + const base::Time process_start_time = + base::CurrentProcessInfo::CreationTime(); + + // Get the timestamp of the last startup from |pref_service|. + const int64_t last_startup_timestamp_internal = + pref_service->GetInt64(kLastStartupTimestampPref); + if (last_startup_timestamp_internal != 0) { + // Log the Startup.TimeSinceLastStartup histogram. + const base::Time last_startup_timestamp = + base::Time::FromInternalValue(last_startup_timestamp_internal); + const base::TimeDelta time_since_last_startup = + process_start_time - last_startup_timestamp; + const int minutes_since_last_startup = time_since_last_startup.InMinutes(); + + // Ignore negative values, which can be caused by system clock changes. + if (minutes_since_last_startup >= 0) { + UMA_HISTOGRAM_WITH_STARTUP_TEMPERATURE( + UMA_HISTOGRAM_TIME_IN_MINUTES_MONTH_RANGE, + "Startup.TimeSinceLastStartup", minutes_since_last_startup); + } + } + + // Write the timestamp of the current startup in |pref_service|. + pref_service->SetInt64(kLastStartupTimestampPref, + process_start_time.ToInternalValue()); +#endif // defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_LINUX) +} + void RecordBrowserWindowDisplay(const base::TimeTicks& ticks) { static bool is_first_call = true; if (!is_first_call || ticks.is_null())
diff --git a/components/startup_metric_utils/browser/startup_metric_utils.h b/components/startup_metric_utils/browser/startup_metric_utils.h index 51bae62..1027792c 100644 --- a/components/startup_metric_utils/browser/startup_metric_utils.h +++ b/components/startup_metric_utils/browser/startup_metric_utils.h
@@ -11,6 +11,9 @@ #include "base/time/time.h" #include "build/build_config.h" +class PrefRegistrySimple; +class PrefService; + // Utility functions to support metric collection for browser startup. Timings // should use TimeTicks whenever possible. OS-provided timings are still // received as Time out of cross-platform support necessity but are converted to @@ -42,6 +45,9 @@ bool GetHardFaultCountForCurrentProcess(uint32_t* hard_fault_count); #endif // defined(OS_WIN) +// Registers startup related prefs in |registry|. +void RegisterPrefs(PrefRegistrySimple* registry); + // Returns true if any UI other than the browser window has been displayed // so far. Useful to test if UI has been displayed before the first browser // window was shown, which would invalidate any surrounding timing metrics. @@ -74,6 +80,13 @@ void RecordBrowserMainMessageLoopStart(const base::TimeTicks& ticks, bool is_first_run); +// Logs the Startup.TimeSinceLastStartup histogram. Obtains the timestamp of the +// last startup from |pref_service| and overwrites it with the timestamp of the +// current startup. If the startup temperature has been set by +// RecordBrowserMainMessageLoopStart, the time since last startup is also logged +// to an histogram suffixed with the startup temperature. +void RecordTimeSinceLastStartup(PrefService* pref_service); + // Call this with the time when the first browser window became visible. void RecordBrowserWindowDisplay(const base::TimeTicks& ticks);
diff --git a/content/browser/background_sync/background_sync_manager.cc b/content/browser/background_sync/background_sync_manager.cc index 589a908..929d9f36b 100644 --- a/content/browser/background_sync/background_sync_manager.cc +++ b/content/browser/background_sync/background_sync_manager.cc
@@ -111,7 +111,9 @@ GetBackgroundSyncControllerOnUIThread(sw_context_wrapper); if (!background_sync_controller) { - // Return default ParameterOverrides which don't disable and don't override. + // If there is no controller then BackgroundSync can't run in the + // background, disable it. + parameters->disable = true; return parameters; }
diff --git a/content/browser/background_sync/background_sync_service_impl_unittest.cc b/content/browser/background_sync/background_sync_service_impl_unittest.cc index 7d7b3ed..a9f8307 100644 --- a/content/browser/background_sync/background_sync_service_impl_unittest.cc +++ b/content/browser/background_sync/background_sync_service_impl_unittest.cc
@@ -17,8 +17,10 @@ #include "content/browser/background_sync/background_sync_network_observer.h" #include "content/browser/service_worker/embedded_worker_test_helper.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" +#include "content/browser/storage_partition_impl.h" #include "content/public/browser/browser_thread.h" #include "content/public/test/background_sync_test_util.h" +#include "content/public/test/test_browser_context.h" #include "content/public/test/test_browser_thread_bundle.h" #include "mojo/public/cpp/bindings/interface_ptr.h" #include "net/base/network_change_notifier.h" @@ -113,6 +115,7 @@ background_sync_test_util::SetIgnoreNetworkChangeNotifier(true); CreateTestHelper(); + CreateStoragePartition(); CreateBackgroundSyncContext(); CreateServiceWorkerRegistration(); CreateBackgroundSyncServiceImpl(); @@ -136,6 +139,17 @@ new EmbeddedWorkerTestHelper(base::FilePath())); } + void CreateStoragePartition() { + // Creates a StoragePartition so that the BackgroundSyncManager can + // use it to access the BrowserContext. + storage_partition_impl_.reset(new StoragePartitionImpl( + embedded_worker_helper_->browser_context(), base::FilePath(), nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); + embedded_worker_helper_->context_wrapper()->set_storage_partition( + storage_partition_impl_.get()); + } + void CreateBackgroundSyncContext() { power_monitor_.reset( new base::PowerMonitor(make_scoped_ptr(new MockPowerMonitorSource()))); @@ -232,6 +246,7 @@ scoped_ptr<TestBrowserThreadBundle> thread_bundle_; scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_; scoped_ptr<EmbeddedWorkerTestHelper> embedded_worker_helper_; + scoped_ptr<StoragePartitionImpl> storage_partition_impl_; scoped_ptr<base::PowerMonitor> power_monitor_; scoped_refptr<BackgroundSyncContextImpl> background_sync_context_; int64_t sw_registration_id_;
diff --git a/content/browser/cache_storage/cache_storage_context_impl.cc b/content/browser/cache_storage/cache_storage_context_impl.cc index 29bb50ccb..83aa12d6 100644 --- a/content/browser/cache_storage/cache_storage_context_impl.cc +++ b/content/browser/cache_storage/cache_storage_context_impl.cc
@@ -36,7 +36,7 @@ base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool(); scoped_refptr<base::SequencedTaskRunner> cache_task_runner = pool->GetSequencedTaskRunnerWithShutdownBehavior( - BrowserThread::GetBlockingPool()->GetSequenceToken(), + base::SequencedWorkerPool::GetSequenceToken(), base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); // This thread-hopping antipattern is needed here for some unit tests, where
diff --git a/content/browser/loader/async_resource_handler.cc b/content/browser/loader/async_resource_handler.cc index df08aa7..512ad72 100644 --- a/content/browser/loader/async_resource_handler.cc +++ b/content/browser/loader/async_resource_handler.cc
@@ -16,6 +16,7 @@ #include "base/metrics/histogram_macros.h" #include "base/strings/string_number_conversions.h" #include "base/time/time.h" +#include "build/build_config.h" #include "content/browser/devtools/devtools_netlog_observer.h" #include "content/browser/host_zoom_map_impl.h" #include "content/browser/loader/resource_buffer.h" @@ -33,6 +34,10 @@ #include "net/log/net_log.h" #include "net/url_request/redirect_info.h" +#if defined(OS_WIN) +#include <windows.h> +#endif + using base::TimeDelta; using base::TimeTicks; @@ -322,6 +327,13 @@ // TODO(erikchen): Temporary debugging. http://crbug.com/527588. CHECK_LE(size, kBufferSize); +#if defined(OS_WIN) + int handle_int = static_cast<int>(HandleToLong(handle.GetHandle())); + filter->Send( + new ResourceMsg_SetDataBufferDebug1(GetRequestID(), handle_int)); + filter->Send( + new ResourceMsg_SetDataBufferDebug2(GetRequestID(), handle_int + 3)); +#endif filter->Send(new ResourceMsg_SetDataBuffer( GetRequestID(), handle, size, filter->peer_pid())); sent_first_data_msg_ = true;
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc index 92f06c3..86b1a2d 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.cc +++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -454,6 +454,17 @@ return lofi_state == LOFI_ON; } +// Record RAPPOR for aborted main frame loads. Separate into a fast and +// slow bucket because a shocking number of aborts happen under 100ms. +void RecordAbortRapporOnUI(const GURL& url, + base::TimeDelta request_loading_time) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (request_loading_time.InMilliseconds() < 100) + GetContentClient()->browser()->RecordURLMetric("Net.ErrAborted.Fast", url); + else + GetContentClient()->browser()->RecordURLMetric("Net.ErrAborted.Slow", url); +} + } // namespace // static @@ -845,8 +856,8 @@ return false; return delegate_->HandleExternalProtocol( - url, info->GetChildID(), info->GetRouteID(), info->IsMainFrame(), - info->GetPageTransition(), info->HasUserGesture()); + url, info->GetChildID(), info->GetWebContentsGetterForRequest(), + info->IsMainFrame(), info->GetPageTransition(), info->HasUserGesture()); } void ResourceDispatcherHostImpl::DidStartRequest(ResourceLoader* loader) { @@ -972,6 +983,11 @@ 1, 50000000, 50); UMA_HISTOGRAM_LONG_TIMES( "Net.RequestTime2.ErrAborted", request_loading_time); + + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&RecordAbortRapporOnUI, loader->request()->url(), + request_loading_time)); break; case net::ERR_CONNECTION_RESET: UMA_HISTOGRAM_LONG_TIMES( @@ -1181,8 +1197,9 @@ // ResourceHandlers should always get state related to the request from the // ResourceRequestInfo rather than caching it locally. This lets us update // the info object when a transfer occurs. - info->UpdateForTransfer(child_id, route_id, request_data.origin_pid, - request_id, filter_->GetWeakPtr()); + info->UpdateForTransfer(child_id, route_id, request_data.render_frame_id, + request_data.origin_pid, request_id, + filter_->GetWeakPtr()); // Update maps that used the old IDs, if necessary. Some transfers in tests // do not actually use a different ID, so not all maps need to be updated.
diff --git a/content/browser/loader/resource_request_info_impl.cc b/content/browser/loader/resource_request_info_impl.cc index 0f61829..8511653 100644 --- a/content/browser/loader/resource_request_info_impl.cc +++ b/content/browser/loader/resource_request_info_impl.cc
@@ -321,11 +321,13 @@ void ResourceRequestInfoImpl::UpdateForTransfer( int child_id, int route_id, + int render_frame_id, int origin_pid, int request_id, base::WeakPtr<ResourceMessageFilter> filter) { child_id_ = child_id; route_id_ = route_id; + render_frame_id_ = render_frame_id; origin_pid_ = origin_pid; request_id_ = request_id; filter_ = filter;
diff --git a/content/browser/loader/resource_request_info_impl.h b/content/browser/loader/resource_request_info_impl.h index 3fbce96b..625e58c 100644 --- a/content/browser/loader/resource_request_info_impl.h +++ b/content/browser/loader/resource_request_info_impl.h
@@ -114,6 +114,7 @@ // does not need to be updated. void UpdateForTransfer(int child_id, int route_id, + int render_frame_id, int origin_pid, int request_id, base::WeakPtr<ResourceMessageFilter> filter);
diff --git a/content/browser/navigator_connect/navigator_connect_context_impl.cc b/content/browser/navigator_connect/navigator_connect_context_impl.cc index c469605..c393c4b 100644 --- a/content/browser/navigator_connect/navigator_connect_context_impl.cc +++ b/content/browser/navigator_connect/navigator_connect_context_impl.cc
@@ -6,6 +6,7 @@ #include <stdint.h> +#include "base/stl_util.h" #include "content/browser/message_port_service.h" #include "content/browser/navigator_connect/service_port_service_impl.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" @@ -13,6 +14,7 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/navigator_connect_service_factory.h" #include "content/public/common/navigator_connect_client.h" +#include "mojo/common/url_type_converters.h" namespace content { @@ -139,8 +141,7 @@ if (status != SERVICE_WORKER_OK) { // No service worker found, reject connection attempt. - OnConnectResult(callback, client_port_id, service_port_id, registration, - status, false, base::string16(), base::string16()); + OnConnectError(callback, client_port_id, service_port_id, status); return; } @@ -152,10 +153,37 @@ service_port.service_worker_registration_origin = registration->pattern().GetOrigin(); - active_version->DispatchServicePortConnectEvent( + active_version->RunAfterStartWorker( + base::Bind(&NavigatorConnectContextImpl::OnConnectError, this, callback, + client_port_id, service_port_id), + base::Bind(&NavigatorConnectContextImpl::DispatchConnectEvent, this, + callback, client_port_id, service_port_id, registration, + make_scoped_refptr(active_version))); +} + +void NavigatorConnectContextImpl::DispatchConnectEvent( + const ConnectCallback& callback, + int client_port_id, + int service_port_id, + const scoped_refptr<ServiceWorkerRegistration>& service_worker_registration, + const scoped_refptr<ServiceWorkerVersion>& worker) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK(ContainsKey(ports_, client_port_id)); + DCHECK(ContainsKey(ports_, service_port_id)); + + const Port& service_port = ports_[service_port_id]; + int request_id = worker->StartRequest( + ServiceWorkerMetrics::EventType::SERVICE_PORT_CONNECT, + base::Bind(&NavigatorConnectContextImpl::OnConnectError, this, callback, + client_port_id, service_port_id)); + base::WeakPtr<ServicePortDispatcher> dispatcher = + worker->GetMojoServiceForRequest<ServicePortDispatcher>(request_id); + dispatcher->Connect( + mojo::String::From(service_port.target_url), + mojo::String::From(service_port.client_origin), service_port_id, base::Bind(&NavigatorConnectContextImpl::OnConnectResult, this, callback, - client_port_id, service_port_id, registration), - service_port.target_url, service_port.client_origin, service_port_id); + client_port_id, service_port_id, service_worker_registration, + worker, request_id)); } void NavigatorConnectContextImpl::ServicePortServiceDestroyed( @@ -171,26 +199,42 @@ } } +void NavigatorConnectContextImpl::OnConnectError( + const ConnectCallback& callback, + int client_port_id, + int service_port_id, + ServiceWorkerStatusCode status) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + // Destroy ports since connection failed. + ports_.erase(service_port_id); + ports_.erase(client_port_id); + callback.Run(MSG_ROUTING_NONE, false); +} + void NavigatorConnectContextImpl::OnConnectResult( const ConnectCallback& callback, int client_port_id, int service_port_id, const scoped_refptr<ServiceWorkerRegistration>& service_worker_registration, - ServiceWorkerStatusCode status, - bool accept_connection, - const base::string16& name, - const base::string16& data) { + const scoped_refptr<ServiceWorkerVersion>& worker, + int request_id, + ServicePortConnectResult result, + const mojo::String& name, + const mojo::String& data) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - if (accept_connection) { - // TODO(mek): Might have to do something else if the client connection got - // severed while the service side connection was being set up. - callback.Run(client_port_id, true); - } else { - // Destroy ports since connection failed. - ports_.erase(service_port_id); - ports_.erase(client_port_id); - callback.Run(MSG_ROUTING_NONE, false); + + if (!worker->FinishRequest(request_id)) + return; + + if (result != SERVICE_PORT_CONNECT_RESULT_ACCEPT) { + OnConnectError(callback, client_port_id, service_port_id, + SERVICE_WORKER_ERROR_FAILED); + return; } + + // TODO(mek): Might have to do something else if the client connection got + // severed while the service side connection was being set up. + callback.Run(client_port_id, true); } void NavigatorConnectContextImpl::DeliverMessage(
diff --git a/content/browser/navigator_connect/navigator_connect_context_impl.h b/content/browser/navigator_connect/navigator_connect_context_impl.h index e57c2e80..5337a33 100644 --- a/content/browser/navigator_connect/navigator_connect_context_impl.h +++ b/content/browser/navigator_connect/navigator_connect_context_impl.h
@@ -9,6 +9,7 @@ #include "base/callback_forward.h" #include "base/memory/scoped_vector.h" #include "base/strings/string16.h" +#include "content/common/service_port_service.mojom.h" #include "content/common/service_worker/service_worker_status_code.h" #include "content/public/browser/navigator_connect_context.h" @@ -23,6 +24,7 @@ class ServicePortServiceImpl; class ServiceWorkerContextWrapper; class ServiceWorkerRegistration; +class ServiceWorkerVersion; struct TransferredMessagePort; // Tracks all active navigator.services connections, as well as available @@ -81,16 +83,30 @@ ServiceWorkerStatusCode status, const scoped_refptr<ServiceWorkerRegistration>& registration); - // Callback called by service factories when a connection succeeded or failed. + void DispatchConnectEvent(const ConnectCallback& callback, + int client_port_id, + int service_port_id, + const scoped_refptr<ServiceWorkerRegistration>& + service_worker_registration, + const scoped_refptr<ServiceWorkerVersion>& worker); + + // Callback called when dispatching a connect event failed. + void OnConnectError(const ConnectCallback& calback, + int client_port_id, + int service_port_id, + ServiceWorkerStatusCode status); + + // Callback called with the response to a connect event. void OnConnectResult(const ConnectCallback& callback, int client_port_id, int service_port_id, const scoped_refptr<ServiceWorkerRegistration>& service_worker_registration, - ServiceWorkerStatusCode status, - bool accept_connection, - const base::string16& name, - const base::string16& data); + const scoped_refptr<ServiceWorkerVersion>& worker, + int request_id, + ServicePortConnectResult result, + const mojo::String& name, + const mojo::String& data); // Callback called when a ServiceWorkerRegistration has been located to // deliver a message to.
diff --git a/content/browser/net/quota_policy_cookie_store.cc b/content/browser/net/quota_policy_cookie_store.cc index 0a7191c..9404981f 100644 --- a/content/browser/net/quota_policy_cookie_store.cc +++ b/content/browser/net/quota_policy_cookie_store.cc
@@ -154,7 +154,7 @@ if (!background_task_runner.get()) { background_task_runner = BrowserThread::GetBlockingPool()->GetSequencedTaskRunner( - BrowserThread::GetBlockingPool()->GetSequenceToken()); + base::SequencedWorkerPool::GetSequenceToken()); } scoped_refptr<net::SQLitePersistentCookieStore> sqlite_store(
diff --git a/content/browser/plugin_service_impl.cc b/content/browser/plugin_service_impl.cc index 09ae4dc..700d3042 100644 --- a/content/browser/plugin_service_impl.cc +++ b/content/browser/plugin_service_impl.cc
@@ -177,7 +177,7 @@ } void PluginServiceImpl::Init() { - plugin_list_token_ = BrowserThread::GetBlockingPool()->GetSequenceToken(); + plugin_list_token_ = base::SequencedWorkerPool::GetSequenceToken(); PluginList::Singleton()->set_will_load_plugins_callback( base::Bind(&WillLoadPluginsCallback, plugin_list_token_));
diff --git a/content/browser/renderer_host/media/audio_renderer_host.cc b/content/browser/renderer_host/media/audio_renderer_host.cc index 279d6fcf..49e395bd 100644 --- a/content/browser/renderer_host/media/audio_renderer_host.cc +++ b/content/browser/renderer_host/media/audio_renderer_host.cc
@@ -73,9 +73,10 @@ } media::AudioParameters DummyParams() { - return media::AudioParameters(media::AudioParameters::AUDIO_PCM_LINEAR, - media::CHANNEL_LAYOUT_STEREO, - media::limits::kMinSampleRate, 1, 1); + return media::AudioParameters( + media::AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_STEREO, + media::AudioParameters::kAudioCDSampleRate, 16, + media::AudioParameters::kAudioCDSampleRate / 10); } std::pair<int, std::pair<bool, std::string>> MakeAuthorizationData( @@ -136,6 +137,19 @@ render_process_host->AudioStateChanged(); } +void MaybeFixAudioParameters(media::AudioParameters* params) { + // If the number of output channels is greater than the maximum, use the + // maximum allowed value. Hardware channels are ignored upstream, so it is + // better to report a valid value if this is the only problem. + if (params->channels() > media::limits::kMaxChannels) + params->set_channels_for_discrete(media::limits::kMaxChannels); + + // If hardware parameters are still invalid, use dummy parameters with + // fake audio path and let the client handle the error. + if (!params->IsValid()) + *params = DummyParams(); +} + } // namespace class AudioRendererHost::AudioEntry @@ -460,6 +474,7 @@ output_params.set_effects(info->device.matched_output.effects); authorizations_.insert(MakeAuthorizationData( stream_id, true, info->device.matched_output_device_id)); + MaybeFixAudioParameters(&output_params); Send(new AudioMsg_NotifyDeviceAuthorized( stream_id, media::OUTPUT_DEVICE_STATUS_OK, output_params)); return; @@ -535,8 +550,11 @@ auth_data->second.first = true; auth_data->second.second = device_info.unique_id; + + media::AudioParameters output_params = device_info.output_params; + MaybeFixAudioParameters(&output_params); Send(new AudioMsg_NotifyDeviceAuthorized( - stream_id, media::OUTPUT_DEVICE_STATUS_OK, device_info.output_params)); + stream_id, media::OUTPUT_DEVICE_STATUS_OK, output_params)); } void AudioRendererHost::OnCreateStream(int stream_id,
diff --git a/content/browser/service_worker/embedded_worker_test_helper.cc b/content/browser/service_worker/embedded_worker_test_helper.cc index e8cbe2d..3f57292 100644 --- a/content/browser/service_worker/embedded_worker_test_helper.cc +++ b/content/browser/service_worker/embedded_worker_test_helper.cc
@@ -18,9 +18,11 @@ #include "content/browser/service_worker/service_worker_context_core.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/common/service_worker/embedded_worker_messages.h" +#include "content/common/service_worker/embedded_worker_setup.mojom.h" #include "content/common/service_worker/service_worker_messages.h" #include "content/public/test/mock_render_process_host.h" #include "content/public/test/test_browser_context.h" +#include "mojo/public/cpp/bindings/strong_binding.h" #include "testing/gtest/include/gtest/gtest.h" namespace content { @@ -47,6 +49,33 @@ } // namespace +class EmbeddedWorkerTestHelper::MockEmbeddedWorkerSetup + : public EmbeddedWorkerSetup { + public: + static void Create(const base::WeakPtr<EmbeddedWorkerTestHelper>& helper, + mojo::InterfaceRequest<EmbeddedWorkerSetup> request) { + new MockEmbeddedWorkerSetup(helper, std::move(request)); + } + + void ExchangeServiceProviders( + int32_t thread_id, + mojo::InterfaceRequest<mojo::ServiceProvider> services, + mojo::ServiceProviderPtr exposed_services) override { + if (!helper_) + return; + helper_->OnSetupMojoStub(thread_id, std::move(services), + std::move(exposed_services)); + } + + private: + MockEmbeddedWorkerSetup(const base::WeakPtr<EmbeddedWorkerTestHelper>& helper, + mojo::InterfaceRequest<EmbeddedWorkerSetup> request) + : helper_(helper), binding_(this, std::move(request)) {} + + base::WeakPtr<EmbeddedWorkerTestHelper> helper_; + mojo::StrongBinding<EmbeddedWorkerSetup> binding_; +}; + EmbeddedWorkerTestHelper::EmbeddedWorkerTestHelper( const base::FilePath& user_data_directory) : browser_context_(new TestBrowserContext), @@ -63,6 +92,16 @@ wrapper_->process_manager()->SetProcessIdForTest(mock_render_process_id_); registry()->AddChildProcessSender(mock_render_process_id_, this, NewMessagePortMessageFilter()); + + // Setup process level mojo service registry pair. + scoped_ptr<ServiceRegistryImpl> host_service_registry( + new ServiceRegistryImpl); + render_process_service_registry_.ServiceRegistry::AddService( + base::Bind(&MockEmbeddedWorkerSetup::Create, weak_factory_.GetWeakPtr())); + mojo::ServiceProviderPtr services; + render_process_service_registry_.Bind(mojo::GetProxy(&services)); + host_service_registry->BindRemoteServiceProvider(std::move(services)); + render_process_host_->SetServiceRegistry(std::move(host_service_registry)); } EmbeddedWorkerTestHelper::~EmbeddedWorkerTestHelper() { @@ -148,6 +187,8 @@ return handled; } +void EmbeddedWorkerTestHelper::OnSetupMojo(ServiceRegistry* service_registry) {} + void EmbeddedWorkerTestHelper::OnActivateEvent(int embedded_worker_id, int request_id) { SimulateSend( @@ -337,6 +378,17 @@ current_embedded_worker_id_, request_id, data)); } +void EmbeddedWorkerTestHelper::OnSetupMojoStub( + int thread_id, + mojo::InterfaceRequest<mojo::ServiceProvider> services, + mojo::ServiceProviderPtr exposed_services) { + scoped_ptr<ServiceRegistryImpl> new_registry(new ServiceRegistryImpl); + new_registry->Bind(std::move(services)); + new_registry->BindRemoteServiceProvider(std::move(exposed_services)); + OnSetupMojo(new_registry.get()); + thread_id_service_registry_map_.add(thread_id, std::move(new_registry)); +} + EmbeddedWorkerRegistry* EmbeddedWorkerTestHelper::registry() { DCHECK(context()); return context()->embedded_worker_registry();
diff --git a/content/browser/service_worker/embedded_worker_test_helper.h b/content/browser/service_worker/embedded_worker_test_helper.h index 9a30831..a95454a 100644 --- a/content/browser/service_worker/embedded_worker_test_helper.h +++ b/content/browser/service_worker/embedded_worker_test_helper.h
@@ -12,8 +12,10 @@ #include <vector> #include "base/callback.h" +#include "base/containers/scoped_ptr_hash_map.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "content/common/mojo/service_registry_impl.h" #include "ipc/ipc_listener.h" #include "ipc/ipc_test_sink.h" #include "testing/gtest/include/gtest/gtest.h" @@ -99,6 +101,10 @@ int embedded_worker_id, const IPC::Message& message); + // Called to setup mojo for a new embedded worker. Override to register + // services the worker should expose to the browser. + virtual void OnSetupMojo(ServiceRegistry* service_registry); + // On*Event handlers. Called by the default implementation of // OnMessageToWorker when events are sent to the embedded // worker. By default they just return success via @@ -126,6 +132,8 @@ EmbeddedWorkerRegistry* registry(); private: + class MockEmbeddedWorkerSetup; + void OnStartWorkerStub(const EmbeddedWorkerMsg_StartWorker_Params& params); void OnStopWorkerStub(int embedded_worker_id); void OnMessageToWorkerStub(int thread_id, @@ -136,6 +144,9 @@ void OnFetchEventStub(int request_id, const ServiceWorkerFetchRequest& request); void OnPushEventStub(int request_id, const std::string& data); + void OnSetupMojoStub(int thread_id, + mojo::InterfaceRequest<mojo::ServiceProvider> services, + mojo::ServiceProviderPtr exposed_services); MessagePortMessageFilter* NewMessagePortMessageFilter(); @@ -150,8 +161,15 @@ int next_thread_id_; int mock_render_process_id_; + ServiceRegistryImpl render_process_service_registry_; + std::map<int, int64_t> embedded_worker_id_service_worker_version_id_map_; + // Stores the ServiceRegistries that are associated with each individual + // service worker. + base::ScopedPtrHashMap<int, scoped_ptr<ServiceRegistryImpl>> + thread_id_service_registry_map_; + // Updated each time MessageToWorker message is received. int current_embedded_worker_id_;
diff --git a/content/browser/service_worker/service_worker_metrics.cc b/content/browser/service_worker/service_worker_metrics.cc index a900d4d..95206ad8 100644 --- a/content/browser/service_worker/service_worker_metrics.cc +++ b/content/browser/service_worker/service_worker_metrics.cc
@@ -168,12 +168,20 @@ type = EVENT_HANDLED_ALL; else if (handled_events == 0) type = EVENT_HANDLED_NONE; + // For now Fetch is the only type that is recorded. - DCHECK_EQ(EVENT_TYPE_FETCH, event); + if (event != EventType::FETCH) + return; UMA_HISTOGRAM_ENUMERATION("ServiceWorker.EventHandledRatioType.Fetch", type, NUM_EVENT_HANDLED_RATIO_TYPE); } +void ServiceWorkerMetrics::RecordEventTimeout(EventType event) { + UMA_HISTOGRAM_ENUMERATION("ServiceWorker.RequestTimeouts.Count", + static_cast<int>(event), + static_cast<int>(EventType::NUM_TYPES)); +} + void ServiceWorkerMetrics::RecordFetchEventStatus( bool is_main_resource, ServiceWorkerStatusCode status) {
diff --git a/content/browser/service_worker/service_worker_metrics.h b/content/browser/service_worker/service_worker_metrics.h index ebf941d..a24dc25 100644 --- a/content/browser/service_worker/service_worker_metrics.h +++ b/content/browser/service_worker/service_worker_metrics.h
@@ -72,11 +72,19 @@ NUM_TYPES }; - enum EventType { - EVENT_TYPE_FETCH, + // Used for UMA. Append-only. + enum class EventType { + ACTIVATE, + INSTALL, + FETCH, + SYNC, + NOTIFICATION_CLICK, + PUSH, + GEOFENCING, + SERVICE_PORT_CONNECT, // Add new events to record here. - NUM_EVENT_TYPES + NUM_TYPES }; // Used for UMA. Append only. @@ -131,6 +139,9 @@ size_t handled_events, size_t fired_events); + // Records how often a dispatched event times out. + static void RecordEventTimeout(EventType event); + // Records the result of dispatching a fetch event to a service worker. static void RecordFetchEventStatus(bool is_main_resource, ServiceWorkerStatusCode status);
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc index ed87996..1d79f52 100644 --- a/content/browser/service_worker/service_worker_provider_host.cc +++ b/content/browser/service_worker/service_worker_provider_host.cc
@@ -411,7 +411,7 @@ return true; } -void ServiceWorkerProviderHost::PostMessage( +void ServiceWorkerProviderHost::PostMessageToClient( ServiceWorkerVersion* version, const base::string16& message, const std::vector<TransferredMessagePort>& sent_message_ports) {
diff --git a/content/browser/service_worker/service_worker_provider_host.h b/content/browser/service_worker/service_worker_provider_host.h index cab3ff0..2748e29 100644 --- a/content/browser/service_worker/service_worker_provider_host.h +++ b/content/browser/service_worker/service_worker_provider_host.h
@@ -170,7 +170,7 @@ bool IsContextAlive(); // Dispatches message event to the document. - void PostMessage( + void PostMessageToClient( ServiceWorkerVersion* version, const base::string16& message, const std::vector<TransferredMessagePort>& sent_message_ports);
diff --git a/content/browser/service_worker/service_worker_test_utils.h b/content/browser/service_worker/service_worker_test_utils.h index 5bb72c9..9e3983b 100644 --- a/content/browser/service_worker/service_worker_test_utils.h +++ b/content/browser/service_worker/service_worker_test_utils.h
@@ -26,12 +26,14 @@ return base::Bind(&ReceiveResult<Arg>, run_quit_thread, quit, out); } -template <typename Arg> base::Callback<void(Arg)> -CreateReceiverOnCurrentThread(Arg* out) { +template <typename Arg> +base::Callback<void(Arg)> CreateReceiverOnCurrentThread( + Arg* out, + const base::Closure& quit = base::Closure()) { BrowserThread::ID id; bool ret = BrowserThread::GetCurrentThreadIdentifier(&id); DCHECK(ret); - return base::Bind(&ReceiveResult<Arg>, id, base::Closure(), out); + return base::Bind(&ReceiveResult<Arg>, id, quit, out); } } // namespace content
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc index bf4f1f61..0636a6c 100644 --- a/content/browser/service_worker/service_worker_version.cc +++ b/content/browser/service_worker/service_worker_version.cc
@@ -158,13 +158,6 @@ callback.Run(status); } -void RunErrorServicePortConnectCallback( - const ServiceWorkerVersion::ServicePortConnectCallback& callback, - ServiceWorkerStatusCode status) { - callback.Run(status, false /* accept_connection */, base::string16(), - base::string16()); -} - void KillEmbeddedWorkerProcess(int process_id, ResultCode code) { DCHECK_CURRENTLY_ON(BrowserThread::UI); RenderProcessHost* render_process_host = @@ -480,6 +473,31 @@ update_timer_.Reset(); } +int ServiceWorkerVersion::StartRequest( + ServiceWorkerMetrics::EventType event_type, + const StatusCallback& error_callback) { + OnBeginEvent(); + DCHECK_EQ(RUNNING, running_status()) + << "Can only start a request with a running worker."; + return AddRequest(error_callback, &custom_requests_, REQUEST_CUSTOM, + event_type); +} + +bool ServiceWorkerVersion::FinishRequest(int request_id) { + PendingRequest<StatusCallback>* request = custom_requests_.Lookup(request_id); + if (!request) + return false; + RemoveCallbackAndStopIfRedundant(&custom_requests_, request_id); + return true; +} + +void ServiceWorkerVersion::RunAfterStartWorker( + const StatusCallback& error_callback, + const base::Closure& task) { + StartWorker(base::Bind(&RunTaskAfterStartWorker, weak_factory_.GetWeakPtr(), + error_callback, task)); +} + void ServiceWorkerVersion::DispatchMessageEvent( const base::string16& message, const std::vector<TransferredMessagePort>& sent_message_ports, @@ -581,7 +599,8 @@ prepare_callback.Run(); - int request_id = AddRequest(fetch_callback, &fetch_requests_, REQUEST_FETCH); + int request_id = AddRequest(fetch_callback, &fetch_requests_, REQUEST_FETCH, + ServiceWorkerMetrics::EventType::FETCH); ServiceWorkerStatusCode status = embedded_worker_->SendMessage( ServiceWorkerMsg_FetchEvent(request_id, request)); if (status != SERVICE_WORKER_OK) { @@ -610,6 +629,7 @@ int request_id = AddRequestWithExpiration(callback, &sync_requests_, REQUEST_SYNC, + ServiceWorkerMetrics::EventType::SYNC, base::TimeTicks::Now() + max_duration); if (!background_sync_dispatcher_) { embedded_worker_->GetServiceRegistry()->ConnectToRemoteService( @@ -643,8 +663,9 @@ return; } - int request_id = AddRequest(callback, ¬ification_click_requests_, - REQUEST_NOTIFICATION_CLICK); + int request_id = AddRequest( + callback, ¬ification_click_requests_, REQUEST_NOTIFICATION_CLICK, + ServiceWorkerMetrics::EventType::NOTIFICATION_CLICK); ServiceWorkerStatusCode status = embedded_worker_->SendMessage(ServiceWorkerMsg_NotificationClickEvent( request_id, persistent_notification_id, notification_data, @@ -669,7 +690,8 @@ return; } - int request_id = AddRequest(callback, &push_requests_, REQUEST_PUSH); + int request_id = AddRequest(callback, &push_requests_, REQUEST_PUSH, + ServiceWorkerMetrics::EventType::PUSH); ServiceWorkerStatusCode status = embedded_worker_->SendMessage( ServiceWorkerMsg_PushEvent(request_id, data)); if (status != SERVICE_WORKER_OK) { @@ -707,7 +729,8 @@ } int request_id = - AddRequest(callback, &geofencing_requests_, REQUEST_GEOFENCING); + AddRequest(callback, &geofencing_requests_, REQUEST_GEOFENCING, + ServiceWorkerMetrics::EventType::GEOFENCING); ServiceWorkerStatusCode status = embedded_worker_->SendMessage(ServiceWorkerMsg_GeofencingEvent( request_id, event_type, region_id, region)); @@ -717,47 +740,6 @@ } } -void ServiceWorkerVersion::DispatchServicePortConnectEvent( - const ServicePortConnectCallback& callback, - const GURL& target_url, - const GURL& origin, - int port_id) { - OnBeginEvent(); - DCHECK_EQ(ACTIVATED, status()) << status(); - - if (!base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableExperimentalWebPlatformFeatures)) { - callback.Run(SERVICE_WORKER_ERROR_ABORT, false, base::string16(), - base::string16()); - return; - } - - if (running_status() != RUNNING) { - // Schedule calling this method after starting the worker. - StartWorker( - base::Bind(&RunTaskAfterStartWorker, weak_factory_.GetWeakPtr(), - base::Bind(&RunErrorServicePortConnectCallback, callback), - base::Bind(&self::DispatchServicePortConnectEvent, - weak_factory_.GetWeakPtr(), callback, target_url, - origin, port_id))); - return; - } - - int request_id = AddRequest(callback, &service_port_connect_requests_, - REQUEST_SERVICE_PORT_CONNECT); - if (!service_port_dispatcher_) { - embedded_worker_->GetServiceRegistry()->ConnectToRemoteService( - mojo::GetProxy(&service_port_dispatcher_)); - service_port_dispatcher_.set_connection_error_handler(base::Bind( - &ServiceWorkerVersion::OnServicePortDispatcherConnectionError, - weak_factory_.GetWeakPtr())); - } - service_port_dispatcher_->Connect( - mojo::String::From(target_url), mojo::String::From(origin), port_id, - base::Bind(&ServiceWorkerVersion::OnServicePortConnectEventFinished, - weak_factory_.GetWeakPtr(), request_id)); -} - void ServiceWorkerVersion::DispatchCrossOriginMessageEvent( const NavigatorConnectClient& client, const base::string16& message, @@ -910,8 +892,9 @@ ServiceWorkerVersion::RequestInfo::RequestInfo( int id, RequestType type, + ServiceWorkerMetrics::EventType event_type, const base::TimeTicks& expiration) - : id(id), type(type), expiration(expiration) {} + : id(id), type(type), event_type(event_type), expiration(expiration) {} ServiceWorkerVersion::RequestInfo::~RequestInfo() { } @@ -932,6 +915,24 @@ ServiceWorkerVersion::PendingRequest<CallbackType>::~PendingRequest() { } +ServiceWorkerVersion::BaseMojoServiceWrapper::BaseMojoServiceWrapper( + ServiceWorkerVersion* worker, + const char* service_name) + : worker_(worker), service_name_(service_name) {} + +ServiceWorkerVersion::BaseMojoServiceWrapper::~BaseMojoServiceWrapper() { + IDMap<PendingRequest<StatusCallback>, IDMapOwnPointer>::iterator iter( + &worker_->custom_requests_); + while (!iter.IsAtEnd()) { + PendingRequest<StatusCallback>* request = iter.GetCurrentValue(); + if (request->mojo_service == service_name_) { + request->callback.Run(SERVICE_WORKER_ERROR_FAILED); + worker_->custom_requests_.Remove(iter.GetCurrentKey()); + } + iter.Advance(); + } +} + void ServiceWorkerVersion::OnThreadStarted() { if (running_status() == STOPPING) return; @@ -1083,7 +1084,8 @@ DCHECK_EQ(RUNNING, running_status()) << "Worker stopped too soon after it was started."; - int request_id = AddRequest(callback, &install_requests_, REQUEST_INSTALL); + int request_id = AddRequest(callback, &install_requests_, REQUEST_INSTALL, + ServiceWorkerMetrics::EventType::INSTALL); ServiceWorkerStatusCode status = embedded_worker_->SendMessage( ServiceWorkerMsg_InstallEvent(request_id)); if (status != SERVICE_WORKER_OK) { @@ -1097,7 +1099,8 @@ DCHECK_EQ(RUNNING, running_status()) << "Worker stopped too soon after it was started."; - int request_id = AddRequest(callback, &activate_requests_, REQUEST_ACTIVATE); + int request_id = AddRequest(callback, &activate_requests_, REQUEST_ACTIVATE, + ServiceWorkerMetrics::EventType::ACTIVATE); ServiceWorkerStatusCode status = embedded_worker_->SendMessage(ServiceWorkerMsg_ActivateEvent(request_id)); if (status != SERVICE_WORKER_OK) { @@ -1202,7 +1205,7 @@ // TODO(kinuko): Record other event statuses too. const bool handled = (result == SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE); - metrics_->RecordEventHandledStatus(ServiceWorkerMetrics::EVENT_TYPE_FETCH, + metrics_->RecordEventHandledStatus(ServiceWorkerMetrics::EventType::FETCH, handled); ServiceWorkerMetrics::RecordFetchEventTime( @@ -1293,28 +1296,6 @@ RemoveCallbackAndStopIfRedundant(&geofencing_requests_, request_id); } -void ServiceWorkerVersion::OnServicePortConnectEventFinished( - int request_id, - ServicePortConnectResult result, - const mojo::String& name, - const mojo::String& data) { - TRACE_EVENT1("ServiceWorker", - "ServiceWorkerVersion::OnServicePortConnectEventFinished", - "Request id", request_id); - PendingRequest<ServicePortConnectCallback>* request = - service_port_connect_requests_.Lookup(request_id); - if (!request) { - NOTREACHED() << "Got unexpected message: " << request_id; - return; - } - - scoped_refptr<ServiceWorkerVersion> protect(this); - request->callback.Run(SERVICE_WORKER_OK, - result == SERVICE_PORT_CONNECT_RESULT_ACCEPT, - name.To<base::string16>(), data.To<base::string16>()); - RemoveCallbackAndStopIfRedundant(&service_port_connect_requests_, request_id); -} - void ServiceWorkerVersion::OnOpenWindow(int request_id, GURL url) { // Just abort if we are shutting down. if (!context_) @@ -1436,7 +1417,7 @@ // possibly due to timing issue or bad message. return; } - provider_host->PostMessage(this, message, sent_message_ports); + provider_host->PostMessageToClient(this, message, sent_message_ports); } void ServiceWorkerVersion::OnFocusClient(int request_id, @@ -1799,8 +1780,7 @@ break; if (MaybeTimeOutRequest(info)) { stop_for_timeout = stop_for_timeout || ShouldStopIfRequestTimesOut(info); - UMA_HISTOGRAM_ENUMERATION("ServiceWorker.RequestTimeouts.Count", - info.type, NUM_REQUEST_TYPES); + ServiceWorkerMetrics::RecordEventTimeout(info.event_type); } requests_.pop(); } @@ -1851,8 +1831,7 @@ return !activate_requests_.IsEmpty() || !install_requests_.IsEmpty() || !fetch_requests_.IsEmpty() || !sync_requests_.IsEmpty() || !notification_click_requests_.IsEmpty() || !push_requests_.IsEmpty() || - !geofencing_requests_.IsEmpty() || - !service_port_connect_requests_.IsEmpty() || + !geofencing_requests_.IsEmpty() || !custom_requests_.IsEmpty() || !streaming_url_request_jobs_.empty(); } @@ -1910,12 +1889,13 @@ int ServiceWorkerVersion::AddRequest( const CallbackType& callback, IDMap<PendingRequest<CallbackType>, IDMapOwnPointer>* callback_map, - RequestType request_type) { + RequestType request_type, + ServiceWorkerMetrics::EventType event_type) { base::TimeTicks expiration_time = base::TimeTicks::Now() + base::TimeDelta::FromMinutes(kRequestTimeoutMinutes); return AddRequestWithExpiration(callback, callback_map, request_type, - expiration_time); + event_type, expiration_time); } template <typename CallbackType> @@ -1923,10 +1903,11 @@ const CallbackType& callback, IDMap<PendingRequest<CallbackType>, IDMapOwnPointer>* callback_map, RequestType request_type, + ServiceWorkerMetrics::EventType event_type, base::TimeTicks expiration) { int request_id = callback_map->Add( new PendingRequest<CallbackType>(callback, base::TimeTicks::Now())); - requests_.push(RequestInfo(request_id, request_type, expiration)); + requests_.push(RequestInfo(request_id, request_type, event_type, expiration)); return request_id; } @@ -1955,11 +1936,9 @@ case REQUEST_GEOFENCING: return RunIDMapCallback(&geofencing_requests_, info.id, SERVICE_WORKER_ERROR_TIMEOUT); - case REQUEST_SERVICE_PORT_CONNECT: - return RunIDMapCallback(&service_port_connect_requests_, info.id, - SERVICE_WORKER_ERROR_TIMEOUT, - false /* accept_connection */, base::string16(), - base::string16()); + case REQUEST_CUSTOM: + return RunIDMapCallback(&custom_requests_, info.id, + SERVICE_WORKER_ERROR_TIMEOUT); case NUM_REQUEST_TYPES: break; } @@ -1981,7 +1960,10 @@ case REQUEST_NOTIFICATION_CLICK: case REQUEST_PUSH: case REQUEST_GEOFENCING: - case REQUEST_SERVICE_PORT_CONNECT: + return true; + case REQUEST_CUSTOM: + // TODO(mek): Custom requests need some way to specify their timeout + // behavior. return true; case NUM_REQUEST_TYPES: NOTREACHED() << "Got unexpected request type: " << info.type; @@ -2102,11 +2084,11 @@ RunIDMapCallbacks(¬ification_click_requests_, SERVICE_WORKER_ERROR_FAILED); RunIDMapCallbacks(&push_requests_, SERVICE_WORKER_ERROR_FAILED); RunIDMapCallbacks(&geofencing_requests_, SERVICE_WORKER_ERROR_FAILED); + RunIDMapCallbacks(&custom_requests_, SERVICE_WORKER_ERROR_FAILED); // Close all mojo services. This will also fire and clear all callbacks // for messages that are still outstanding for those services. - OnServicePortDispatcherConnectionError(); - + mojo_services_.clear(); OnBackgroundSyncDispatcherConnectionError(); // TODO(falken): Call SWURLRequestJob::ClearStream here? @@ -2118,18 +2100,17 @@ StartWorkerInternal(); } -void ServiceWorkerVersion::OnServicePortDispatcherConnectionError() { - RunIDMapCallbacks(&service_port_connect_requests_, - SERVICE_WORKER_ERROR_FAILED, false, base::string16(), - base::string16()); - service_port_dispatcher_.reset(); -} - void ServiceWorkerVersion::OnBackgroundSyncDispatcherConnectionError() { RunIDMapCallbacks(&sync_requests_, SERVICE_WORKER_ERROR_FAILED); background_sync_dispatcher_.reset(); } +void ServiceWorkerVersion::OnMojoConnectionError(const char* service_name) { + // Simply deleting the service will cause error callbacks to be called from + // the destructor of the MojoServiceWrapper instance. + mojo_services_.erase(service_name); +} + void ServiceWorkerVersion::OnBeginEvent() { if (should_exclude_from_uma_ || running_status() != RUNNING || idle_time_.is_null()) {
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h index 5856ed6..53b1bfd1 100644 --- a/content/browser/service_worker/service_worker_version.h +++ b/content/browser/service_worker/service_worker_version.h
@@ -14,6 +14,7 @@ #include <vector> #include "base/callback.h" +#include "base/containers/scoped_ptr_hash_map.h" #include "base/gtest_prod_util.h" #include "base/id_map.h" #include "base/macros.h" @@ -23,10 +24,10 @@ #include "base/timer/timer.h" #include "content/browser/background_sync/background_sync_registration_handle.h" #include "content/browser/service_worker/embedded_worker_instance.h" +#include "content/browser/service_worker/service_worker_metrics.h" #include "content/browser/service_worker/service_worker_script_cache_map.h" #include "content/common/background_sync_service.mojom.h" #include "content/common/content_export.h" -#include "content/common/service_port_service.mojom.h" #include "content/common/service_worker/service_worker_status_code.h" #include "content/common/service_worker/service_worker_types.h" #include "content/public/common/service_registry.h" @@ -74,11 +75,6 @@ typedef base::Callback<void(ServiceWorkerStatusCode, ServiceWorkerFetchEventResult, const ServiceWorkerResponse&)> FetchCallback; - typedef base::Callback<void(ServiceWorkerStatusCode, - bool /* accept_connction */, - const base::string16& /* name */, - const base::string16& /* data */)> - ServicePortConnectCallback; enum RunningStatus { STOPPED = EmbeddedWorkerInstance::STOPPED, @@ -178,6 +174,36 @@ // Starts an update now. void StartUpdate(); + // Starts the worker if it isn't already running, and calls |task| when the + // worker is running, or |error_callback| if starting the worker failed. + void RunAfterStartWorker(const StatusCallback& error_callback, + const base::Closure& task); + + // Call this while the worker is running before dispatching an event to the + // worker. This informs ServiceWorkerVersion about the event in progress. + // Returns a request id, which should later be passed to FinishRequest when + // the event finished. + // The |error_callback| is called if either ServiceWorkerVersion decides the + // event is taking too long, or if for some reason the worker stops or is + // killed before the request finishes. + int StartRequest(ServiceWorkerMetrics::EventType event_type, + const StatusCallback& error_callback); + + // Informs ServiceWorkerVersion that an event has finished being dispatched. + // Returns false if no pending requests with the provided id exist, for + // example if the request has already timed out. + bool FinishRequest(int request_id); + + // Connects to a specific mojo service exposed by the (running) service + // worker. If a connection to a service for the same Interface already exists + // this will return that existing connection. The |request_id| must be a value + // previously returned by StartRequest. If the connection to the service + // fails or closes before the request finished, the error callback associated + // with |request_id| is called. + // Only call GetMojoServiceForRequest once for a specific |request_id|. + template <typename Interface> + base::WeakPtr<Interface> GetMojoServiceForRequest(int request_id); + // Sends a message event to the associated embedded worker. void DispatchMessageEvent( const base::string16& message, @@ -254,16 +280,6 @@ const std::string& region_id, const blink::WebCircularGeofencingRegion& region); - // Sends a ServicePort connect event to the associated embedded worker and - // asynchronously calls |callback| with the response from the worker. - // - // This must be called when the status() is ACTIVATED. - void DispatchServicePortConnectEvent( - const ServicePortConnectCallback& callback, - const GURL& target_url, - const GURL& origin, - int port_id); - // Sends a cross origin message event to the associated embedded worker and // asynchronously calls |callback| when the message was sent (or failed to // sent). @@ -366,6 +382,7 @@ FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, StaleUpdate_DoNotDeferTimer); FRIEND_TEST_ALL_PREFIXES(ServiceWorkerWaitForeverInFetchTest, RequestTimeout); + FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, RequestTimeout); FRIEND_TEST_ALL_PREFIXES(ServiceWorkerFailToStartTest, Timeout); FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionBrowserTest, TimeoutStartingWorker); @@ -382,7 +399,6 @@ class Metrics; class PingController; - // Used for UMA; add new entries to the end, before NUM_REQUEST_TYPES. enum RequestType { REQUEST_ACTIVATE, REQUEST_INSTALL, @@ -391,16 +407,20 @@ REQUEST_NOTIFICATION_CLICK, REQUEST_PUSH, REQUEST_GEOFENCING, - REQUEST_SERVICE_PORT_CONNECT, + REQUEST_CUSTOM, NUM_REQUEST_TYPES }; struct RequestInfo { - RequestInfo(int id, RequestType type, const base::TimeTicks& expiration); + RequestInfo(int id, + RequestType type, + ServiceWorkerMetrics::EventType event_type, + const base::TimeTicks& expiration); ~RequestInfo(); bool operator>(const RequestInfo& other) const; int id; RequestType type; + ServiceWorkerMetrics::EventType event_type; base::TimeTicks expiration; }; @@ -411,6 +431,47 @@ CallbackType callback; base::TimeTicks start_time; + // Name of the mojo service this request is associated with. Used to call + // the callback when a connection closes with outstanding requests. + // Compared as pointer, so should only contain static strings. Typically + // this would be Interface::Name_ for some mojo interface. + const char* mojo_service = nullptr; + }; + + // Base class to enable storing a list of mojo interface pointers for + // arbitrary interfaces. The destructor is also responsible for calling the + // error callbacks for any outstanding requests using this service. + class CONTENT_EXPORT BaseMojoServiceWrapper { + public: + BaseMojoServiceWrapper(ServiceWorkerVersion* worker, + const char* service_name); + virtual ~BaseMojoServiceWrapper(); + + private: + ServiceWorkerVersion* worker_; + const char* service_name_; + + DISALLOW_COPY_AND_ASSIGN(BaseMojoServiceWrapper); + }; + + // Wrapper around a mojo::InterfacePtr, which passes out WeakPtr's to the + // interface. + template <typename Interface> + class MojoServiceWrapper : public BaseMojoServiceWrapper { + public: + MojoServiceWrapper(ServiceWorkerVersion* worker, + mojo::InterfacePtr<Interface> interface) + : BaseMojoServiceWrapper(worker, Interface::Name_), + interface_(std::move(interface)), + weak_ptr_factory_(interface_.get()) {} + + base::WeakPtr<Interface> GetWeakPtr() { + return weak_ptr_factory_.GetWeakPtr(); + } + + private: + mojo::InterfacePtr<Interface> interface_; + base::WeakPtrFactory<Interface> weak_ptr_factory_; }; typedef ServiceWorkerVersion self; @@ -481,10 +542,6 @@ void OnPushEventFinished(int request_id, blink::WebServiceWorkerEventResult result); void OnGeofencingEventFinished(int request_id); - void OnServicePortConnectEventFinished(int request_id, - ServicePortConnectResult result, - const mojo::String& name, - const mojo::String& data); void OnOpenWindow(int request_id, GURL url); void OnOpenWindowFinished(int request_id, ServiceWorkerStatusCode status, @@ -555,13 +612,15 @@ int AddRequest( const CallbackType& callback, IDMap<PendingRequest<CallbackType>, IDMapOwnPointer>* callback_map, - RequestType request_type); + RequestType request_type, + ServiceWorkerMetrics::EventType event_type); template <typename CallbackType> int AddRequestWithExpiration( const CallbackType& callback, IDMap<PendingRequest<CallbackType>, IDMapOwnPointer>* callback_map, RequestType request_type, + ServiceWorkerMetrics::EventType event_type, base::TimeTicks expiration); bool MaybeTimeOutRequest(const RequestInfo& info); @@ -587,9 +646,11 @@ // Called when a connection to a mojo event Dispatcher drops or fails. // Calls callbacks for any outstanding requests to the dispatcher as well // as cleans up the dispatcher. - void OnServicePortDispatcherConnectionError(); void OnBackgroundSyncDispatcherConnectionError(); + // Called when the remote side of a connection to a mojo service is lost. + void OnMojoConnectionError(const char* service_name); + // Called at the beginning of each Dispatch*Event function: records // the time elapsed since idle (generally the time since the previous // event ended). @@ -617,12 +678,18 @@ notification_click_requests_; IDMap<PendingRequest<StatusCallback>, IDMapOwnPointer> push_requests_; IDMap<PendingRequest<StatusCallback>, IDMapOwnPointer> geofencing_requests_; - IDMap<PendingRequest<ServicePortConnectCallback>, IDMapOwnPointer> - service_port_connect_requests_; + IDMap<PendingRequest<StatusCallback>, IDMapOwnPointer> custom_requests_; - ServicePortDispatcherPtr service_port_dispatcher_; BackgroundSyncServiceClientPtr background_sync_dispatcher_; + // Stores all open connections to mojo services. Maps the service name to + // the actual interface pointer. When a connection is closed it is removed + // from this map. + // mojo_services_[Interface::Name_] is assumed to always contain a + // MojoServiceWrapper<Interface> instance. + base::ScopedPtrHashMap<const char*, scoped_ptr<BaseMojoServiceWrapper>> + mojo_services_; + std::set<const ServiceWorkerURLRequestJob*> streaming_url_request_jobs_; std::map<std::string, ServiceWorkerProviderHost*> controllee_map_; @@ -677,6 +744,32 @@ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerVersion); }; +template <typename Interface> +base::WeakPtr<Interface> ServiceWorkerVersion::GetMojoServiceForRequest( + int request_id) { + DCHECK_EQ(RUNNING, running_status()); + PendingRequest<StatusCallback>* request = custom_requests_.Lookup(request_id); + DCHECK(request) << "Invalid request id"; + DCHECK(!request->mojo_service) + << "Request is already associated with a mojo service"; + + MojoServiceWrapper<Interface>* service = + static_cast<MojoServiceWrapper<Interface>*>( + mojo_services_.get(Interface::Name_)); + if (!service) { + mojo::InterfacePtr<Interface> interface; + embedded_worker_->GetServiceRegistry()->ConnectToRemoteService( + mojo::GetProxy(&interface)); + interface.set_connection_error_handler( + base::Bind(&ServiceWorkerVersion::OnMojoConnectionError, + weak_factory_.GetWeakPtr(), Interface::Name_)); + service = new MojoServiceWrapper<Interface>(this, std::move(interface)); + mojo_services_.add(Interface::Name_, make_scoped_ptr(service)); + } + request->mojo_service = Interface::Name_; + return service->GetWeakPtr(); +} + } // namespace content #endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_VERSION_H_
diff --git a/content/browser/service_worker/service_worker_version_unittest.cc b/content/browser/service_worker/service_worker_version_unittest.cc index 82f55b6..8fb33c3 100644 --- a/content/browser/service_worker/service_worker_version_unittest.cc +++ b/content/browser/service_worker/service_worker_version_unittest.cc
@@ -17,6 +17,8 @@ #include "content/common/service_worker/service_worker_utils.h" #include "content/public/test/mock_render_process_host.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "content/public/test/test_mojo_service.mojom.h" +#include "content/public/test/test_utils.h" #include "mojo/public/cpp/bindings/strong_binding.h" #include "testing/gtest/include/gtest/gtest.h" @@ -176,6 +178,27 @@ base::TimeDelta::FromSeconds(1); } +class TestMojoServiceImpl : public TestMojoService { + public: + static void Create(mojo::InterfaceRequest<TestMojoService> request) { + new TestMojoServiceImpl(std::move(request)); + } + + void DoSomething(const DoSomethingCallback& callback) override { + callback.Run(); + } + + void GetRequestorURL(const GetRequestorURLCallback& callback) override { + callback.Run(mojo::String("")); + } + + private: + explicit TestMojoServiceImpl(mojo::InterfaceRequest<TestMojoService> request) + : binding_(this, std::move(request)) {} + + mojo::StrongBinding<TestMojoService> binding_; +}; + } // namespace class ServiceWorkerVersionTest : public testing::Test { @@ -340,6 +363,31 @@ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerWaitForeverInFetchTest); }; +class MessageReceiverMojoTestService : public MessageReceiver { + public: + MessageReceiverMojoTestService() : MessageReceiver() {} + ~MessageReceiverMojoTestService() override {} + + void OnSetupMojo(ServiceRegistry* service_registry) override { + service_registry->AddService(base::Bind(&TestMojoServiceImpl::Create)); + } + + private: + DISALLOW_COPY_AND_ASSIGN(MessageReceiverMojoTestService); +}; + +class ServiceWorkerVersionWithMojoTest : public ServiceWorkerVersionTest { + protected: + ServiceWorkerVersionWithMojoTest() : ServiceWorkerVersionTest() {} + + scoped_ptr<MessageReceiver> GetMessageReceiver() override { + return make_scoped_ptr(new MessageReceiverMojoTestService()); + } + + private: + DISALLOW_COPY_AND_ASSIGN(ServiceWorkerVersionWithMojoTest); +}; + TEST_F(ServiceWorkerVersionTest, ConcurrentStartAndStop) { // Call StartWorker() multiple times. ServiceWorkerStatusCode status1 = SERVICE_WORKER_ERROR_FAILED; @@ -613,6 +661,17 @@ EXPECT_EQ(SERVICE_WORKER_OK, status); EXPECT_LT(idle_time, version_->idle_time_); + // Starting and finishing a request resets the idle time. + version_->idle_time_ -= kOneSecond; + idle_time = version_->idle_time_; + int request_id = + version_->StartRequest(ServiceWorkerMetrics::EventType::SYNC, + CreateReceiverOnCurrentThread(&status)); + EXPECT_TRUE(version_->FinishRequest(request_id)); + + EXPECT_EQ(SERVICE_WORKER_OK, status); + EXPECT_LT(idle_time, version_->idle_time_); + // Dispatching a message event resets the idle time. std::vector<TransferredMessagePort> ports; SetUpDummyMessagePort(&ports); @@ -880,6 +939,35 @@ EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->running_status()); } +TEST_F(ServiceWorkerVersionTest, RequestTimeout) { + ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK; // dummy value + + version_->SetStatus(ServiceWorkerVersion::ACTIVATED); + version_->StartWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); + base::RunLoop().RunUntilIdle(); + int request_id = + version_->StartRequest(ServiceWorkerMetrics::EventType::SYNC, + CreateReceiverOnCurrentThread(&status)); + base::RunLoop().RunUntilIdle(); + + // Callback has not completed yet. + EXPECT_EQ(SERVICE_WORKER_ERROR_NETWORK, status); + EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status()); + + // Simulate timeout. + EXPECT_TRUE(version_->timeout_timer_.IsRunning()); + version_->SetAllRequestExpirations( + base::TimeTicks::Now() - + base::TimeDelta::FromMinutes( + ServiceWorkerVersion::kRequestTimeoutMinutes + 1)); + version_->timeout_timer_.user_task().Run(); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(SERVICE_WORKER_ERROR_TIMEOUT, status); + EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->running_status()); + + EXPECT_FALSE(version_->FinishRequest(request_id)); +} + TEST_F(ServiceWorkerFailToStartTest, RendererCrash) { ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK; // dummy value version_->StartWorker( @@ -1055,4 +1143,85 @@ EXPECT_EQ(valid_scope_2, version_->foreign_fetch_scopes_[1]); } +TEST_F(ServiceWorkerVersionTest, RendererCrashDuringEvent) { + ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK; // dummy value + + version_->SetStatus(ServiceWorkerVersion::ACTIVATED); + version_->StartWorker(CreateReceiverOnCurrentThread(&status)); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(SERVICE_WORKER_OK, status); + EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status()); + + int request_id = + version_->StartRequest(ServiceWorkerMetrics::EventType::SYNC, + CreateReceiverOnCurrentThread(&status)); + base::RunLoop().RunUntilIdle(); + + // Callback has not completed yet. + EXPECT_EQ(SERVICE_WORKER_OK, status); + + // Simulate renderer crash: do what + // ServiceWorkerDispatcherHost::OnFilterRemoved does. + int process_id = helper_->mock_render_process_id(); + helper_->context()->RemoveAllProviderHostsForProcess(process_id); + helper_->context()->embedded_worker_registry()->RemoveChildProcessSender( + process_id); + base::RunLoop().RunUntilIdle(); + + // Callback completed. + EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED, status); + EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->running_status()); + + // Request already failed, calling finsh should return false. + EXPECT_FALSE(version_->FinishRequest(request_id)); +} + +TEST_F(ServiceWorkerVersionWithMojoTest, MojoService) { + ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK; // dummy value + + version_->SetStatus(ServiceWorkerVersion::ACTIVATED); + version_->StartWorker(CreateReceiverOnCurrentThread(&status)); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(SERVICE_WORKER_OK, status); + EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status()); + + scoped_refptr<MessageLoopRunner> runner(new MessageLoopRunner); + int request_id = version_->StartRequest( + ServiceWorkerMetrics::EventType::SYNC, + CreateReceiverOnCurrentThread(&status, runner->QuitClosure())); + base::WeakPtr<TestMojoService> service = + version_->GetMojoServiceForRequest<TestMojoService>(request_id); + service->DoSomething(runner->QuitClosure()); + runner->Run(); + + // Mojo service does exist in worker, so error callback should not have been + // called and FinishRequest should return true. + EXPECT_EQ(SERVICE_WORKER_OK, status); + EXPECT_TRUE(version_->FinishRequest(request_id)); +} + +TEST_F(ServiceWorkerVersionTest, NonExistentMojoService) { + ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK; // dummy value + + version_->SetStatus(ServiceWorkerVersion::ACTIVATED); + version_->StartWorker(CreateReceiverOnCurrentThread(&status)); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(SERVICE_WORKER_OK, status); + EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status()); + + scoped_refptr<MessageLoopRunner> runner(new MessageLoopRunner); + int request_id = version_->StartRequest( + ServiceWorkerMetrics::EventType::SYNC, + CreateReceiverOnCurrentThread(&status, runner->QuitClosure())); + base::WeakPtr<TestMojoService> service = + version_->GetMojoServiceForRequest<TestMojoService>(request_id); + service->DoSomething(runner->QuitClosure()); + runner->Run(); + + // Mojo service doesn't exist in worker, so error callback should have been + // called and FinishRequest should return false. + EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED, status); + EXPECT_FALSE(version_->FinishRequest(request_id)); +} + } // namespace content
diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h index 9d9e6ee..ece0a8e 100644 --- a/content/browser/storage_partition_impl.h +++ b/content/browser/storage_partition_impl.h
@@ -86,6 +86,7 @@ private: friend class BackgroundSyncManagerTest; + friend class BackgroundSyncServiceImplTest; friend class StoragePartitionImplMap; FRIEND_TEST_ALL_PREFIXES(StoragePartitionShaderClearTest, ClearShaderCache); FRIEND_TEST_ALL_PREFIXES(StoragePartitionImplTest,
diff --git a/content/child/resource_dispatcher.cc b/content/child/resource_dispatcher.cc index bcb99b9..94cfc79 100644 --- a/content/child/resource_dispatcher.cc +++ b/content/child/resource_dispatcher.cc
@@ -40,6 +40,10 @@ #include "net/base/request_priority.h" #include "net/http/http_response_headers.h" +#if defined(OS_WIN) +#include <windows.h> +#endif + namespace content { namespace { @@ -186,6 +190,22 @@ request_info->peer->OnReceivedCachedMetadata(&data.front(), data.size()); } +#if defined(OS_WIN) +void ResourceDispatcher::OnSetDataBufferDebug1(int request_id, int handle) { + PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); + if (!request_info) + return; + request_info->handle1 = handle; +} + +void ResourceDispatcher::OnSetDataBufferDebug2(int request_id, int handle) { + PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); + if (!request_info) + return; + request_info->handle2 = handle - 3; +} +#endif + void ResourceDispatcher::OnSetDataBuffer(int request_id, base::SharedMemoryHandle shm_handle, int shm_size, @@ -197,6 +217,11 @@ bool shm_valid = base::SharedMemory::IsHandleValid(shm_handle); CHECK((shm_valid && shm_size > 0) || (!shm_valid && !shm_size)); +#if defined(OS_WIN) + int handle_int = static_cast<int>(HandleToLong(shm_handle.GetHandle())); + CHECK(request_info->handle2 != -2 && request_info->handle2 == handle_int); + CHECK(request_info->handle1 != -2 && request_info->handle1 == handle_int); +#endif request_info->buffer.reset( new base::SharedMemory(shm_handle, true)); // read only @@ -536,8 +561,7 @@ frame_origin(frame_origin), response_url(request_url), download_to_file(download_to_file), - request_start(base::TimeTicks::Now()) { -} + request_start(base::TimeTicks::Now()) {} ResourceDispatcher::PendingRequestInfo::~PendingRequestInfo() { if (threaded_data_provider) @@ -551,6 +575,10 @@ IPC_MESSAGE_HANDLER(ResourceMsg_ReceivedCachedMetadata, OnReceivedCachedMetadata) IPC_MESSAGE_HANDLER(ResourceMsg_ReceivedRedirect, OnReceivedRedirect) +#if defined(OS_WIN) + IPC_MESSAGE_HANDLER(ResourceMsg_SetDataBufferDebug1, OnSetDataBufferDebug1) + IPC_MESSAGE_HANDLER(ResourceMsg_SetDataBufferDebug2, OnSetDataBufferDebug2) +#endif IPC_MESSAGE_HANDLER(ResourceMsg_SetDataBuffer, OnSetDataBuffer) IPC_MESSAGE_HANDLER(ResourceMsg_DataReceivedDebug, OnReceivedDataDebug) IPC_MESSAGE_HANDLER(ResourceMsg_DataReceived, OnReceivedData) @@ -735,6 +763,10 @@ case ResourceMsg_ReceivedResponse::ID: case ResourceMsg_ReceivedCachedMetadata::ID: case ResourceMsg_ReceivedRedirect::ID: +#if defined(OS_WIN) + case ResourceMsg_SetDataBufferDebug1::ID: + case ResourceMsg_SetDataBufferDebug2::ID: +#endif case ResourceMsg_SetDataBuffer::ID: case ResourceMsg_DataReceivedDebug::ID: case ResourceMsg_DataReceived::ID:
diff --git a/content/child/resource_dispatcher.h b/content/child/resource_dispatcher.h index 8f1946e..edd5450 100644 --- a/content/child/resource_dispatcher.h +++ b/content/child/resource_dispatcher.h
@@ -21,6 +21,7 @@ #include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" #include "base/time/time.h" +#include "build/build_config.h" #include "content/common/content_export.h" #include "content/public/common/resource_type.h" #include "ipc/ipc_listener.h" @@ -178,6 +179,12 @@ // Debugging for https://code.google.com/p/chromium/issues/detail?id=527588. int data_offset = -1; +#if defined(OS_WIN) + // This handle is passed through Chrome IPC as a raw int. + int handle1 = -2; + // This handle is passed through Chrome IPC as a raw int + 3. + int handle2 = -2; +#endif }; using PendingRequestMap = std::map<int, scoped_ptr<PendingRequestInfo>>; @@ -195,6 +202,10 @@ void OnReceivedRedirect(int request_id, const net::RedirectInfo& redirect_info, const ResourceResponseHead& response_head); +#if defined(OS_WIN) + void OnSetDataBufferDebug1(int request_id, int handle); + void OnSetDataBufferDebug2(int request_id, int handle); +#endif void OnSetDataBuffer(int request_id, base::SharedMemoryHandle shm_handle, int shm_size,
diff --git a/content/child/resource_dispatcher_unittest.cc b/content/child/resource_dispatcher_unittest.cc index aafa029c..f902985 100644 --- a/content/child/resource_dispatcher_unittest.cc +++ b/content/child/resource_dispatcher_unittest.cc
@@ -17,6 +17,7 @@ #include "base/process/process_handle.h" #include "base/run_loop.h" #include "base/stl_util.h" +#include "build/build_config.h" #include "content/child/request_extra_data.h" #include "content/child/request_info.h" #include "content/common/appcache_interfaces.h" @@ -298,6 +299,12 @@ base::SharedMemoryHandle duplicate_handle; EXPECT_TRUE(shared_memory->ShareToProcess(base::GetCurrentProcessHandle(), &duplicate_handle)); +#if defined(OS_WIN) + EXPECT_TRUE(dispatcher_.OnMessageReceived(ResourceMsg_SetDataBufferDebug1( + request_id, HandleToLong(duplicate_handle.GetHandle())))); + EXPECT_TRUE(dispatcher_.OnMessageReceived(ResourceMsg_SetDataBufferDebug2( + request_id, HandleToLong(duplicate_handle.GetHandle()) + 3))); +#endif EXPECT_TRUE(dispatcher_.OnMessageReceived( ResourceMsg_SetDataBuffer(request_id, duplicate_handle, shared_memory->requested_size(), 0)));
diff --git a/content/common/resource_messages.h b/content/common/resource_messages.h index cc0b3d0..918afc1 100644 --- a/content/common/resource_messages.h +++ b/content/common/resource_messages.h
@@ -12,6 +12,7 @@ #include "base/memory/shared_memory.h" #include "base/process/process.h" +#include "build/build_config.h" #include "content/common/content_param_traits_macros.h" #include "content/common/navigation_params.h" #include "content/common/resource_request_body.h" @@ -333,6 +334,22 @@ net::RedirectInfo /* redirect_info */, content::ResourceResponseHead) +#if defined(OS_WIN) +// A message that always precedes ResourceMsg_SetDataBuffer. |shm_handle| is the +// underlying HANDLE of base::SharedMemoryHandle converted to an int. Exists to +// help debug https://code.google.com/p/chromium/issues/detail?id=527588. +IPC_MESSAGE_CONTROL2(ResourceMsg_SetDataBufferDebug1, + int /* request_id */, + int /* shm_handle */) + +// A message that always precedes ResourceMsg_SetDataBuffer. |shm_handle| is the +// underlying HANDLE of base::SharedMemoryHandle converted to an int + 3. Exists +// to help debug https://code.google.com/p/chromium/issues/detail?id=527588. +IPC_MESSAGE_CONTROL2(ResourceMsg_SetDataBufferDebug2, + int /* request_id */, + int /* shm_handle */) +#endif + // Sent to set the shared memory buffer to be used to transmit response data to // the renderer. Subsequent DataReceived messages refer to byte ranges in the // shared memory buffer. The shared memory buffer should be retained by the @@ -343,7 +360,6 @@ // // TODO(darin): The |renderer_pid| parameter is just a temporary parameter, // added to help in debugging crbug/160401. -// IPC_MESSAGE_CONTROL4(ResourceMsg_SetDataBuffer, int /* request_id */, base::SharedMemoryHandle /* shm_handle */,
diff --git a/content/public/browser/resource_dispatcher_host_delegate.cc b/content/public/browser/resource_dispatcher_host_delegate.cc index ce903af..3fb54d3 100644 --- a/content/public/browser/resource_dispatcher_host_delegate.cc +++ b/content/public/browser/resource_dispatcher_host_delegate.cc
@@ -4,6 +4,7 @@ #include "content/public/browser/resource_dispatcher_host_delegate.h" +#include "content/public/browser/resource_request_info.h" #include "content/public/browser/stream_info.h" namespace content { @@ -45,7 +46,7 @@ bool ResourceDispatcherHostDelegate::HandleExternalProtocol( const GURL& url, int child_id, - int route_id, + const ResourceRequestInfo::WebContentsGetter& web_contents_getter, bool is_main_frame, ui::PageTransition page_transition, bool has_user_gesture) {
diff --git a/content/public/browser/resource_dispatcher_host_delegate.h b/content/public/browser/resource_dispatcher_host_delegate.h index 1226d15..ad6e2c5e 100644 --- a/content/public/browser/resource_dispatcher_host_delegate.h +++ b/content/public/browser/resource_dispatcher_host_delegate.h
@@ -10,6 +10,7 @@ #include "base/files/file_path.h" #include "base/memory/scoped_ptr.h" #include "content/common/content_export.h" +#include "content/public/browser/resource_request_info.h" #include "content/public/common/resource_type.h" #include "ui/base/page_transition_types.h" @@ -73,12 +74,13 @@ // Launches the url for the given tab. Returns true if an attempt to handle // the url was made, e.g. by launching an app. Note that this does not // guarantee that the app successfully handled it. - virtual bool HandleExternalProtocol(const GURL& url, - int child_id, - int route_id, - bool is_main_frame, - ui::PageTransition page_transition, - bool has_user_gesture); + virtual bool HandleExternalProtocol( + const GURL& url, + int child_id, + const ResourceRequestInfo::WebContentsGetter& web_contents_getter, + bool is_main_frame, + ui::PageTransition page_transition, + bool has_user_gesture); // Returns true if we should force the given resource to be downloaded. // Otherwise, the content layer decides.
diff --git a/content/public/test/mock_render_process_host.cc b/content/public/test/mock_render_process_host.cc index 076f028..487772e 100644 --- a/content/public/test/mock_render_process_host.cc +++ b/content/public/test/mock_render_process_host.cc
@@ -263,7 +263,7 @@ } ServiceRegistry* MockRenderProcessHost::GetServiceRegistry() { - return NULL; + return service_registry_.get(); } const base::TimeTicks& MockRenderProcessHost::GetInitTimeForNavigationMetrics()
diff --git a/content/public/test/mock_render_process_host.h b/content/public/test/mock_render_process_host.h index 295c772..a86b4f5 100644 --- a/content/public/test/mock_render_process_host.h +++ b/content/public/test/mock_render_process_host.h
@@ -14,6 +14,7 @@ #include "base/observer_list.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_process_host_factory.h" +#include "content/public/common/service_registry.h" #include "ipc/ipc_test_sink.h" class StoragePartition; @@ -136,6 +137,10 @@ int worker_ref_count() const { return worker_ref_count_; } + void SetServiceRegistry(scoped_ptr<ServiceRegistry> service_registry) { + service_registry_ = std::move(service_registry); + } + private: // Stores IPC messages that would have been sent to the renderer. IPC::TestSink sink_; @@ -155,6 +160,7 @@ bool is_process_backgrounded_; scoped_ptr<base::ProcessHandle> process_handle; int worker_ref_count_; + scoped_ptr<ServiceRegistry> service_registry_; DISALLOW_COPY_AND_ASSIGN(MockRenderProcessHost); };
diff --git a/content/public/test/test_browser_context.cc b/content/public/test/test_browser_context.cc index a022778c..b86c5634 100644 --- a/content/public/test/test_browser_context.cc +++ b/content/public/test/test_browser_context.cc
@@ -143,6 +143,9 @@ } BackgroundSyncController* TestBrowserContext::GetBackgroundSyncController() { + if (!background_sync_controller_) + background_sync_controller_.reset(new BackgroundSyncController()); + return background_sync_controller_.get(); }
diff --git a/content/renderer/media/audio_renderer_mixer_manager.cc b/content/renderer/media/audio_renderer_mixer_manager.cc index 95ca916..97d0e15 100644 --- a/content/renderer/media/audio_renderer_mixer_manager.cc +++ b/content/renderer/media/audio_renderer_mixer_manager.cc
@@ -89,16 +89,24 @@ #if defined(OS_CHROMEOS) || defined(OS_ANDROID) int sample_rate = params.sample_rate(); #else - int sample_rate = hardware_params.sample_rate(); + int sample_rate = + hardware_params.format() != media::AudioParameters::AUDIO_FAKE + ? hardware_params.sample_rate() + : params.sample_rate(); #endif + int buffer_size = + hardware_params.format() != media::AudioParameters::AUDIO_FAKE + ? media::AudioHardwareConfig::GetHighLatencyBufferSize( + hardware_params) + : params.frames_per_buffer(); + // Create output parameters based on the audio hardware configuration for // passing on to the output sink. Force to 16-bit output for now since we // know that works everywhere; ChromeOS does not support other bit depths. media::AudioParameters output_params( media::AudioParameters::AUDIO_PCM_LOW_LATENCY, params.channel_layout(), - sample_rate, 16, - media::AudioHardwareConfig::GetHighLatencyBufferSize(hardware_params)); + sample_rate, 16, buffer_size); // If we've created invalid output parameters, simply pass on the input // params and let the browser side handle automatic fallback.
diff --git a/content/shell/browser/shell_browser_context.cc b/content/shell/browser/shell_browser_context.cc index 492eb8b..31e1485 100644 --- a/content/shell/browser/shell_browser_context.cc +++ b/content/shell/browser/shell_browser_context.cc
@@ -14,6 +14,7 @@ #include "base/path_service.h" #include "base/threading/thread.h" #include "build/build_config.h" +#include "content/public/browser/background_sync_controller.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/storage_partition.h" #include "content/public/common/content_switches.h" @@ -207,7 +208,9 @@ } BackgroundSyncController* ShellBrowserContext::GetBackgroundSyncController() { - return nullptr; + if (!background_sync_controller_) + background_sync_controller_.reset(new BackgroundSyncController()); + return background_sync_controller_.get(); } } // namespace content
diff --git a/content/shell/browser/shell_browser_context.h b/content/shell/browser/shell_browser_context.h index d5c95f69..bf40cd3 100644 --- a/content/shell/browser/shell_browser_context.h +++ b/content/shell/browser/shell_browser_context.h
@@ -111,6 +111,7 @@ bool ignore_certificate_errors_; scoped_ptr<ShellDownloadManagerDelegate> download_manager_delegate_; scoped_ptr<PermissionManager> permission_manager_; + scoped_ptr<BackgroundSyncController> background_sync_controller_; private: // Performs initialization of the ShellBrowserContext while IO is still
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py index 7717179..411ddf6 100644 --- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py +++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -86,6 +86,9 @@ self.Fail('conformance2/rendering/draw-buffers.html', bug=483282) self.Fail('conformance2/samplers/sampler-drawing-test.html', bug=483282) self.Skip('conformance2/textures/webgl_canvas/*', bug=483282) + # Remove after we roll in https://github.com/KhronosGroup/WebGL/pull/1408. + self.Fail('conformance2/textures/misc/tex-input-validation.html', + bug=575550) # Windows only. self.Skip('deqp/functional/gles3/readpixel.html', ['win'], bug=483282) @@ -102,8 +105,6 @@ self.Fail('conformance2/textures/canvas/*', ['win'], bug=483282) self.Fail('conformance2/textures/misc/gl-get-tex-parameter.html', ['win'], bug=483282) - self.Fail('conformance2/textures/misc/tex-input-validation.html', - ['win'], bug=483282) self.Skip('conformance2/textures/misc/tex-mipmap-levels.html', ['win'], bug=483282) self.Skip('conformance2/transform_feedback/transform_feedback.html',
diff --git a/courgette/label_manager.cc b/courgette/label_manager.cc index 06f3558..268bda2d 100644 --- a/courgette/label_manager.cc +++ b/courgette/label_manager.cc
@@ -16,9 +16,13 @@ namespace courgette { -LabelManager::RvaVisitor::~RvaVisitor() {} +LabelManager::LabelManager() {} -LabelManager::SimpleIndexAssigner::SimpleIndexAssigner(LabelVector* labels) +LabelManager::~LabelManager() {} + +LabelManagerImpl::RvaVisitor::~RvaVisitor() {} + +LabelManagerImpl::SimpleIndexAssigner::SimpleIndexAssigner(LabelVector* labels) : labels_(labels) { // Find the maximum assigned index. Not bounded by |labels_| size. int max_index = -1; @@ -42,9 +46,9 @@ VLOG(1) << used << " of " << labels_->size() << " labels pre-assigned."; } -LabelManager::SimpleIndexAssigner::~SimpleIndexAssigner() {} +LabelManagerImpl::SimpleIndexAssigner::~SimpleIndexAssigner() {} -void LabelManager::SimpleIndexAssigner::DoForwardFill() { +void LabelManagerImpl::SimpleIndexAssigner::DoForwardFill() { size_t count = 0; // Inside the loop, if |prev_index| == |kNoIndex| then we try to assign 0. // This allows 0 (if unused) to be assigned in middle of |labels_|. @@ -63,7 +67,7 @@ VLOG(1) << " fill forward " << count; } -void LabelManager::SimpleIndexAssigner::DoBackwardFill() { +void LabelManagerImpl::SimpleIndexAssigner::DoBackwardFill() { size_t count = 0; // This is asymmetric from DoForwardFill(), to preserve old behavior. // Inside the loop, if |prev_index| == |kNoIndex| then we skip assignment. @@ -85,7 +89,7 @@ VLOG(1) << " fill backward " << count; } -void LabelManager::SimpleIndexAssigner::DoInFill() { +void LabelManagerImpl::SimpleIndexAssigner::DoInFill() { size_t count = 0; int index = 0; for (Label& label : *labels_) { @@ -101,9 +105,9 @@ VLOG(1) << " infill " << count; } -LabelManager::LabelManager() {} +LabelManagerImpl::LabelManagerImpl() {} -LabelManager::~LabelManager() {} +LabelManagerImpl::~LabelManagerImpl() {} // We wish to minimize peak memory usage here. Analysis: Let // m = number of (RVA) elements in |rva_visitor|, @@ -115,7 +119,7 @@ // For our typical usage (i.e. Chrome) we see m = ~4n, so we use 16 * n bytes of // extra contiguous memory during computation. Assuming memory fragmentation // would not be an issue, this is much better than using std::map. -void LabelManager::Read(RvaVisitor* rva_visitor) { +void LabelManagerImpl::Read(RvaVisitor* rva_visitor) { // Write all values in |rva_visitor| to |rvas|. size_t num_rva = rva_visitor->Remaining(); std::vector<RVA> rvas(num_rva); @@ -139,7 +143,19 @@ } } -void LabelManager::RemoveUnderusedLabels(int32_t count_threshold) { +size_t LabelManagerImpl::Size() const { + return labels_.size(); +} + +// Uses binary search to find |rva|. +Label* LabelManagerImpl::Find(RVA rva) { + auto it = std::lower_bound( + labels_.begin(), labels_.end(), Label(rva), + [](const Label& l1, const Label& l2) { return l1.rva_ < l2.rva_; }); + return it == labels_.end() || it->rva_ != rva ? nullptr : &(*it); +} + +void LabelManagerImpl::RemoveUnderusedLabels(int32_t count_threshold) { if (count_threshold <= 0) return; labels_.erase(std::remove_if(labels_.begin(), labels_.end(), @@ -150,20 +166,12 @@ // Not shrinking |labels_|, since this may cause reallocation. } -// Uses binary search to find |rva|. -Label* LabelManager::Find(RVA rva) { - auto it = std::lower_bound( - labels_.begin(), labels_.end(), Label(rva), - [](const Label& l1, const Label& l2) { return l1.rva_ < l2.rva_; }); - return it == labels_.end() || it->rva_ != rva ? nullptr : &(*it); -} - -void LabelManager::UnassignIndexes() { +void LabelManagerImpl::UnassignIndexes() { for (Label& label : labels_) label.index_ = Label::kNoIndex; } -void LabelManager::DefaultAssignIndexes() { +void LabelManagerImpl::DefaultAssignIndexes() { int cur_index = 0; for (Label& label : labels_) { CHECK_EQ(Label::kNoIndex, label.index_); @@ -171,7 +179,7 @@ } } -void LabelManager::AssignRemainingIndexes() { +void LabelManagerImpl::AssignRemainingIndexes() { // This adds some memory overhead, about 1 bit per Label (more if indexes >= // |labels_.size()| get used). SimpleIndexAssigner assigner(&labels_); @@ -180,4 +188,8 @@ assigner.DoInFill(); } +void LabelManagerImpl::SetLabels(const LabelVector& labels) { + labels_ = labels; +} + } // namespace courgette
diff --git a/courgette/label_manager.h b/courgette/label_manager.h index 1b88024..3034ebf 100644 --- a/courgette/label_manager.h +++ b/courgette/label_manager.h
@@ -10,6 +10,7 @@ #include <vector> +#include "base/gtest_prod_util.h" #include "base/macros.h" #include "courgette/image_utils.h" @@ -17,11 +18,43 @@ using LabelVector = std::vector<Label>; -// A container to store and manage Label instances. A key consideration is peak -// memory usage reduction. To this end we preallocate Label instances in bulk, -// and carefully control transient memory usage when initializing Labels. +// A container to store and manage Label instances. class LabelManager { public: + virtual ~LabelManager(); + + // Returns the number of Label instances stored. + virtual size_t Size() const = 0; + + // Efficiently searches for a Label that targets |rva|. Returns the pointer to + // the stored Label instance if found, or null otherwise. Non-const to support + // implementations that allocate-on-read. + virtual Label* Find(RVA rva) = 0; + + // Removes Label instances whose |count_| is less than |count_threshold|. + virtual void RemoveUnderusedLabels(int32_t count_threshold) = 0; + + // Resets all indexes to an unassigned state. + virtual void UnassignIndexes() = 0; + + // Assigns indexes to successive integers from 0, ordered by RVA. + virtual void DefaultAssignIndexes() = 0; + + // Assigns indexes to any Label instances that don't have one yet. + virtual void AssignRemainingIndexes() = 0; + + protected: + LabelManager(); + + private: + DISALLOW_COPY_AND_ASSIGN(LabelManager); +}; + +// An implementation of LabelManager dedicated to reducing peak memory usage. +// To this end we preallocate Label instances in bulk, and carefully control +// transient memory usage when initializing Labels. +class LabelManagerImpl : public LabelManager { + public: // An adaptor to sequentially traverse multiple RVAs. This is useful for RVA // translation without extra storage. For example, we might have a stored list // of RVA locations, but we want to traverse the matching RVA targets. @@ -91,36 +124,37 @@ DISALLOW_COPY_AND_ASSIGN(SimpleIndexAssigner); }; - LabelManager(); - virtual ~LabelManager(); + LabelManagerImpl(); + ~LabelManagerImpl() override; - // Initializes |labels_| using RVAs from |rva_visitor|. Each distinct RVA from + // LabelManager interfaces. + size_t Size() const override; + Label* Find(RVA rva) override; + void RemoveUnderusedLabels(int32_t count_threshold) override; + void UnassignIndexes() override; + void DefaultAssignIndexes() override; + void AssignRemainingIndexes() override; + + // Populates |labels_| using RVAs from |rva_visitor|. Each distinct RVA from // |rva_visitor| yields a Label with |rva_| assigned as the RVA, and |count_| // assigned as the repeat. void Read(RvaVisitor* rva_visitor); - // Removes |labels_| elements whose |count_| is less than |count_threshold|. - void RemoveUnderusedLabels(int32_t count_threshold); - - // Efficiently searches for a Label that targets |rva|. Returns the pointer to - // the stored Label instance if found, or null otherwise. - Label* Find(RVA rva); - - // Resets all indexes to an unassigend state. - void UnassignIndexes(); - - // Assigns indexes to successive integers from 0, ordered by RVA. - void DefaultAssignIndexes(); - - // Assigns indexes to any Label elements that don't have one yet. - void AssignRemainingIndexes(); - protected: // The main list of Label instances, sorted by the |rva_| member. LabelVector labels_; private: - DISALLOW_COPY_AND_ASSIGN(LabelManager); + FRIEND_TEST_ALL_PREFIXES(LabelManagerTest, TrivialAssign); + FRIEND_TEST_ALL_PREFIXES(LabelManagerTest, AssignRemainingIndexes); + + // Accessor to stored Label instances. For testing only. + const LabelVector& Labels() const { return labels_; } + + // Directly assign |labels_|. For testing only. + void SetLabels(const LabelVector& labels); + + DISALLOW_COPY_AND_ASSIGN(LabelManagerImpl); }; } // namespace courgette
diff --git a/courgette/label_manager_unittest.cc b/courgette/label_manager_unittest.cc index cc112a85..b66f5630 100644 --- a/courgette/label_manager_unittest.cc +++ b/courgette/label_manager_unittest.cc
@@ -23,7 +23,7 @@ namespace { // Test version of RvaVisitor: Just wrap std::vector<RVA>. -class TestRvaVisitor : public LabelManager::RvaVisitor { +class TestRvaVisitor : public LabelManagerImpl::RvaVisitor { public: explicit TestRvaVisitor(std::vector<RVA>::const_iterator rva_begin, std::vector<RVA>::const_iterator rva_end) @@ -42,20 +42,9 @@ std::vector<RVA>::const_iterator rva_end_; }; -// Test version of LabelManager: Expose data to test implementation. -class TestLabelManager : public LabelManager { - public: - TestLabelManager() {} - - // Using move semantics to optimize injection of test LabelVector. - explicit TestLabelManager(LabelVector&& labels) { labels_ = labels; } - - const LabelVector& Labels() const { return labels_; } -}; - -void CheckLabelManagerContent(TestLabelManager* label_manager, +void CheckLabelManagerContent(LabelManager* label_manager, const std::map<RVA, int32_t>& expected) { - EXPECT_EQ(expected.size(), label_manager->Labels().size()); + EXPECT_EQ(expected.size(), label_manager->Size()); for (const auto& rva_and_count : expected) { Label* label = label_manager->Find(rva_and_count.first); EXPECT_TRUE(label != nullptr); @@ -64,7 +53,7 @@ } } -// Instantiates a LabelVector with |n| elements. The |rva_| fields are assigned +// Instantiates a LabelVector with |n| instances. The |rva_| fields are assigned // 0, ..., |n| - 1. The other fields are uninitialized. LabelVector CreateLabelVectorBasic(size_t n) { LabelVector labels; @@ -106,7 +95,7 @@ return labels; } -// Returns a string encoding for |index_| assignments for |label_| elements, +// Returns a string encoding for |index_| assignments for |label_| instances, // with kNoIndex => '.', 0 => 'A', ..., '25' => 'Z'. Fails if any |index_| // does not fit the above. std::string EncodeLabelIndexes(const LabelVector& labels) { @@ -143,7 +132,7 @@ TestRvaVisitor visitor(test_targets.begin(), test_targets.end()); // Preallocate targets, then populate. - TestLabelManager label_manager; + LabelManagerImpl label_manager; label_manager.Read(&visitor); static const std::pair<RVA, int32_t> kExpected1Raw[] = { @@ -177,9 +166,9 @@ // Test data: |dup| copies of kRva. std::vector<RVA> test_targets(dup, kRva); TestRvaVisitor visitor(test_targets.begin(), test_targets.end()); - TestLabelManager label_manager; + LabelManagerImpl label_manager; label_manager.Read(&visitor); - EXPECT_EQ(1U, label_manager.Labels().size()); // Deduped to 1 Label. + EXPECT_EQ(1U, label_manager.Size()); // Deduped to 1 Label. Label* label = label_manager.Find(kRva); EXPECT_NE(nullptr, label); @@ -196,15 +185,15 @@ TEST(LabelManagerTest, Empty) { std::vector<RVA> empty_test_targets; TestRvaVisitor visitor(empty_test_targets.begin(), empty_test_targets.end()); - TestLabelManager label_manager; + LabelManagerImpl label_manager; label_manager.Read(&visitor); - EXPECT_EQ(0U, label_manager.Labels().size()); + EXPECT_EQ(0U, label_manager.Size()); for (RVA rva = 0U; rva < 16U; ++rva) EXPECT_EQ(nullptr, label_manager.Find(rva)); } TEST(LabelManagerTest, EmptyAssign) { - TestLabelManager label_manager_empty; + LabelManagerImpl label_manager_empty; label_manager_empty.DefaultAssignIndexes(); label_manager_empty.UnassignIndexes(); label_manager_empty.AssignRemainingIndexes(); @@ -212,7 +201,9 @@ TEST(LabelManagerTest, TrivialAssign) { for (size_t size = 0; size < 20; ++size) { - TestLabelManager label_manager(CreateLabelVectorBasic(size)); + LabelManagerImpl label_manager; + label_manager.SetLabels(CreateLabelVectorBasic(size)); + // Sanity check. for (size_t i = 0; i < size; ++i) EXPECT_EQ(Label::kNoIndex, label_manager.Labels()[i].index_); @@ -236,7 +227,7 @@ // Tests SimpleIndexAssigner fill strategies independently. TEST(LabelManagerTest, SimpleIndexAssigner) { - using SimpleIndexAssigner = LabelManager::SimpleIndexAssigner; + using SimpleIndexAssigner = LabelManagerImpl::SimpleIndexAssigner; // See CreateLabelVectorWithIndexes() explanation on how we encode LabelVector // |index_| values as a string. const struct TestCase { @@ -353,8 +344,9 @@ {"..FE..GD..", "ABFECHGDIJ"}, // Forward: "AB"; backward: "IJ"; in: "CH". }; for (const auto& test_case : kTestCases) { - TestLabelManager label_manager( - CreateLabelVectorWithIndexes(test_case.input)); + LabelManagerImpl label_manager; + label_manager.SetLabels(CreateLabelVectorWithIndexes(test_case.input)); + label_manager.AssignRemainingIndexes(); std::string result = EncodeLabelIndexes(label_manager.Labels()); EXPECT_EQ(test_case.expect, result);
diff --git a/device/BUILD.gn b/device/BUILD.gn index 0a4b688..0f439a6a 100644 --- a/device/BUILD.gn +++ b/device/BUILD.gn
@@ -170,10 +170,6 @@ deps += [ "//dbus" ] } - if (is_posix && !is_android && !is_mac) { - libs = [ "rt" ] - } - if (is_mac) { deps += [ "//third_party/ocmock" ] ldflags = [ "-ObjC" ]
diff --git a/gpu/khronos_glcts_support/BUILD.gn b/gpu/khronos_glcts_support/BUILD.gn index 2868134..dfd5253 100644 --- a/gpu/khronos_glcts_support/BUILD.gn +++ b/gpu/khronos_glcts_support/BUILD.gn
@@ -138,8 +138,6 @@ ":dethread", ] - libs = [ "rt" ] - configs += [ ":defaults_config" ] configs -= [ "//build/config/compiler:chromium_code" ] configs += [ "//build/config/compiler:no_chromium_code" ]
diff --git a/ios/chrome/app/resources/ios_resources.grd b/ios/chrome/app/resources/ios_resources.grd index b754efc..71c071a 100644 --- a/ios/chrome/app/resources/ios_resources.grd +++ b/ios/chrome/app/resources/ios_resources.grd
@@ -13,5 +13,9 @@ SAME CONDITIONALS. --> <structure name="IDR_IOS_INCOGNITO_TAB_HTML" file="ntp/incognito_tab.html" flattenhtml="true" type="chrome_html" /> </structures> + <includes> + <include name="IDR_IOS_OMAHA_HTML" file="omaha/omaha.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> + <include name="IDR_IOS_OMAHA_JS" file="omaha/omaha.js" type="BINDATA" /> + </includes> </release> </grit>
diff --git a/ios/chrome/app/resources/omaha/omaha.css b/ios/chrome/app/resources/omaha/omaha.css new file mode 100644 index 0000000..677b5f4 --- /dev/null +++ b/ios/chrome/app/resources/omaha/omaha.css
@@ -0,0 +1,49 @@ +/* Copyright (c) 2012 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. */ + +body { + background-color: white; + color: black; + font-family: Helvetica,Arial,sans-serif; + margin: 0; +} + +tr { + display: none; +} + +#outer { + margin-left: auto; + margin-right: auto; + margin-top: 10px; + width: 800px; +} + +#inner { + padding-top: 10px; + width: 550px; +} + +.label { + -webkit-padding-end: 5px; + font-size: 0.9em; + font-weight: bold; + text-align: end; + vertical-align: top; + white-space: nowrap; +} + +.label:after { + content: ':'; +} + +#message { + font-family: monospace; +} + +.value { + font-family: monospace; + max-width: 430px; + padding-left: 5px; +}
diff --git a/ios/chrome/app/resources/omaha/omaha.html b/ios/chrome/app/resources/omaha/omaha.html new file mode 100644 index 0000000..3f30fdf --- /dev/null +++ b/ios/chrome/app/resources/omaha/omaha.html
@@ -0,0 +1,58 @@ +<!DOCTYPE HTML> +<html i18n-values="dir:textdirection;"> +<head> + <meta name="viewport" + content="width=device-width, initial-scale=1, maximum-scale=1"/> + <meta charset="utf-8"/> + <title>Omaha</title> + <link rel="stylesheet" href="omaha.css"> + <script src="chrome://resources/js/ios/web_ui.js"></script> + <script src="chrome://resources/js/load_time_data.js"></script> + <script src="chrome://resources/js/util.js"></script> + <script src="chrome://omaha/omaha.js"></script> + <script src="chrome://omaha/strings.js"></script> +</head> +<body i18n-values=".style.fontFamily:fontfamily;.style.fontSize:fontsize"> + <div id="outer"> + <table id="inner" cellpadding="0" cellspacing="0" border="0"> + <tr id="last_sent_time-tr"> + <td class="label">Last Sent Time</td> + <td class="value" id="last_sent_time"></td> + </tr> + <tr id="next_tries_time-tr"> + <td class="label">Next Tried Time</td> + <td class="value" id="next_tries_time"></td> + </tr> + <tr id="current_ping_time-tr"> + <td class="label">Current Ping Time</td> + <td class="value" id="current_ping_time"></td> + </tr> + <tr id="last_sent_version-tr"> + <td class="label">Last Sent Version</td> + <td class="value" id="last_sent_version"></td> + </tr> + <tr id="number_of_tries-tr"> + <td class="label">Number of Tries</td> + <td class="value" id="number_of_tries"></td> + </tr> + <tr id="timer_running-tr"> + <td class="label">Timer Running</td> + <td class="value" id="timer_running"></td> + </tr> + <tr id="timer_current_delay-tr"> + <td class="label">Timer Current Delay</td> + <td class="value" id="timer_current_delay"></td> + </tr> + <tr id="timer_desired_run_time-tr"> + <td class="label">Timer Desired Run Time</td> + <td class="value" id="timer_desired_run_time"></td> + </tr> + <tr id="message-tr"> + <td class="label">Message</td> + <td class="value" id="message"></td> + </tr> + </table> + </div> + <script src="chrome://resources/js/i18n_template.js"></script> +</body> +</html>
diff --git a/ios/chrome/app/resources/omaha/omaha.js b/ios/chrome/app/resources/omaha/omaha.js new file mode 100644 index 0000000..f950ea6 --- /dev/null +++ b/ios/chrome/app/resources/omaha/omaha.js
@@ -0,0 +1,33 @@ +// Copyright 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * Requests the debug information from the backend. + */ +function requestOmahaDebugInformation() { + chrome.send('requestOmahaDebugInformation'); +} + +/** + * Update the visibility state of the given element. Using the hidden attribute + * is not supported on iOS 4.3. + * @param {Element} element The element to update. + * @param {boolean} visible The new visibility state. + */ +function setVisible(element, visible) { + element.style.display = visible ? 'inline' : 'none'; +} + +/** + * Callback from backend with the debug informations. Construct the UI. + * @param {Object} information The debug information. + */ +function updateOmahaDebugInformation(information) { + for (key in information) { + $(key).textContent = information[key]; + setVisible($(key + '-tr'), true); + } +} + +document.addEventListener('DOMContentLoaded', requestOmahaDebugInformation);
diff --git a/ios/chrome/app/strings/ios_chromium_strings.grd b/ios/chrome/app/strings/ios_chromium_strings.grd index c330157e..941c98de 100644 --- a/ios/chrome/app/strings/ios_chromium_strings.grd +++ b/ios/chrome/app/strings/ios_chromium_strings.grd
@@ -151,6 +151,9 @@ <message name="IDS_IOS_PASSWORD_MANAGER_SAVE_PASSWORD_PROMPT" desc="Info bar message to save a password. [Length: 60em]"> Do you want Chromium to save your password for this site? </message> + <message name="IDS_IOS_UPGRADE_AVAILABLE" desc="Text to inform the user of the presence of a new version of the application"> + Chromium just got better! A new version is available. + </message> </messages> </release> </grit>
diff --git a/ios/chrome/app/strings/ios_google_chrome_strings.grd b/ios/chrome/app/strings/ios_google_chrome_strings.grd index 756a6445..fe784b0 100644 --- a/ios/chrome/app/strings/ios_google_chrome_strings.grd +++ b/ios/chrome/app/strings/ios_google_chrome_strings.grd
@@ -151,6 +151,9 @@ <message name="IDS_IOS_PASSWORD_MANAGER_SAVE_PASSWORD_PROMPT" desc="Info bar message to save a password. [Length: 60em]"> Do you want Google Chrome to save your password for this site? </message> + <message name="IDS_IOS_UPGRADE_AVAILABLE" desc="Text to inform the user of the presence of a new version of the application"> + Chrome just got better! A new version is available. + </message> </messages> </release> </grit>
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index 56a8e8f..b7d6c0d 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -296,6 +296,9 @@ The site you are trying to access is acting strangely, and Chrome is unable to verify that its URL is correct. For security reasons, you should not proceed, and perhaps try again tomorrow or go somewhere else. </message> + <message name="IDS_IOS_UPGRADE_AVAILABLE_BUTTON" desc="Displayed on a button the user can use to upgrade the a more recent version of the application. [Length: 10em]"> + Update + </message> </messages> </release> </grit>
diff --git a/ios/chrome/browser/DEPS b/ios/chrome/browser/DEPS index 9ca7243..e695693 100644 --- a/ios/chrome/browser/DEPS +++ b/ios/chrome/browser/DEPS
@@ -47,7 +47,6 @@ "+components/proxy_config", "+components/rappor", "+components/rlz", - "+components/safe_browsing_db", "+components/search", "+components/search_engines", "+components/security_interstitials", @@ -71,6 +70,7 @@ "+components/web_resource", "+components/webdata_services", "+components/webp_transcode", + "+crypto", "+google_apis", "+ios/chrome/common", "+ios/net",
diff --git a/ios/chrome/browser/about_flags.mm b/ios/chrome/browser/about_flags.mm index cd4827fb..c1586d2 100644 --- a/ios/chrome/browser/about_flags.mm +++ b/ios/chrome/browser/about_flags.mm
@@ -195,10 +195,6 @@ } } - // Populate command line flags from DisableKeyboardCommands. - if ([defaults boolForKey:@"DisableKeyboardCommands"]) - command_line->AppendSwitch(switches::kDisableKeyboardCommands); - // TODO(crbug.com/450311): Remove this compile-time flag once bots are passing // the compile-time flag. #if defined(FORCE_ENABLE_WKWEBVIEW)
diff --git a/ios/chrome/browser/chrome_switches.cc b/ios/chrome/browser/chrome_switches.cc index dc15ee3..2a23c651 100644 --- a/ios/chrome/browser/chrome_switches.cc +++ b/ios/chrome/browser/chrome_switches.cc
@@ -37,9 +37,6 @@ // Disables the use of WKWebView instead of UIWebView. const char kDisableIOSWKWebView[] = "disable-wkwebview"; -// Disables support for keyboard commands. -const char kDisableKeyboardCommands[] = "disable-keyboard-commands"; - // Disable the snapshots lru cache. const char kDisableLRUSnapshotCache[] = "disable-lru-snapshot-cache";
diff --git a/ios/chrome/browser/chrome_switches.h b/ios/chrome/browser/chrome_switches.h index 08da4c0..e2acb17 100644 --- a/ios/chrome/browser/chrome_switches.h +++ b/ios/chrome/browser/chrome_switches.h
@@ -16,7 +16,6 @@ extern const char kDisableIOSPasswordSuggestions[]; extern const char kDisableIOSWebResources[]; extern const char kDisableIOSWKWebView[]; -extern const char kDisableKeyboardCommands[]; extern const char kDisableLRUSnapshotCache[]; extern const char kDisableNTPFavicons[]; extern const char kDisableOfflineAutoReload[];
diff --git a/ios/chrome/browser/experimental_flags.h b/ios/chrome/browser/experimental_flags.h index 5bfa8214..dd95a16 100644 --- a/ios/chrome/browser/experimental_flags.h +++ b/ios/chrome/browser/experimental_flags.h
@@ -44,9 +44,6 @@ // omnibox search requests. The returned value contains a leading "&". std::string GetWKWebViewSearchParams(); -// Whether keyboard commands are supported. -bool AreKeyboardCommandsEnabled(); - // Whether viewing and copying passwords is enabled. bool IsViewCopyPasswordsEnabled();
diff --git a/ios/chrome/browser/experimental_flags.mm b/ios/chrome/browser/experimental_flags.mm index aeb717d..a84c2b5b 100644 --- a/ios/chrome/browser/experimental_flags.mm +++ b/ios/chrome/browser/experimental_flags.mm
@@ -192,11 +192,6 @@ return variations::GetVariationParamValue(kWKWebViewTrialName, "esrch"); } -bool AreKeyboardCommandsEnabled() { - return !base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableKeyboardCommands); -} - bool IsViewCopyPasswordsEnabled() { NSString* viewCopyPasswordFlag = [[NSUserDefaults standardUserDefaults] objectForKey:kEnableViewCopyPasswords];
diff --git a/ios/chrome/browser/safe_browsing/hit_report.h b/ios/chrome/browser/safe_browsing/hit_report.h index 34aa362..1b11ba3 100644 --- a/ios/chrome/browser/safe_browsing/hit_report.h +++ b/ios/chrome/browser/safe_browsing/hit_report.h
@@ -7,7 +7,7 @@ #ifndef IOS_CHROME_BROWSER_SAFE_BROWSING_HIT_REPORT_H_ #define IOS_CHROME_BROWSER_SAFE_BROWSING_HIT_REPORT_H_ -#include "components/safe_browsing_db/util.h" +#include "ios/chrome/browser/safe_browsing/util.h" #include "url/gurl.h" namespace safe_browsing {
diff --git a/ios/chrome/browser/safe_browsing/ping_manager.h b/ios/chrome/browser/safe_browsing/ping_manager.h index be84b4e..5e0a121 100644 --- a/ios/chrome/browser/safe_browsing/ping_manager.h +++ b/ios/chrome/browser/safe_browsing/ping_manager.h
@@ -14,9 +14,9 @@ #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/memory/scoped_ptr.h" -#include "components/safe_browsing_db/util.h" #include "ios/chrome/browser/safe_browsing/hit_report.h" #include "ios/chrome/browser/safe_browsing/protocol_manager_helper.h" +#include "ios/chrome/browser/safe_browsing/util.h" #include "net/url_request/url_fetcher_delegate.h" #include "url/gurl.h"
diff --git a/ios/chrome/browser/safe_browsing/safe_browsing_service.h b/ios/chrome/browser/safe_browsing/safe_browsing_service.h index 78e62c1..8bb9967 100644 --- a/ios/chrome/browser/safe_browsing/safe_browsing_service.h +++ b/ios/chrome/browser/safe_browsing/safe_browsing_service.h
@@ -19,7 +19,7 @@ #include "base/memory/scoped_ptr.h" #include "base/observer_list.h" #include "base/sequenced_task_runner_helpers.h" -#include "components/safe_browsing_db/util.h" +#include "ios/chrome/browser/safe_browsing/util.h" #include "ios/web/public/web_thread.h" class PrefChangeRegistrar;
diff --git a/ios/chrome/browser/safe_browsing/ui_manager.h b/ios/chrome/browser/safe_browsing/ui_manager.h index 8d1eb51..1111614 100644 --- a/ios/chrome/browser/safe_browsing/ui_manager.h +++ b/ios/chrome/browser/safe_browsing/ui_manager.h
@@ -18,8 +18,8 @@ #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/time/time.h" -#include "components/safe_browsing_db/util.h" #include "ios/chrome/browser/safe_browsing/hit_report.h" +#include "ios/chrome/browser/safe_browsing/util.h" #include "url/gurl.h" namespace base {
diff --git a/ios/chrome/browser/safe_browsing/util.cc b/ios/chrome/browser/safe_browsing/util.cc new file mode 100644 index 0000000..afc1cf5 --- /dev/null +++ b/ios/chrome/browser/safe_browsing/util.cc
@@ -0,0 +1,394 @@ +// Copyright 2016 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 "ios/chrome/browser/safe_browsing/util.h" + +#include <stddef.h> + +#include "base/macros.h" +#include "base/strings/string_util.h" +#include "crypto/sha2.h" +#include "net/base/escape.h" +#include "url/gurl.h" +#include "url/url_util.h" + +namespace safe_browsing { + +// Utility functions ----------------------------------------------------------- + +namespace { +bool IsKnownList(const std::string& name) { + for (size_t i = 0; i < arraysize(kAllLists); ++i) { + if (!strcmp(kAllLists[i], name.c_str())) { + return true; + } + } + return false; +} +} // namespace + +// SBCachedFullHashResult ------------------------------------------------------ + +SBCachedFullHashResult::SBCachedFullHashResult() {} + +SBCachedFullHashResult::SBCachedFullHashResult( + const base::Time& in_expire_after) + : expire_after(in_expire_after) {} + +SBCachedFullHashResult::~SBCachedFullHashResult() {} + +// Listnames that browser can process. +const char kMalwareList[] = "goog-malware-shavar"; +const char kPhishingList[] = "goog-phish-shavar"; +const char kBinUrlList[] = "goog-badbinurl-shavar"; +const char kCsdWhiteList[] = "goog-csdwhite-sha256"; +const char kDownloadWhiteList[] = "goog-downloadwhite-digest256"; +const char kExtensionBlacklist[] = "goog-badcrxids-digestvar"; +const char kIPBlacklist[] = "goog-badip-digest256"; +const char kUnwantedUrlList[] = "goog-unwanted-shavar"; +const char kInclusionWhitelist[] = "goog-csdinclusionwhite-sha256"; + +const char* kAllLists[9] = { + kMalwareList, kPhishingList, kBinUrlList, + kCsdWhiteList, kDownloadWhiteList, kExtensionBlacklist, + kIPBlacklist, kUnwantedUrlList, kInclusionWhitelist, +}; + +ListType GetListId(const base::StringPiece& name) { + ListType id; + if (name == kMalwareList) { + id = MALWARE; + } else if (name == kPhishingList) { + id = PHISH; + } else if (name == kBinUrlList) { + id = BINURL; + } else if (name == kCsdWhiteList) { + id = CSDWHITELIST; + } else if (name == kDownloadWhiteList) { + id = DOWNLOADWHITELIST; + } else if (name == kExtensionBlacklist) { + id = EXTENSIONBLACKLIST; + } else if (name == kIPBlacklist) { + id = IPBLACKLIST; + } else if (name == kUnwantedUrlList) { + id = UNWANTEDURL; + } else if (name == kInclusionWhitelist) { + id = INCLUSIONWHITELIST; + } else { + id = INVALID; + } + return id; +} + +bool GetListName(ListType list_id, std::string* list) { + switch (list_id) { + case MALWARE: + *list = kMalwareList; + break; + case PHISH: + *list = kPhishingList; + break; + case BINURL: + *list = kBinUrlList; + break; + case CSDWHITELIST: + *list = kCsdWhiteList; + break; + case DOWNLOADWHITELIST: + *list = kDownloadWhiteList; + break; + case EXTENSIONBLACKLIST: + *list = kExtensionBlacklist; + break; + case IPBLACKLIST: + *list = kIPBlacklist; + break; + case UNWANTEDURL: + *list = kUnwantedUrlList; + break; + case INCLUSIONWHITELIST: + *list = kInclusionWhitelist; + break; + default: + return false; + } + DCHECK(IsKnownList(*list)); + return true; +} + +SBFullHash SBFullHashForString(const base::StringPiece& str) { + SBFullHash h; + crypto::SHA256HashString(str, &h.full_hash, sizeof(h.full_hash)); + return h; +} + +SBFullHash StringToSBFullHash(const std::string& hash_in) { + DCHECK_EQ(crypto::kSHA256Length, hash_in.size()); + SBFullHash hash_out; + memcpy(hash_out.full_hash, hash_in.data(), crypto::kSHA256Length); + return hash_out; +} + +std::string SBFullHashToString(const SBFullHash& hash) { + DCHECK_EQ(crypto::kSHA256Length, sizeof(hash.full_hash)); + return std::string(hash.full_hash, sizeof(hash.full_hash)); +} + +std::string Unescape(const std::string& url) { + std::string unescaped_str(url); + const int kMaxLoopIterations = 1024; + size_t old_size = 0; + int loop_var = 0; + do { + old_size = unescaped_str.size(); + unescaped_str = net::UnescapeURLComponent( + unescaped_str, net::UnescapeRule::SPOOFING_AND_CONTROL_CHARS | + net::UnescapeRule::SPACES | + net::UnescapeRule::URL_SPECIAL_CHARS); + } while (old_size != unescaped_str.size() && + ++loop_var <= kMaxLoopIterations); + + return unescaped_str; +} + +std::string Escape(const std::string& url) { + std::string escaped_str; + // The escaped string is larger so allocate double the length to reduce the + // chance of the string being grown. + escaped_str.reserve(url.length() * 2); + const char* kHexString = "0123456789ABCDEF"; + for (size_t i = 0; i < url.length(); i++) { + unsigned char c = static_cast<unsigned char>(url[i]); + if (c <= ' ' || c > '~' || c == '#' || c == '%') { + escaped_str += '%'; + escaped_str += kHexString[c >> 4]; + escaped_str += kHexString[c & 0xf]; + } else { + escaped_str += c; + } + } + + return escaped_str; +} + +std::string RemoveConsecutiveChars(base::StringPiece str, const char c) { + std::string output; + // Output is at most the length of the original string. + output.reserve(str.size()); + + size_t i = 0; + while (i < str.size()) { + output.append(1, str[i++]); + if (str[i - 1] == c) { + while (i < str.size() && str[i] == c) { + i++; + } + } + } + + return output; +} + +// Canonicalizes url as per Google Safe Browsing Specification. +// See section 6.1 in +// http://code.google.com/p/google-safe-browsing/wiki/Protocolv2Spec. +void CanonicalizeUrl(const GURL& url, + std::string* canonicalized_hostname, + std::string* canonicalized_path, + std::string* canonicalized_query) { + DCHECK(url.is_valid()); + + // We only canonicalize "normal" URLs. + if (!url.IsStandard()) + return; + + // Following canonicalization steps are excluded since url parsing takes care + // of those :- + // 1. Remove any tab (0x09), CR (0x0d), and LF (0x0a) chars from url. + // (Exclude escaped version of these chars). + // 2. Normalize hostname to 4 dot-seperated decimal values. + // 3. Lowercase hostname. + // 4. Resolve path sequences "/../" and "/./". + + // That leaves us with the following :- + // 1. Remove fragment in URL. + GURL url_without_fragment; + GURL::Replacements f_replacements; + f_replacements.ClearRef(); + f_replacements.ClearUsername(); + f_replacements.ClearPassword(); + url_without_fragment = url.ReplaceComponents(f_replacements); + + // 2. Do URL unescaping until no more hex encoded characters exist. + std::string url_unescaped_str(Unescape(url_without_fragment.spec())); + url::Parsed parsed; + url::ParseStandardURL(url_unescaped_str.data(), url_unescaped_str.length(), + &parsed); + + // 3. In hostname, remove all leading and trailing dots. + base::StringPiece host; + if (parsed.host.len > 0) + host.set(url_unescaped_str.data() + parsed.host.begin, parsed.host.len); + + base::StringPiece host_without_end_dots = + base::TrimString(host, ".", base::TrimPositions::TRIM_ALL); + + // 4. In hostname, replace consecutive dots with a single dot. + std::string host_without_consecutive_dots( + RemoveConsecutiveChars(host_without_end_dots, '.')); + + // 5. In path, replace runs of consecutive slashes with a single slash. + base::StringPiece path; + if (parsed.path.len > 0) + path.set(url_unescaped_str.data() + parsed.path.begin, parsed.path.len); + std::string path_without_consecutive_slash(RemoveConsecutiveChars(path, '/')); + + url::Replacements<char> hp_replacements; + hp_replacements.SetHost( + host_without_consecutive_dots.data(), + url::Component(0, host_without_consecutive_dots.length())); + hp_replacements.SetPath( + path_without_consecutive_slash.data(), + url::Component(0, path_without_consecutive_slash.length())); + + std::string url_unescaped_with_can_hostpath; + url::StdStringCanonOutput output(&url_unescaped_with_can_hostpath); + url::Parsed temp_parsed; + url::ReplaceComponents(url_unescaped_str.data(), url_unescaped_str.length(), + parsed, hp_replacements, NULL, &output, &temp_parsed); + output.Complete(); + + // 6. Step needed to revert escaping done in url::ReplaceComponents. + url_unescaped_with_can_hostpath = Unescape(url_unescaped_with_can_hostpath); + + // 7. After performing all above steps, percent-escape all chars in url which + // are <= ASCII 32, >= 127, #, %. Escapes must be uppercase hex characters. + std::string escaped_canon_url_str(Escape(url_unescaped_with_can_hostpath)); + url::Parsed final_parsed; + url::ParseStandardURL(escaped_canon_url_str.data(), + escaped_canon_url_str.length(), &final_parsed); + + if (canonicalized_hostname && final_parsed.host.len > 0) { + *canonicalized_hostname = escaped_canon_url_str.substr( + final_parsed.host.begin, final_parsed.host.len); + } + if (canonicalized_path && final_parsed.path.len > 0) { + *canonicalized_path = escaped_canon_url_str.substr(final_parsed.path.begin, + final_parsed.path.len); + } + if (canonicalized_query && final_parsed.query.len > 0) { + *canonicalized_query = escaped_canon_url_str.substr( + final_parsed.query.begin, final_parsed.query.len); + } +} + +void UrlToFullHashes(const GURL& url, + bool include_whitelist_hashes, + std::vector<SBFullHash>* full_hashes) { + std::vector<std::string> hosts; + if (url.HostIsIPAddress()) { + hosts.push_back(url.host()); + } else { + GenerateHostsToCheck(url, &hosts); + } + + std::vector<std::string> paths; + GeneratePathsToCheck(url, &paths); + + for (const std::string& host : hosts) { + for (const std::string& path : paths) { + full_hashes->push_back(SBFullHashForString(host + path)); + + // We may have /foo as path-prefix in the whitelist which should + // also match with /foo/bar and /foo?bar. Hence, for every path + // that ends in '/' we also add the path without the slash. + if (include_whitelist_hashes && path.size() > 1 && + path[path.size() - 1] == '/') { + full_hashes->push_back( + SBFullHashForString(host + path.substr(0, path.size() - 1))); + } + } + } +} + +void GenerateHostsToCheck(const GURL& url, std::vector<std::string>* hosts) { + hosts->clear(); + + std::string canon_host; + CanonicalizeUrl(url, &canon_host, NULL, NULL); + + const std::string host = canon_host; // const sidesteps GCC bugs below! + if (host.empty()) + return; + + // Per the Safe Browsing Protocol v2 spec, we try the host, and also up to 4 + // hostnames formed by starting with the last 5 components and successively + // removing the leading component. The last component isn't examined alone, + // since it's the TLD or a subcomponent thereof. + // + // Note that we don't need to be clever about stopping at the "real" eTLD -- + // the data on the server side has been filtered to ensure it will not + // blacklist a whole TLD, and it's not significantly slower on our side to + // just check too much. + // + // Also note that because we have a simple blacklist, not some sort of complex + // whitelist-in-blacklist or vice versa, it doesn't matter what order we check + // these in. + const size_t kMaxHostsToCheck = 4; + bool skipped_last_component = false; + for (std::string::const_reverse_iterator i(host.rbegin()); + i != host.rend() && hosts->size() < kMaxHostsToCheck; ++i) { + if (*i == '.') { + if (skipped_last_component) + hosts->push_back(std::string(i.base(), host.end())); + else + skipped_last_component = true; + } + } + hosts->push_back(host); +} + +void GeneratePathsToCheck(const GURL& url, std::vector<std::string>* paths) { + paths->clear(); + + std::string canon_path; + std::string canon_query; + CanonicalizeUrl(url, NULL, &canon_path, &canon_query); + + const std::string path = canon_path; // const sidesteps GCC bugs below! + const std::string query = canon_query; + if (path.empty()) + return; + + // Per the Safe Browsing Protocol v2 spec, we try the exact path with/without + // the query parameters, and also up to 4 paths formed by starting at the root + // and adding more path components. + // + // As with the hosts above, it doesn't matter what order we check these in. + const size_t kMaxPathsToCheck = 4; + for (std::string::const_iterator i(path.begin()); + i != path.end() && paths->size() < kMaxPathsToCheck; ++i) { + if (*i == '/') + paths->push_back(std::string(path.begin(), i + 1)); + } + + if (!paths->empty() && paths->back() != path) + paths->push_back(path); + + if (!query.empty()) + paths->push_back(path + "?" + query); +} + +void GeneratePatternsToCheck(const GURL& url, std::vector<std::string>* urls) { + std::vector<std::string> hosts, paths; + GenerateHostsToCheck(url, &hosts); + GeneratePathsToCheck(url, &paths); + for (size_t h = 0; h < hosts.size(); ++h) { + for (size_t p = 0; p < paths.size(); ++p) { + urls->push_back(hosts[h] + paths[p]); + } + } +} + +} // namespace safe_browsing
diff --git a/ios/chrome/browser/safe_browsing/util.h b/ios/chrome/browser/safe_browsing/util.h new file mode 100644 index 0000000..50552f3 --- /dev/null +++ b/ios/chrome/browser/safe_browsing/util.h
@@ -0,0 +1,171 @@ +// Copyright 2016 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. +// +// Utilities for the SafeBrowsing DB code. + +#ifndef IOS_CHROME_BROWSER_SAFE_BROWSING_UTIL_H_ +#define IOS_CHROME_BROWSER_SAFE_BROWSING_UTIL_H_ + +#include <stdint.h> + +#include <cstring> +#include <string> +#include <vector> + +#include "base/strings/string_piece.h" +#include "base/time/time.h" + +class GURL; + +namespace safe_browsing { + +// Different types of threats that SafeBrowsing protects against. +enum SBThreatType { + // No threat at all. + SB_THREAT_TYPE_SAFE, + + // The URL is being used for phishing. + SB_THREAT_TYPE_URL_PHISHING, + + // The URL hosts malware. + SB_THREAT_TYPE_URL_MALWARE, + + // The URL hosts unwanted programs. + SB_THREAT_TYPE_URL_UNWANTED, + + // The download URL is malware. + SB_THREAT_TYPE_BINARY_MALWARE_URL, + + // Url detected by the client-side phishing model. Note that unlike the + // above values, this does not correspond to a downloaded list. + SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL, + + // The Chrome extension or app (given by its ID) is malware. + SB_THREAT_TYPE_EXTENSION, + + // Url detected by the client-side malware IP list. This IP list is part + // of the client side detection model. + SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL, +}; + +// A truncated hash's type. +typedef uint32_t SBPrefix; + +// A full hash. +union SBFullHash { + char full_hash[32]; + SBPrefix prefix; +}; + +// Used when we get a gethash response. +struct SBFullHashResult { + SBFullHash hash; + // TODO(shess): Refactor to allow ListType here. + int list_id; + std::string metadata; +}; + +// Caches individual response from GETHASH request. +struct SBCachedFullHashResult { + SBCachedFullHashResult(); + explicit SBCachedFullHashResult(const base::Time& in_expire_after); + ~SBCachedFullHashResult(); + + base::Time expire_after; + std::vector<SBFullHashResult> full_hashes; +}; + +// SafeBrowsing list names. +extern const char kMalwareList[]; +extern const char kPhishingList[]; +// Binary Download list name. +extern const char kBinUrlList[]; +// SafeBrowsing client-side detection whitelist list name. +extern const char kCsdWhiteList[]; +// SafeBrowsing download whitelist list name. +extern const char kDownloadWhiteList[]; +// SafeBrowsing extension list name. +extern const char kExtensionBlacklist[]; +// SafeBrowsing csd malware IP blacklist name. +extern const char kIPBlacklist[]; +// SafeBrowsing unwanted URL list. +extern const char kUnwantedUrlList[]; +// SafeBrowsing off-domain inclusion whitelist list name. +extern const char kInclusionWhitelist[]; +// This array must contain all Safe Browsing lists. +extern const char* kAllLists[9]; + +enum ListType { + INVALID = -1, + MALWARE = 0, + PHISH = 1, + BINURL = 2, + // Obsolete BINHASH = 3, + CSDWHITELIST = 4, + // SafeBrowsing lists are stored in pairs. Keep ListType 5 + // available for a potential second list that we would store in the + // csd-whitelist store file. + DOWNLOADWHITELIST = 6, + // See above comment. Leave 7 available. + EXTENSIONBLACKLIST = 8, + // See above comment. Leave 9 available. + // Obsolete SIDEEFFECTFREEWHITELIST = 10, + // See above comment. Leave 11 available. + IPBLACKLIST = 12, + // See above comment. Leave 13 available. + UNWANTEDURL = 14, + // See above comment. Leave 15 available. + INCLUSIONWHITELIST = 16, + // See above comment. Leave 17 available. +}; + +inline bool SBFullHashEqual(const SBFullHash& a, const SBFullHash& b) { + return !memcmp(a.full_hash, b.full_hash, sizeof(a.full_hash)); +} + +inline bool SBFullHashLess(const SBFullHash& a, const SBFullHash& b) { + return memcmp(a.full_hash, b.full_hash, sizeof(a.full_hash)) < 0; +} + +// Generate full hash for the given string. +SBFullHash SBFullHashForString(const base::StringPiece& str); +SBFullHash StringToSBFullHash(const std::string& hash_in); +std::string SBFullHashToString(const SBFullHash& hash_out); + +// Maps a list name to ListType. +ListType GetListId(const base::StringPiece& name); + +// Maps a ListId to list name. Return false if fails. +bool GetListName(ListType list_id, std::string* list); + +// Canonicalizes url as per Google Safe Browsing Specification. +// See section 6.1 in +// http://code.google.com/p/google-safe-browsing/wiki/Protocolv2Spec. +void CanonicalizeUrl(const GURL& url, + std::string* canonicalized_hostname, + std::string* canonicalized_path, + std::string* canonicalized_query); + +// Generate the set of full hashes to check for |url|. If +// |include_whitelist_hashes| is true we will generate additional path-prefixes +// to match against the csd whitelist. E.g., if the path-prefix /foo is on the +// whitelist it should also match /foo/bar which is not the case for all the +// other lists. We'll also always add a pattern for the empty path. +void UrlToFullHashes(const GURL& url, + bool include_whitelist_hashes, + std::vector<SBFullHash>* full_hashes); + +// Given a URL, returns all the hosts we need to check. They are returned +// in order of size (i.e. b.c is first, then a.b.c). +void GenerateHostsToCheck(const GURL& url, std::vector<std::string>* hosts); + +// Given a URL, returns all the paths we need to check. +void GeneratePathsToCheck(const GURL& url, std::vector<std::string>* paths); + +// Given a URL, returns all the patterns we need to check. +void GeneratePatternsToCheck(const GURL& url, std::vector<std::string>* urls); + +} // namespace safe_browsing + +#endif // IOS_CHROME_BROWSER_SAFE_BROWSING_UTIL_H_
diff --git a/ios/chrome/browser/safe_browsing/util_unittest.cc b/ios/chrome/browser/safe_browsing/util_unittest.cc new file mode 100644 index 0000000..01da998 --- /dev/null +++ b/ios/chrome/browser/safe_browsing/util_unittest.cc
@@ -0,0 +1,237 @@ +// Copyright 2016 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 <stddef.h> + +#include <algorithm> + +#include "base/macros.h" +#include "base/strings/stringprintf.h" +#include "ios/chrome/browser/safe_browsing/util.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace safe_browsing { + +namespace { + +bool VectorContains(const std::vector<std::string>& data, + const std::string& str) { + return std::find(data.begin(), data.end(), str) != data.end(); +} + +} // namespace + +// Tests that we generate the required host/path combinations for testing +// according to the Safe Browsing spec. +// See section 6.2 in +// http://code.google.com/p/google-safe-browsing/wiki/Protocolv2Spec. +TEST(SafeBrowsingDbUtilTest, UrlParsing) { + std::vector<std::string> hosts, paths; + + GURL url("http://a.b.c/1/2.html?param=1"); + GenerateHostsToCheck(url, &hosts); + GeneratePathsToCheck(url, &paths); + EXPECT_EQ(hosts.size(), static_cast<size_t>(2)); + EXPECT_EQ(paths.size(), static_cast<size_t>(4)); + EXPECT_EQ(hosts[0], "b.c"); + EXPECT_EQ(hosts[1], "a.b.c"); + + EXPECT_TRUE(VectorContains(paths, "/1/2.html?param=1")); + EXPECT_TRUE(VectorContains(paths, "/1/2.html")); + EXPECT_TRUE(VectorContains(paths, "/1/")); + EXPECT_TRUE(VectorContains(paths, "/")); + + url = GURL("http://a.b.c.d.e.f.g/1.html"); + GenerateHostsToCheck(url, &hosts); + GeneratePathsToCheck(url, &paths); + EXPECT_EQ(hosts.size(), static_cast<size_t>(5)); + EXPECT_EQ(paths.size(), static_cast<size_t>(2)); + EXPECT_EQ(hosts[0], "f.g"); + EXPECT_EQ(hosts[1], "e.f.g"); + EXPECT_EQ(hosts[2], "d.e.f.g"); + EXPECT_EQ(hosts[3], "c.d.e.f.g"); + EXPECT_EQ(hosts[4], "a.b.c.d.e.f.g"); + EXPECT_TRUE(VectorContains(paths, "/1.html")); + EXPECT_TRUE(VectorContains(paths, "/")); + + url = GURL("http://a.b/saw-cgi/eBayISAPI.dll/"); + GeneratePathsToCheck(url, &paths); + EXPECT_EQ(paths.size(), static_cast<size_t>(3)); + EXPECT_TRUE(VectorContains(paths, "/saw-cgi/eBayISAPI.dll/")); + EXPECT_TRUE(VectorContains(paths, "/saw-cgi/")); + EXPECT_TRUE(VectorContains(paths, "/")); +} + +// Tests the url canonicalization according to the Safe Browsing spec. +// See section 6.1 in +// http://code.google.com/p/google-safe-browsing/wiki/Protocolv2Spec. +TEST(SafeBrowsingDbUtilTest, CanonicalizeUrl) { + struct { + const char* input_url; + const char* expected_canonicalized_hostname; + const char* expected_canonicalized_path; + const char* expected_canonicalized_query; + } tests[] = { + {"http://host/%25%32%35", "host", "/%25", ""}, + {"http://host/%25%32%35%25%32%35", "host", "/%25%25", ""}, + {"http://host/%2525252525252525", "host", "/%25", ""}, + {"http://host/asdf%25%32%35asd", "host", "/asdf%25asd", ""}, + {"http://host/%%%25%32%35asd%%", "host", "/%25%25%25asd%25%25", ""}, + {"http://host/%%%25%32%35asd%%", "host", "/%25%25%25asd%25%25", ""}, + {"http://www.google.com/", "www.google.com", "/", ""}, + {"http://%31%36%38%2e%31%38%38%2e%39%39%2e%32%36/%2E%73%65%63%75%72%65/" + "%77" + "%77%77%2E%65%62%61%79%2E%63%6F%6D/", + "168.188.99.26", "/.secure/www.ebay.com/", ""}, + {"http://195.127.0.11/uploads/%20%20%20%20/.verify/" + ".eBaysecure=updateuserd" + "ataxplimnbqmn-xplmvalidateinfoswqpcmlx=hgplmcx/", + "195.127.0.11", + "/uploads/%20%20%20%20/.verify/" + ".eBaysecure=updateuserdataxplimnbqmn-xplmv" + "alidateinfoswqpcmlx=hgplmcx/", + ""}, + {"http://host.com/%257Ea%2521b%2540c%2523d%2524e%25f%255E00%252611%252A" + "22%252833%252944_55%252B", + "host.com", "/~a!b@c%23d$e%25f^00&11*22(33)44_55+", ""}, + {"http://3279880203/blah", "195.127.0.11", "/blah", ""}, + {"http://www.google.com/blah/..", "www.google.com", "/", ""}, + {"http://www.google.com/blah#fraq", "www.google.com", "/blah", ""}, + {"http://www.GOOgle.com/", "www.google.com", "/", ""}, + {"http://www.google.com.../", "www.google.com", "/", ""}, + {"http://www.google.com/q?", "www.google.com", "/q", ""}, + {"http://www.google.com/q?r?", "www.google.com", "/q", "r?"}, + {"http://www.google.com/q?r?s", "www.google.com", "/q", "r?s"}, + {"http://evil.com/foo#bar#baz", "evil.com", "/foo", ""}, + {"http://evil.com/foo;", "evil.com", "/foo;", ""}, + {"http://evil.com/foo?bar;", "evil.com", "/foo", "bar;"}, + {"http://notrailingslash.com", "notrailingslash.com", "/", ""}, + {"http://www.gotaport.com:1234/", "www.gotaport.com", "/", ""}, + {" http://www.google.com/ ", "www.google.com", "/", ""}, + {"http:// leadingspace.com/", "%20leadingspace.com", "/", ""}, + {"http://%20leadingspace.com/", "%20leadingspace.com", "/", ""}, + {"https://www.securesite.com/", "www.securesite.com", "/", ""}, + {"http://host.com/ab%23cd", "host.com", "/ab%23cd", ""}, + {"http://host%3e.com//twoslashes?more//slashes", "host>.com", + "/twoslashes", "more//slashes"}, + {"http://host.com/abc?val=xyz#anything", "host.com", "/abc", "val=xyz"}, + {"http://abc:def@host.com/xyz", "host.com", "/xyz", ""}, + {"http://host%3e.com/abc/%2e%2e%2fdef", "host>.com", "/def", ""}, + {"http://.......host...com.....//abc/////def%2F%2F%2Fxyz", "host.com", + "/abc/def/xyz", ""}, + {"ftp://host.com/foo?bar", "host.com", "/foo", "bar"}, + {"data:text/html;charset=utf-8,%0D%0A", "", "", ""}, + {"javascript:alert()", "", "", ""}, + {"mailto:abc@example.com", "", "", ""}, + }; + for (size_t i = 0; i < arraysize(tests); ++i) { + SCOPED_TRACE(base::StringPrintf("Test: %s", tests[i].input_url)); + GURL url(tests[i].input_url); + + std::string canonicalized_hostname; + std::string canonicalized_path; + std::string canonicalized_query; + CanonicalizeUrl(url, &canonicalized_hostname, &canonicalized_path, + &canonicalized_query); + + EXPECT_EQ(tests[i].expected_canonicalized_hostname, canonicalized_hostname); + EXPECT_EQ(tests[i].expected_canonicalized_path, canonicalized_path); + EXPECT_EQ(tests[i].expected_canonicalized_query, canonicalized_query); + } +} + +TEST(SafeBrowsingDbUtilTest, UrlToFullHashes) { + std::vector<SBFullHash> results; + GURL url("http://www.evil.com/evil1/evilness.html"); + UrlToFullHashes(url, false, &results); + + EXPECT_EQ(6UL, results.size()); + EXPECT_TRUE(SBFullHashEqual(SBFullHashForString("evil.com/"), results[0])); + EXPECT_TRUE( + SBFullHashEqual(SBFullHashForString("evil.com/evil1/"), results[1])); + EXPECT_TRUE(SBFullHashEqual( + SBFullHashForString("evil.com/evil1/evilness.html"), results[2])); + EXPECT_TRUE( + SBFullHashEqual(SBFullHashForString("www.evil.com/"), results[3])); + EXPECT_TRUE( + SBFullHashEqual(SBFullHashForString("www.evil.com/evil1/"), results[4])); + EXPECT_TRUE(SBFullHashEqual( + SBFullHashForString("www.evil.com/evil1/evilness.html"), results[5])); + + results.clear(); + GURL url2("http://www.evil.com/evil1/evilness.html"); + UrlToFullHashes(url2, true, &results); + + EXPECT_EQ(8UL, results.size()); + EXPECT_TRUE(SBFullHashEqual(SBFullHashForString("evil.com/"), results[0])); + EXPECT_TRUE( + SBFullHashEqual(SBFullHashForString("evil.com/evil1/"), results[1])); + EXPECT_TRUE( + SBFullHashEqual(SBFullHashForString("evil.com/evil1"), results[2])); + EXPECT_TRUE(SBFullHashEqual( + SBFullHashForString("evil.com/evil1/evilness.html"), results[3])); + EXPECT_TRUE( + SBFullHashEqual(SBFullHashForString("www.evil.com/"), results[4])); + EXPECT_TRUE( + SBFullHashEqual(SBFullHashForString("www.evil.com/evil1/"), results[5])); + EXPECT_TRUE( + SBFullHashEqual(SBFullHashForString("www.evil.com/evil1"), results[6])); + EXPECT_TRUE(SBFullHashEqual( + SBFullHashForString("www.evil.com/evil1/evilness.html"), results[7])); +} + +TEST(SafeBrowsingDbUtilTest, ListIdListNameConversion) { + std::string list_name; + EXPECT_FALSE(GetListName(INVALID, &list_name)); + EXPECT_TRUE(GetListName(MALWARE, &list_name)); + EXPECT_EQ(list_name, std::string(kMalwareList)); + EXPECT_EQ(MALWARE, GetListId(list_name)); + + EXPECT_TRUE(GetListName(PHISH, &list_name)); + EXPECT_EQ(list_name, std::string(kPhishingList)); + EXPECT_EQ(PHISH, GetListId(list_name)); + + EXPECT_TRUE(GetListName(BINURL, &list_name)); + EXPECT_EQ(list_name, std::string(kBinUrlList)); + EXPECT_EQ(BINURL, GetListId(list_name)); +} + +// Since the ids are saved in file, we need to make sure they don't change. +// Since only the last bit of each id is saved in file together with +// chunkids, this checks only last bit. +TEST(SafeBrowsingDbUtilTest, ListIdVerification) { + EXPECT_EQ(0, MALWARE % 2); + EXPECT_EQ(1, PHISH % 2); + EXPECT_EQ(0, BINURL % 2); +} + +TEST(SafeBrowsingDbUtilTest, StringToSBFullHashAndSBFullHashToString) { + // 31 chars plus the last \0 as full_hash. + const std::string hash_in = "12345678902234567890323456789012"; + SBFullHash hash_out = StringToSBFullHash(hash_in); + EXPECT_EQ(0x34333231U, hash_out.prefix); + EXPECT_EQ(0, memcmp(hash_in.data(), hash_out.full_hash, sizeof(SBFullHash))); + + std::string hash_final = SBFullHashToString(hash_out); + EXPECT_EQ(hash_in, hash_final); +} + +TEST(SafeBrowsingDbUtilTest, FullHashOperators) { + const SBFullHash kHash1 = SBFullHashForString("one"); + const SBFullHash kHash2 = SBFullHashForString("two"); + + EXPECT_TRUE(SBFullHashEqual(kHash1, kHash1)); + EXPECT_TRUE(SBFullHashEqual(kHash2, kHash2)); + EXPECT_FALSE(SBFullHashEqual(kHash1, kHash2)); + EXPECT_FALSE(SBFullHashEqual(kHash2, kHash1)); + + EXPECT_FALSE(SBFullHashLess(kHash1, kHash2)); + EXPECT_TRUE(SBFullHashLess(kHash2, kHash1)); + + EXPECT_FALSE(SBFullHashLess(kHash1, kHash1)); + EXPECT_FALSE(SBFullHashLess(kHash2, kHash2)); +} + +} // namespace safe_browsing
diff --git a/ios/chrome/ios_chrome.gyp b/ios/chrome/ios_chrome.gyp index 082c75bc..96f11b2 100644 --- a/ios/chrome/ios_chrome.gyp +++ b/ios/chrome/ios_chrome.gyp
@@ -93,7 +93,6 @@ '../../components/components.gyp:pref_registry', '../../components/components.gyp:proxy_config', '../../components/components.gyp:rappor', - '../../components/components.gyp:safe_browsing_db', '../../components/components.gyp:search', '../../components/components.gyp:search_engines', '../../components/components.gyp:security_interstitials_core', @@ -655,8 +654,11 @@ 'browser/safe_browsing/safe_browsing_service.h', 'browser/safe_browsing/ui_manager.cc', 'browser/safe_browsing/ui_manager.h', + 'browser/safe_browsing/util.cc', + 'browser/safe_browsing/util.h', ], 'dependencies': [ + '../../crypto/crypto.gyp:crypto', 'ios_chrome_safe_browsing_proto', ], }]
diff --git a/ios/chrome/ios_chrome_tests.gyp b/ios/chrome/ios_chrome_tests.gyp index 043f9e03..2130a166 100644 --- a/ios/chrome/ios_chrome_tests.gyp +++ b/ios/chrome/ios_chrome_tests.gyp
@@ -85,6 +85,13 @@ 'includes': [ '../../build/copy_test_data_ios.gypi' ] }, ], + 'conditions': [ + ['safe_browsing!=0', { + 'sources': [ + 'browser/safe_browsing/util_unittest.cc', + ], + }], + ], 'includes': ['ios_chrome_resources_bundle.gypi'], }, {
diff --git a/ipc/attachment_broker_privileged_win_unittest.cc b/ipc/attachment_broker_privileged_win_unittest.cc index 7a2be3b..b25214d9 100644 --- a/ipc/attachment_broker_privileged_win_unittest.cc +++ b/ipc/attachment_broker_privileged_win_unittest.cc
@@ -102,7 +102,7 @@ new base::SharedMemory(handle, false)); shared_memory->Map(size); - return std::move(shared_memory); + return shared_memory; } // |message| must be deserializable as a TestTwoHandleWinMsg. Returns the
diff --git a/media/renderers/audio_renderer_impl.cc b/media/renderers/audio_renderer_impl.cc index e6d48a6..d7cdfe1 100644 --- a/media/renderers/audio_renderer_impl.cc +++ b/media/renderers/audio_renderer_impl.cc
@@ -341,7 +341,8 @@ const AudioParameters& hw_params = hardware_config_.GetOutputConfig(); expecting_config_changes_ = stream->SupportsConfigChanges(); - if (!expecting_config_changes_ || !hw_params.IsValid()) { + if (!expecting_config_changes_ || !hw_params.IsValid() || + hw_params.format() == AudioParameters::AUDIO_FAKE) { // The actual buffer size is controlled via the size of the AudioBus // provided to Render(), so just choose something reasonable here for looks. int buffer_size = stream->audio_decoder_config().samples_per_second() / 100; @@ -668,7 +669,7 @@ // Delay playback by writing silence if we haven't reached the first // timestamp yet; this can occur if the video starts before the audio. if (algorithm_->frames_buffered() > 0) { - DCHECK(first_packet_timestamp_ != kNoTimestamp()); + CHECK(first_packet_timestamp_ != kNoTimestamp()); const base::TimeDelta play_delay = first_packet_timestamp_ - audio_clock_->back_timestamp(); if (play_delay > base::TimeDelta()) {
diff --git a/native_client_sdk/src/build_tools/json/naclsdk_manifest2.json b/native_client_sdk/src/build_tools/json/naclsdk_manifest2.json index a348e56..aab7909 100644 --- a/native_client_sdk/src/build_tools/json/naclsdk_manifest2.json +++ b/native_client_sdk/src/build_tools/json/naclsdk_manifest2.json
@@ -85,16 +85,6 @@ }, { "archives": [], - "description": "Chrome 48 bundle, revision xxxxx", - "name": "pepper_48", - "recommended": "no", - "repath": "pepper_48", - "revision": 0, - "stability": "post_stable", - "version": 48 - }, - { - "archives": [], "description": "Chrome 49 bundle, revision xxxxx", "name": "pepper_49", "recommended": "no",
diff --git a/ppapi/nacl_irt/irt_pnacl_translator_compile.cc b/ppapi/nacl_irt/irt_pnacl_translator_compile.cc index d676b21..80a7464 100644 --- a/ppapi/nacl_irt/irt_pnacl_translator_compile.cc +++ b/ppapi/nacl_irt/irt_pnacl_translator_compile.cc
@@ -2,115 +2,108 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <argz.h> -#include <stddef.h> -#include <string.h> - +#include "base/macros.h" #include "build/build_config.h" -#include "native_client/src/shared/platform/nacl_log.h" -#include "native_client/src/shared/srpc/nacl_srpc.h" +#include "ipc/ipc_listener.h" +#include "ipc/ipc_sync_channel.h" #include "native_client/src/untrusted/irt/irt_dev.h" #include "ppapi/nacl_irt/irt_interfaces.h" +#include "ppapi/nacl_irt/plugin_startup.h" +#include "ppapi/proxy/ppapi_messages.h" #if !defined(OS_NACL_NONSFI) namespace { -const int kMaxObjectFiles = 16; - -const struct nacl_irt_pnacl_compile_funcs* g_funcs; - -void StreamInitWithSplit(NaClSrpcRpc* rpc, - NaClSrpcArg** in_args, - NaClSrpcArg** out_args, - NaClSrpcClosure* done) { - int num_threads = in_args[0]->u.ival; - if (num_threads < 0 || num_threads > kMaxObjectFiles) { - NaClLog(LOG_FATAL, "Invalid # of threads (%d)\n", num_threads); +class TranslatorCompileListener : public IPC::Listener { + public: + TranslatorCompileListener(const IPC::ChannelHandle& handle, + const struct nacl_irt_pnacl_compile_funcs* funcs) + : funcs_(funcs) { + channel_ = IPC::Channel::Create(handle, IPC::Channel::MODE_SERVER, this); + CHECK(channel_->Connect()); } - int fd_start = 1; - int i = fd_start; - int num_valid_fds = 0; - int obj_fds[kMaxObjectFiles]; - while (num_valid_fds < kMaxObjectFiles && in_args[i]->u.hval >= 0) { - obj_fds[num_valid_fds] = in_args[i]->u.hval; - ++i; - ++num_valid_fds; - } - // Convert the null-delimited strings into an array of - // null-terminated strings. - char* cmd_argz = in_args[kMaxObjectFiles + fd_start]->arrays.carr; - size_t cmd_argz_len = in_args[kMaxObjectFiles + fd_start]->u.count; - size_t argc = argz_count(cmd_argz, cmd_argz_len); - char** argv = (char**)malloc((argc + 1) * sizeof(char*)); - argz_extract(cmd_argz, cmd_argz_len, argv); - char* result = - g_funcs->init_callback(num_threads, obj_fds, num_valid_fds, argv, argc); - free(argv); - if (result != NULL) { - rpc->result = NACL_SRPC_RESULT_APP_ERROR; - // SRPC wants to free() the string, so just strdup here so that the - // init_callback implementation doesn't have to know if the string - // comes from malloc or new. On error, we don't care so much - // about leaking this bit of memory. - out_args[0]->arrays.str = strdup(result); - } else { - rpc->result = NACL_SRPC_RESULT_OK; - out_args[0]->arrays.str = strdup(""); - } - done->Run(done); -} -void StreamChunk(NaClSrpcRpc* rpc, - NaClSrpcArg** in_args, - NaClSrpcArg** out_args, - NaClSrpcClosure* done) { - int result = - g_funcs->data_callback(in_args[0]->arrays.carr, in_args[0]->u.count); - rpc->result = result == 0 ? NACL_SRPC_RESULT_OK : NACL_SRPC_RESULT_APP_ERROR; - done->Run(done); -} - -void StreamEnd(NaClSrpcRpc* rpc, - NaClSrpcArg** in_args, - NaClSrpcArg** out_args, - NaClSrpcClosure* done) { - char* result = g_funcs->end_callback(); - // Fill in the deprecated return values with dummy values. - out_args[0]->u.ival = 0; - out_args[1]->arrays.str = strdup(""); - out_args[2]->arrays.str = strdup(""); - if (result != NULL) { - rpc->result = NACL_SRPC_RESULT_APP_ERROR; - // SRPC wants to free(), so strdup() and leak to hide this detail. - out_args[3]->arrays.str = strdup(result); - } else { - rpc->result = NACL_SRPC_RESULT_OK; - out_args[3]->arrays.str = strdup(""); + // Needed for handling sync messages in OnMessageReceived(). + bool Send(IPC::Message* message) { + return channel_->Send(message); } - done->Run(done); -} -const struct NaClSrpcHandlerDesc kSrpcMethods[] = { - // Protocol for streaming: - // StreamInitWithSplit(num_threads, obj_fd x 16, cmdline_flags) -> error_str - // StreamChunk(data) + - // TODO(jvoung): remove these is_shared_lib, etc. - // StreamEnd() -> (is_shared_lib, soname, dependencies, error_str) - { "StreamInitWithSplit:ihhhhhhhhhhhhhhhhC:s", StreamInitWithSplit }, - { "StreamChunk:C:", StreamChunk }, - { "StreamEnd::isss", StreamEnd }, - { NULL, NULL }, + virtual bool OnMessageReceived(const IPC::Message& msg) { + bool handled = false; + IPC_BEGIN_MESSAGE_MAP(TranslatorCompileListener, msg) + IPC_MESSAGE_HANDLER_DELAY_REPLY(PpapiMsg_PnaclTranslatorCompileInit, + OnPnaclTranslatorCompileInit) + IPC_MESSAGE_HANDLER_DELAY_REPLY(PpapiMsg_PnaclTranslatorCompileChunk, + OnPnaclTranslatorCompileChunk) + IPC_MESSAGE_HANDLER_DELAY_REPLY(PpapiMsg_PnaclTranslatorCompileEnd, + OnPnaclTranslatorCompileEnd) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; + } + + private: + void OnPnaclTranslatorCompileInit( + int num_threads, + const std::vector<ppapi::proxy::SerializedHandle>& obj_files, + const std::vector<std::string>& cmd_flags, + IPC::Message* reply_msg) { + std::vector<int> obj_file_fds(obj_files.size()); + for (size_t i = 0; i < obj_files.size(); ++i) { + CHECK(obj_files[i].is_file()); + obj_file_fds[i] = obj_files[i].descriptor().fd; + } + + std::vector<char*> cmd_flags_cstrings(cmd_flags.size()); + for (size_t i = 0; i < cmd_flags.size(); ++i) { + // It's OK to use const_cast here because the callee (the translator) + // is not supposed to modify the strings. (The interface definition + // should have used "const char* const*".) + cmd_flags_cstrings[i] = const_cast<char*>(cmd_flags[i].c_str()); + } + + char* error_cstr = funcs_->init_callback(num_threads, + obj_file_fds.data(), + obj_file_fds.size(), + cmd_flags_cstrings.data(), + cmd_flags_cstrings.size()); + bool success = !error_cstr; + std::string error_str(error_cstr ? error_cstr : ""); + PpapiMsg_PnaclTranslatorCompileInit::WriteReplyParams( + reply_msg, success, error_str); + Send(reply_msg); + } + + void OnPnaclTranslatorCompileChunk(const std::string& data_chunk, + IPC::Message* reply_msg) { + int result = funcs_->data_callback(data_chunk.data(), data_chunk.size()); + bool success = !result; + PpapiMsg_PnaclTranslatorCompileChunk::WriteReplyParams(reply_msg, success); + Send(reply_msg); + } + + void OnPnaclTranslatorCompileEnd(IPC::Message* reply_msg) { + char* error_cstr = funcs_->end_callback(); + bool success = !error_cstr; + std::string error_str(error_cstr ? error_cstr : ""); + PpapiMsg_PnaclTranslatorCompileEnd::WriteReplyParams( + reply_msg, success, error_str); + Send(reply_msg); + } + + scoped_ptr<IPC::Channel> channel_; + const struct nacl_irt_pnacl_compile_funcs* funcs_; + + DISALLOW_COPY_AND_ASSIGN(TranslatorCompileListener); }; void ServeTranslateRequest(const struct nacl_irt_pnacl_compile_funcs* funcs) { - g_funcs = funcs; - if (!NaClSrpcModuleInit()) { - NaClLog(LOG_FATAL, "NaClSrpcModuleInit() failed\n"); - } - if (!NaClSrpcAcceptClientConnection(kSrpcMethods)) { - NaClLog(LOG_FATAL, "NaClSrpcAcceptClientConnection() failed\n"); - } + base::MessageLoop loop; + int fd = ppapi::GetRendererIPCFileDescriptor(); + IPC::ChannelHandle handle("NaCl IPC", base::FileDescriptor(fd, false)); + new TranslatorCompileListener(handle, funcs); + loop.Run(); } }
diff --git a/ppapi/proxy/nacl_message_scanner.cc b/ppapi/proxy/nacl_message_scanner.cc index 5011501..6ea9adf 100644 --- a/ppapi/proxy/nacl_message_scanner.cc +++ b/ppapi/proxy/nacl_message_scanner.cc
@@ -364,6 +364,7 @@ CASE_FOR_MESSAGE(PpapiMsg_PPBAudio_NotifyAudioStreamCreated) CASE_FOR_MESSAGE(PpapiMsg_PPPMessaging_HandleMessage) CASE_FOR_MESSAGE(PpapiPluginMsg_ResourceReply) + CASE_FOR_SYNC_MESSAGE(PpapiMsg_PnaclTranslatorCompileInit) CASE_FOR_SYNC_MESSAGE(PpapiMsg_PnaclTranslatorLink) CASE_FOR_REPLY(PpapiHostMsg_OpenResource) CASE_FOR_REPLY(PpapiHostMsg_PPBGraphics3D_Create)
diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index 41be9a4..9a1f45c 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h
@@ -871,6 +871,45 @@ #endif // !defined(OS_NACL) && !defined(NACL_WIN64) +// This message is sent from the renderer to the PNaCl compiler process +// (NaCl untrusted code -- a nexe). This implements the init_callback() +// IRT interface. This message initializes the translation process, +// providing an array of object file FDs for writing output to, along with +// other parameters. +IPC_SYNC_MESSAGE_CONTROL3_2(PpapiMsg_PnaclTranslatorCompileInit, + /* number of threads to use */ + int, + /* object file FDs for outputs */ + std::vector<ppapi::proxy::SerializedHandle>, + /* list of command line flags */ + std::vector<std::string>, + /* success status result */ + bool, + /* error string if the success field is false */ + std::string) + +// This message is sent from the renderer to the PNaCl compiler process +// (NaCl untrusted code -- a nexe). This implements the data_callback() +// IRT interface. This message sends the next chunk of input bitcode data +// to the compiler process. If the success result is false (for failure), +// the renderer can still invoke PpapiMsg_PnaclTranslatorCompileEnd to get +// a message describing the error. +IPC_SYNC_MESSAGE_CONTROL1_1(PpapiMsg_PnaclTranslatorCompileChunk, + /* chunk of data for the input pexe file */ + std::string, + /* success status result */ + bool) + +// This message is sent from the renderer to the PNaCl compiler process +// (NaCl untrusted code -- a nexe). This implements the end_callback() IRT +// interface. This blocks until translation is complete or an error has +// occurred. +IPC_SYNC_MESSAGE_CONTROL0_2(PpapiMsg_PnaclTranslatorCompileEnd, + /* success status result */ + bool, + /* error string if the success field is false */ + std::string) + // This message is sent from the renderer to the PNaCl linker process // (NaCl untrusted code -- a nexe). This message tells the PNaCl // linker to link the given object files together to produce a nexe
diff --git a/sandbox/linux/BUILD.gn b/sandbox/linux/BUILD.gn index 8396a661..341d363 100644 --- a/sandbox/linux/BUILD.gn +++ b/sandbox/linux/BUILD.gn
@@ -119,11 +119,6 @@ defines = [ "SANDBOX_USES_BASE_TEST_SUITE" ] } - if (is_linux) { - # Don't use this on Android. - libs = [ "rt" ] - } - if (compile_suid_client) { sources += [ "suid/client/setuid_sandbox_client_unittest.cc",
diff --git a/sandbox/mac/launchd_interception_server.cc b/sandbox/mac/launchd_interception_server.cc index b793b03..69231b5 100644 --- a/sandbox/mac/launchd_interception_server.cc +++ b/sandbox/mac/launchd_interception_server.cc
@@ -32,6 +32,7 @@ } LaunchdInterceptionServer::~LaunchdInterceptionServer() { + message_server_->Shutdown(); } bool LaunchdInterceptionServer::Initialize(mach_port_t server_receive_right) {
diff --git a/sandbox/mac/mach_message_server.cc b/sandbox/mac/mach_message_server.cc index 20bd94c..7626c3a 100644 --- a/sandbox/mac/mach_message_server.cc +++ b/sandbox/mac/mach_message_server.cc
@@ -76,6 +76,10 @@ return true; } +void MachMessageServer::Shutdown() { + dispatch_source_.reset(); +} + pid_t MachMessageServer::GetMessageSenderPID(IPCMessage request) { // Get the PID of the task that sent this request. This requires getting at // the trailer of the message, from the header.
diff --git a/sandbox/mac/mach_message_server.h b/sandbox/mac/mach_message_server.h index cf5b36f..515d565 100644 --- a/sandbox/mac/mach_message_server.h +++ b/sandbox/mac/mach_message_server.h
@@ -34,6 +34,7 @@ // MessageServer: bool Initialize() override; + void Shutdown() override; pid_t GetMessageSenderPID(IPCMessage request) override; IPCMessage CreateReply(IPCMessage request) override; bool SendReply(IPCMessage reply) override;
diff --git a/sandbox/mac/message_server.h b/sandbox/mac/message_server.h index 1cd40b0..6ee119b 100644 --- a/sandbox/mac/message_server.h +++ b/sandbox/mac/message_server.h
@@ -44,6 +44,11 @@ // returns false, no other methods may be called on this class. virtual bool Initialize() = 0; + // Blocks the calling thread while the server shuts down. This prevents + // the server from receiving new messages. After this method is called, + // no other methods may be called on this class. + virtual void Shutdown() = 0; + // Given a received request message, returns the PID of the sending process. virtual pid_t GetMessageSenderPID(IPCMessage request) = 0;
diff --git a/sandbox/mac/xpc_message_server.cc b/sandbox/mac/xpc_message_server.cc index d811e5d5c..1375310 100644 --- a/sandbox/mac/xpc_message_server.cc +++ b/sandbox/mac/xpc_message_server.cc
@@ -48,6 +48,10 @@ return true; } +void XPCMessageServer::Shutdown() { + dispatch_source_.reset(); +} + pid_t XPCMessageServer::GetMessageSenderPID(IPCMessage request) { audit_token_t token; xpc_dictionary_get_audit_token(request.xpc, &token);
diff --git a/sandbox/mac/xpc_message_server.h b/sandbox/mac/xpc_message_server.h index 94c8858d..c509bab 100644 --- a/sandbox/mac/xpc_message_server.h +++ b/sandbox/mac/xpc_message_server.h
@@ -31,6 +31,7 @@ // MessageServer: bool Initialize() override; + void Shutdown() override; pid_t GetMessageSenderPID(IPCMessage request) override; IPCMessage CreateReply(IPCMessage request) override; bool SendReply(IPCMessage reply) override;
diff --git a/testing/buildbot/chromium.memory.fyi.json b/testing/buildbot/chromium.memory.fyi.json index e1986d4..6d82bfd 100644 --- a/testing/buildbot/chromium.memory.fyi.json +++ b/testing/buildbot/chromium.memory.fyi.json
@@ -837,5 +837,100 @@ "test": "wm_unittests" } ] + }, + "Linux Tests (valgrind)(1)": { + "gtest_tests": [ + { + "test": "crypto_unittests" + }, + { + "test": "display_unittests" + }, + { + "test": "ipc_tests" + }, + { + "test": "jingle_unittests" + }, + { + "test": "net_unittests" + }, + { + "test": "ppapi_unittests" + }, + { + "test": "printing_unittests" + }, + { + "test": "sandbox_linux_unittests" + }, + { + "test": "sql_unittests" + }, + { + "test": "sync_unit_tests" + }, + { + "test": "ui_base_unittests" + }, + { + "test": "url_unittests" + } + ] + }, + "Linux Tests (valgrind)(2)": { + "gtest_tests": [ + { + "test": "extensions_unittests" + } + ] + }, + "Linux Tests (valgrind)(3)": { + "gtest_tests": [ + { + "test": "media_unittests" + }, + { + "test": "midi_unittests" + }, + { + "test": "remoting_unittests" + }, + { + "shard_index": 0, + "test": "unit_tests", + "total_shards": 3 + } + ] + }, + "Linux Tests (valgrind)(4)": { + "gtest_tests": [ + { + "test": "components_unittests" + }, + { + "test": "content_unittests" + }, + { + "shard_index": 1, + "test": "unit_tests", + "total_shards": 3 + } + ] + }, + "Linux Tests (valgrind)(5)": { + "gtest_tests": [ + { + "test": "base_unittests" + }, + { + "test": "gpu_unittests" + }, + { + "shard_index": 2, + "test": "unit_tests", + "total_shards": 3 + } + ] } }
diff --git a/testing/buildbot/filters/browser-side-navigation.linux.browser_tests.filter b/testing/buildbot/filters/browser-side-navigation.linux.browser_tests.filter index 9d3178f..d2fce69 100644 --- a/testing/buildbot/filters/browser-side-navigation.linux.browser_tests.filter +++ b/testing/buildbot/filters/browser-side-navigation.linux.browser_tests.filter
@@ -1,87 +1,29 @@ -ActivityLogApiTest.TriggerEvent --AdbClientSocketTest.TestFlushWithData --AdbClientSocketTest.TestFlushWithoutSize --AdbClientSocketTest.TestFlushWithSize -AllUrlsApiTest.WhitelistedExtension --AppBannerDataFetcherBrowserTest.CancelBannerDirect --AppBannerDataFetcherBrowserTest.CancelBannerIndirect --AppBannerDataFetcherBrowserTest.NoManifest --AppBannerDataFetcherBrowserTest.PromptBanner --AppBannerDataFetcherBrowserTest.PromptBannerInHandler --AppBannerDataFetcherBrowserTest.WebAppBannerCreatedDirect --AppBannerDataFetcherBrowserTest.WebAppBannerCreatedDirectLargerTotal --AppBannerDataFetcherBrowserTest.WebAppBannerCreatedDirectMultiple --AppBannerDataFetcherBrowserTest.WebAppBannerCreatedDirectMultipleLargerTotal --AppBannerDataFetcherBrowserTest.WebAppBannerCreatedDirectMultipleSmallerTotal --AppBannerDataFetcherBrowserTest.WebAppBannerCreatedDirectSingle --AppBannerDataFetcherBrowserTest.WebAppBannerCreatedDirectSmallerTotal --AppBannerDataFetcherBrowserTest.WebAppBannerCreatedIndirect --AppBannerDataFetcherBrowserTest.WebAppBannerCreatedIndirectLargerTotal --AppBannerDataFetcherBrowserTest.WebAppBannerCreatedIndirectMultiple --AppBannerDataFetcherBrowserTest.WebAppBannerCreatedIndirectMultipleLargerTotal --AppBannerDataFetcherBrowserTest.WebAppBannerCreatedIndirectSingle --AppBannerDataFetcherBrowserTest.WebAppBannerCreatedIndirectSmallerTotal --AppBannerDataFetcherBrowserTest.WebAppBannerCreatedVarious --AppBannerDataFetcherBrowserTest.WebAppBannerInIFrame --AppBannerDataFetcherBrowserTest.WebAppBannerNoTypeInManifest --AppBannerDataFetcherBrowserTest.WebAppBannerNoTypeInManifestCapsExtension --AppListServiceImplBrowserTest.DeletingProfileUpdatesViewDelegate +-AppViewTest.TestAppViewMultipleConnects -AppWindowAPITest.TestCreate -AutofillTest.AggregatesMinValidProfile -AutofillTest.AggregatesMinValidProfileDifferentJS -AutofillTest.AppendCountryCodeForAggregatedPhones --AutofillTest.CCInfoNotStoredWhenAutocompleteOff --AutofillTest.InvalidCreditCardNumberIsNotAggregated -AutofillTest.ProfileSavedWithValidCountryPhone -AutofillTest.ProfilesNotAggregatedWithInvalidEmail -AutofillTest.ProfilesNotAggregatedWithNoAddress -AutofillTest.ProfilesNotAggregatedWithSubmitHandler -AutofillTest.ProfileWithEmailInOtherFieldNotSaved -AutofillTest.UsePlusSignForInternationalNumber --AutofillTest.WhitespacesAndSeparatorCharsStrippedForValidCCNums --BrowserCloseManagerWithDownloadsBrowserTest/BrowserCloseManagerWithDownloadsBrowserTest.TestWithDangerousUrlDownload/0 --BrowserCloseManagerWithDownloadsBrowserTest/BrowserCloseManagerWithDownloadsBrowserTest.TestWithDangerousUrlDownload/1 --BrowserCloseManagerWithDownloadsBrowserTest/BrowserCloseManagerWithDownloadsBrowserTest.TestWithDownloads/0 --BrowserCloseManagerWithDownloadsBrowserTest/BrowserCloseManagerWithDownloadsBrowserTest.TestWithDownloads/1 --BrowserCloseManagerWithDownloadsBrowserTest/BrowserCloseManagerWithDownloadsBrowserTest.TestWithDownloadsFromDifferentProfiles/0 --BrowserCloseManagerWithDownloadsBrowserTest/BrowserCloseManagerWithDownloadsBrowserTest.TestWithDownloadsFromDifferentProfiles/1 --BrowserCloseManagerWithDownloadsBrowserTest/BrowserCloseManagerWithDownloadsBrowserTest.TestWithOffTheRecordDownloads/0 --BrowserCloseManagerWithDownloadsBrowserTest/BrowserCloseManagerWithDownloadsBrowserTest.TestWithOffTheRecordDownloads/1 +-BrowserActionApiTest.BrowserActionPopupWithIframe -BrowserNavigatorTest.NavigateFromNTPToOptionsInSameTab -BrowserTest.BeforeUnloadVsBeforeReload -BrowserTest.ClearPendingOnFailUnlessNTP -BrowserTest.InterstitialCancelsGuestViewDialogs -BrowserTest.NoStopDuringTransferUntilCommit --BrowserTest.SecurityStyleChangedObserver --BrowserTest.SecurityStyleChangedObserverGoBack --BrowserTest.ShouldShowLocationBar --BrowserViewTest.DevToolsUpdatesBrowserWindow --BrowsingDataRemoverBrowserTest.Download --CaptivePortalBrowserTest.InterstitialTimerCertErrorAfterSlowLoad --CaptivePortalBrowserTest.InterstitialTimerNavigateAwayWhileLoading --CaptivePortalBrowserTest.InterstitialTimerNavigateWhileLoading_EndWithCaptivePortalInterstitial --CaptivePortalBrowserTest.InterstitialTimerNavigateWhileLoading_EndWithSSLInterstitial --CaptivePortalBrowserTest.InterstitialTimerReloadWhileLoading --CaptivePortalBrowserTest.InterstitialTimerStopNavigationWhileLoading --CaptivePortalBrowserTest.ShowCaptivePortalInterstitialOnCertError +-BrowserTest.SadTabCancelsSubframeDialogs -CaptivePortalBrowserTest.SSLCertErrorLogin --CertVerifierBrowserTest.MockCertVerifierSmokeTest -ChromeMainTest.SecondLaunchFromIncognitoWithNormalUrl -ChromeRenderProcessHostTest.DevToolsOnSelfInOwnProcess -ChromeRenderProcessHostTest.DevToolsOnSelfInOwnProcessPPT -ChromeRenderViewTest.BackToTranslatablePage -ChromeResourceDispatcherHostDelegateBrowserTest.PolicyHeaderForRedirect --ChromeSitePerProcessTest.OriginReplicationAllowsAccessToStorage --ChromeSitePerProcessTest.PluginWithRemoteTopFrame --ClearBrowserDataBrowserTest.CommitButtonDisabledWhenNoDataTypesSelected --ClearBrowserDataBrowserTest.CommitButtonDisabledWhileDeletionInProgress --CommonNameMismatchBrowserTest.CheckWWWSubdomainMismatchInverse --CommonNameMismatchBrowserTest.InterstitialNavigateAwayWhileLoading --CommonNameMismatchBrowserTest.InterstitialReloadNavigationWhileLoading --CommonNameMismatchBrowserTest.InterstitialStopNavigationWhileLoading --CommonNameMismatchBrowserTest.ShouldShowWWWSubdomainMismatchInterstitial --ContentSettingBubbleModelMixedScriptTest.Iframe --ContentSettingsExceptionsAreaBrowserTest.OpenIncognitoWindow -ContentSettingsTest.RedirectCrossOrigin -ContentSettingsTest.RedirectLoopCookies -ContinueWhereILeftOffTest.Post @@ -89,40 +31,9 @@ -ContinueWhereILeftOffTest.PostCloseAllBrowsers -CrashRecoveryBrowserTest.DoubleReloadWithError -CrashRecoveryBrowserTest.LoadInNewTab --DeveloperPrivateApiTest.InspectAppWindowView --DevToolsBeforeUnloadTest.TestDockedDevToolsClose --DevToolsBeforeUnloadTest.TestDockedDevToolsInspectedBrowserClose --DevToolsBeforeUnloadTest.TestDockedDevToolsInspectedTabClose --DevToolsBeforeUnloadTest.TestUndockedDevToolsApplicationClose --DevToolsBeforeUnloadTest.TestUndockedDevToolsClose --DevToolsBeforeUnloadTest.TestUndockedDevToolsInspectedBrowserClose --DevToolsBeforeUnloadTest.TestUndockedDevToolsInspectedTabClose --DevToolsBeforeUnloadTest.TestWorkerWindowClosing --DevToolsExperimentalExtensionTest.TestDevToolsExperimentalExtensionAPI --DevToolsExtensionTest.TestContentScriptIsPresent --DevToolsExtensionTest.TestDevToolsExtensionAPI --DevToolsExtensionTest.TestDevToolsExtensionMessaging --DevToolsPixelOutputTests.TestScreenshotRecording --DevToolsReattachAfterCrashTest.TestReattachAfterCrashOnNetwork --DevToolsReattachAfterCrashTest.TestReattachAfterCrashOnTimeline +-DataSaverBrowserTest.DataSaverEnabled -DevToolsSanityTest.TestConsoleOnNavigateBack --DevToolsSanityTest.TestDeviceEmulation --DevToolsSanityTest.TestDevToolsExternalNavigation -DevToolsSanityTest.TestNetworkRawHeadersText --DevToolsSanityTest.TestNetworkSize --DevToolsSanityTest.TestNetworkSyncSize --DevToolsSanityTest.TestNetworkTiming --DevToolsSanityTest.TestNoScriptDuplicatesOnPanelSwitch --DevToolsSanityTest.TestPageWithNoJavaScript --DevToolsSanityTest.TestPauseWhenLoadingDevTools --DevToolsSanityTest.TestPauseWhenScriptIsRunning --DevToolsSanityTest.TestScriptsTabIsPopulatedOnInspectedPageRefresh --DevToolsSanityTest.TestSettings --DevToolsSanityTest.TestShowScriptsTab --DevToolsSanityTest.TestToolboxLoadedUndocked --DevToolsSanityTest.TestToolboxNotLoadedDocked --DevToolsTagTest.DevToolsTaskIsProvided --DevToolsTagTest.TagsManagerRecordsATag -DomDistillerTabUtilsBrowserTest.TestDistillIntoWebContents -DomDistillerTabUtilsBrowserTest.TestSwapWebContents -DomDistillerViewerSourceBrowserTest.DistillerJavaScriptExposed @@ -139,92 +50,28 @@ -DomDistillerViewerSourceBrowserTest.PrefChangeError -DomDistillerViewerSourceBrowserTest.PrefPersist -DomDistillerViewerSourceBrowserTest.TestBadUrlErrorPage --DownloadExtensionTest.DownloadExtensionTest_FileIcon_Active --DownloadExtensionTest.DownloadExtensionTest_OnDeterminingFilename_InterruptedResume --DownloadExtensionTest.DownloadExtensionTest_Open --DownloadExtensionTest.DownloadExtensionTest_PauseResumeCancelErase --DownloadExtensionTest.DownloadExtensionTest_SearchEmptyQuery --DownloadExtensionTest.DownloadExtensionTest_SearchId --DownloadExtensionTest.DownloadExtensionTest_SearchIdAndFilename --DownloadExtensionTest.DownloadExtensionTest_SearchLimit --DownloadExtensionTest.DownloadExtensionTest_SearchPauseResumeCancelGetFileIconIncognito --DownloadExtensionTest.DownloadExtensionTest_SearchState --DownloadTest.AutoOpen --DownloadTest.BrowserCloseAfterDownload -DownloadTest.ChromeURLAfterDownload --DownloadTest.CloseNewTab1 --DownloadTest.CloseNewTab2 --DownloadTest.CloseNewTab3 --DownloadTest.ContentDisposition --DownloadTest.CrxDenyInstall --DownloadTest.CrxInstallAcceptPermissions --DownloadTest.CrxInstallDenysPermissions --DownloadTest.CrxInvalid --DownloadTest.CrxLargeTheme --DownloadTest.DontCloseNewTab2 --DownloadTest.DontCloseNewTab3 --DownloadTest.DownloadErrorReadonlyFolder --DownloadTest.DownloadErrorsFile --DownloadTest.DownloadErrorsServer --DownloadTest.DownloadHistoryCheck --DownloadTest.DownloadHistoryDangerCheck --DownloadTest.DownloadMimeType --DownloadTest.DownloadMimeTypeSelect --DownloadTest.DownloadTest_CrazyFilenames --DownloadTest.DownloadTest_GZipWithNoContent --DownloadTest.DownloadTest_IncognitoRegular --DownloadTest.DownloadTest_PauseResumeCancel --DownloadTest.DownloadTest_PercentComplete --DownloadTest.DownloadTest_Remove --DownloadTest.DownloadTest_Renaming --DownloadTest.FeedbackService --DownloadTest.IncognitoDownload --DownloadTest.KnownSize -DownloadTest.LoadURLExternallyReferrerPolicy --DownloadTest.Resumption_Automatic --DownloadTest.Resumption_MultipleAttempts --DownloadTest.Resumption_NoPrompt --DownloadTest.Resumption_WithPrompt --DownloadTest.Resumption_WithPromptAlways -DownloadTest.SavePageNonHTMLViaPost --DownloadTest.TestMultipleDownloadsBubble --DownloadTest.UnknownSize --DownloadTestWithShelf.AutoOpen --DownloadTestWithShelf.CloseShelfOnDownloadsTab --DownloadTestWithShelf.CrxDenyInstall --DownloadTestWithShelf.DownloadAndWait --DownloadTestWithShelf.IncognitoDownload --DownloadTestWithShelf.NewWindow --DownloadTestWithShelf.PerWindowShelf --DownloadTestWithShelf.PRE_DownloadTest_History -ErrorPageAutoReloadTest.AutoReload +-ErrorPageAutoReloadTest.IgnoresSamePageNavigation -ErrorPageAutoReloadTest.ManualReloadNotSuppressed -ErrorPageTest.DNSError_DoClickLink -ErrorPageTest.DNSError_DoReload +-ErrorPageTest.DNSError_DoReloadAfterSamePageNavigation -ErrorPageTest.DNSError_DoSearch -ErrorPageTest.StaleCacheStatus -ExtensionApiNewTabTest.Tabs +-ExtensionApiTest.ContentScriptAboutBlankAndSrcdoc -ExtensionApiTest.CookiesEventsSpanning -ExtensionApiTest.Events --ExtensionApiTest.Incognito --ExtensionApiTest.JavaScriptURLPermissions --ExtensionApiTest.JavasScriptEncodedURL -ExtensionApiTest.TabsOnUpdated -ExtensionBrowserTest.WindowOpenExtension --ExtensionLoadingTest.KeepAliveWithDevToolsOpenOnReload -ExtensionOverrideTest.OverrideNewTabIncognito -ExtensionPreferenceApiTest.OnChangeSplit -ExtensionResourceRequestPolicyTest.LinkToWebAccessibleResources -ExtensionResourceRequestPolicyTest.WebAccessibleResources -ExtensionTabsTest.DefaultToIncognitoWhenItIsForcedAndNoArgs --ExtensionTabsTest.ExecuteScriptOnDevTools --ExtensionTabsTest.FilteredEvents --ExtensionTabsTest.GetAllWindows --ExtensionTabsTest.GetAllWindowsAllTypes --ExtensionTabsTest.GetWindow --ExtensionTabsTest.NoTabsEventOnDevTools --ExtensionTabsTest.QueryAllTabsWithDevTools --ExtensionTabsTest.UpdateDevToolsWindow -ExtensionURLRewriteBrowserTest.NewTabPageURL -ExtensionWebRequestApiTest.WebRequestBlocking -ExtensionWebRequestApiTest.WebRequestComplex @@ -232,19 +79,9 @@ -ExtensionWebRequestApiTest.WebRequestDeclarative2 -ExtensionWebRequestApiTest.WebRequestNewTab -ExtensionWebRequestApiTest.WebRequestSimple --ExtensionWindowLastFocusedTest.NoDevtoolsAndAppWindows --ExtensionWindowLastFocusedTest.NoTabIdForDevToolsAndAppWindows --FindInPageControllerTest.BigString -FindInPageControllerTest.SearchWithinSpecialURL --FindInPageControllerTest.SelectChangesOrdinal_Issue20883 -FirstRunMasterPrefsImportNothing.ImportNothingAndShowNewTabPage --HistoryApiTest.Delete --HistoryApiTest.DeleteProhibited --HistoryApiTest.SearchAfterAdd --HistoryBrowserTest.DownloadNoHistory --HostedAppTest.ShouldUseWebAppFrame -InlineLoginUISafeIframeBrowserTest.ConfirmationRequiredForNonsecureSignin --InspectUITest.AndroidTargets -IsolatedAppTest.CookieIsolation -LoadTimingBrowserTest.Basic -LoadTimingBrowserTest.EverythingAtOnce @@ -253,32 +90,7 @@ -LoadTimingBrowserTest.PreconnectProxySsl -LoadTimingBrowserTest.ReuseSocket -LoadTimingBrowserTest.Ssl --LoginPromptBrowserTest.AllowCrossdomainPromptForSubframes --LoginPromptBrowserTest.CancelRedundantAuths --LoginPromptBrowserTest.NoLoginPromptForFavicon --LoginPromptBrowserTest.ShouldReplaceExistingInterstitialWhenNavigated --LoginPromptBrowserTest.ShowCorrectUrlForCrossOriginMainFrameRedirects --LoginPromptBrowserTest.ShowCorrectUrlForCrossOriginMainFrameRequests --LoginPromptBrowserTest.SupplyRedundantAuths --LoginPromptBrowserTest.SupplyRedundantAuthsMultiProfile --LoginPromptBrowserTest.TestBasicAuth --LoginPromptBrowserTest.TestCancelAuth --LoginPromptBrowserTest.TestDigestAuth --LoginPromptBrowserTest.TestTwoAuths --LogWebUIUrlTest.TestHistoryFrame -LogWebUIUrlTest.TestUberPage --MaterialPDFExtensionTest.Basic --MaterialPDFExtensionTest.BasicPlugin --MaterialPDFExtensionTest.Bookmark --MaterialPDFExtensionTest.Elements --MaterialPDFExtensionTest.Navigator --MaterialPDFExtensionTest.PageChange --MaterialPDFExtensionTest.ParamsParser --MaterialPDFExtensionTest.Title --MaterialPDFExtensionTest.ToolbarManager --MaterialPDFExtensionTest.Viewport --MaterialPDFExtensionTest.WhitespaceTitle --MaterialPDFExtensionTest.ZoomManager -MaybeSetMetadata/SafeBrowsingServiceMetadataTest.MalwareIFrame/0 -MaybeSetMetadata/SafeBrowsingServiceMetadataTest.MalwareIFrame/1 -MaybeSetMetadata/SafeBrowsingServiceMetadataTest.MalwareIFrame/2 @@ -294,29 +106,29 @@ -MimeHandlerViewTest.DataUrl -MimeHandlerViewTest.Iframe -MimeHandlerViewTest.NonAsciiHeaders --NetInternalsTest.netInternalsPrerenderViewFail -NewTabUIBrowserTest.ShowIncognito --OmniboxApiTest.OnInputEntered --OptionsUIBrowserTest.LoadOptionsByURL -OptionsWebUIExtendedTest.OverlayBackToChild -OptionsWebUIExtendedTest.OverlayBackToUnrelated -OptionsWebUIExtendedTest.OverlayTabNavigation --PasswordManagerBrowserTestBase.BasicAuthSeparateRealms -PasswordManagerBrowserTestBase.CrossSiteIframeNotFillTest --PasswordManagerBrowserTestBase.NoLastLoadGoodLastLoad -PasswordManagerBrowserTestBase.NoPromptIfLinkClicked -PasswordManagerBrowserTestBase.PromptAfterSubmitWithSubFrameNavigation +-PasswordManagerBrowserTestBase.PromptForSubmitFromIframe -PasswordManagerBrowserTestBase.SameOriginIframeAutoFillTest -PDFExtensionTest.Basic -PDFExtensionTest.BasicPlugin -PDFExtensionTest.Bookmark --PDFExtensionTest.DisablePlugin +-PDFExtensionTest.Elements -PDFExtensionTest.EnsureSameOriginRepliesAllowed -PDFExtensionTest.LinkPermissions -PDFExtensionTest.Navigator -PDFExtensionTest.PageChange -PDFExtensionTest.ParamsParser +-PDFExtensionTest.PdfZoomWithoutBubble +-PDFExtensionTest.TabTitleWithNoTitle +-PDFExtensionTest.TabTitleWithTitle -PDFExtensionTest.Title +-PDFExtensionTest.ToolbarManager -PDFExtensionTest.Viewport -PDFExtensionTest.WhitespaceTitle -PDFExtensionTest.ZoomManager @@ -324,22 +136,20 @@ -PDFTestFiles/PDFExtensionTest.Load/1 -PDFTestFiles/PDFExtensionTest.Load/5 -PDFTestFiles/PDFExtensionTest.Load/8 --PhishingClassifierTest.TestClassification --PhishingDOMFeatureExtractorTest.LinkFeatures +-PhishingClassifierTest.TestClassificationWhenPostRequest -PlatformAppBrowserTest.ActiveAppsAreRecorded -PlatformAppBrowserTest.AppWindowRestoreState --PlatformAppDevToolsBrowserTest.ReOpenedWithID --PlatformAppDevToolsBrowserTest.ReOpenedWithURL +-PlatformAppUrlRedirectorBrowserTest.BlankClickInAppIntercepted +-PlatformAppUrlRedirectorBrowserTest.BlankClickInTabIntercepted +-PlatformAppUrlRedirectorBrowserTest.ClickInTabIntercepted +-PlatformAppUrlRedirectorBrowserTest.EntryInOmnibarIntercepted -PlatformAppUrlRedirectorBrowserTest.PrerenderedClickInTabIntercepted --PolicyTest.DownloadDirectory --PolicyTest.ExtensionInstallSources +-PlatformAppUrlRedirectorBrowserTest.WebviewNavigationNotIntercepted +-PlatformAppUrlRedirectorBrowserTest.WindowOpenInAppIntercepted +-PlatformAppUrlRedirectorBrowserTest.WindowOpenInTabIntercepted -PolicyTest.FullscreenAllowedApp -PolicyTest.HomepageLocation --PolicyTest.SafeBrowsingExtendedReportingOptInAllowed --PolicyTest.SSLErrorOverridingAllowed --PolicyTest.SSLErrorOverridingDisallowed -PolicyUITest.ExtensionLoadAndSendPolicy --PrefsFunctionalTest.TestDownloadDirPref -PrerenderBrowserTest.PrerenderCancelMainFrameRedirectUnsupportedScheme -PrerenderBrowserTest.PrerenderClientRedirectFromFragment -PrerenderBrowserTest.PrerenderClientRedirectNavigateToFirst @@ -348,11 +158,6 @@ -PrerenderBrowserTest.PrerenderClientRedirectToFragment -PrerenderBrowserTest.PrerenderCrossProcessServerRedirect -PrerenderBrowserTest.PrerenderCrossProcessServerRedirectNoHang --PrerenderBrowserTest.PrerenderCrx --PrerenderBrowserTest.PrerenderDownloadClientRedirect --PrerenderBrowserTest.PrerenderDownloadIframe --PrerenderBrowserTest.PrerenderDownloadLocation --PrerenderBrowserTest.PrerenderHttpAuthentication -PrerenderBrowserTest.PrerenderLocationReplaceGWSHistograms -PrerenderBrowserTest.PrerenderLocationReplaceNavigateToFirst -PrerenderBrowserTest.PrerenderLocationReplaceNavigateToSecond @@ -363,40 +168,8 @@ -PrerenderBrowserTest.PrerenderSafeBrowsingTopLevel -PrerenderBrowserTest.PrerenderSSLClientCertIframe -PrerenderBrowserTest.PrerenderSSLClientCertTopLevel --PrerenderBrowserTest.PrerenderSSLErrorTopLevel -PrerenderBrowserTestWithExtensions.StreamsTest --ProfileManagerBrowserTest.DeletePasswords --ProfileManagerBrowserTest.EphemeralProfile --ProxyBrowserTest.BasicAuthWSConnect --PushMessagingBackgroundModeDisabledBrowserTest.BackgroundModeDisabledWithCommandLine --PushMessagingBackgroundModeEnabledBrowserTest.BackgroundModeEnabledWithCommandLine --PushMessagingBrowserTest.AutomaticUnsubscriptionFollowsContentSettingRules --PushMessagingBrowserTest.BackgroundModeDisabledByDefault --PushMessagingBrowserTest.DenyNotificationsPermissionUnsubscribes --PushMessagingBrowserTest.DenyPushPermissionUnsubscribes --PushMessagingBrowserTest.EncryptionKeyUniqueness --PushMessagingBrowserTest.GlobalResetNotificationsPermissionUnsubscribes --PushMessagingBrowserTest.GlobalResetPushPermissionUnsubscribes --PushMessagingBrowserTest.GrantAlreadyGrantedPermissionDoesNotUnsubscribe --PushMessagingBrowserTest.LocalResetNotificationsPermissionUnsubscribes --PushMessagingBrowserTest.LocalResetPushPermissionUnsubscribes --PushMessagingBrowserTest.PermissionStateSaysDenied --PushMessagingBrowserTest.PermissionStateSaysGranted --PushMessagingBrowserTest.PermissionStateSaysPrompt --PushMessagingBrowserTest.PushEventEnforcesUserVisibleNotification --PushMessagingBrowserTest.PushEventEnforcesUserVisibleNotificationAfterQueue --PushMessagingBrowserTest.PushEventNoServiceWorker --PushMessagingBrowserTest.PushEventNotificationWithoutEventWaitUntil --PushMessagingBrowserTest.PushEventSuccess --PushMessagingBrowserTest.ResetPushPermissionAfterClearingSiteData --PushMessagingBrowserTest.SubscribeFailureNoManifest --PushMessagingBrowserTest.SubscribeFailureNotificationsBlocked --PushMessagingBrowserTest.SubscribePersisted --PushMessagingBrowserTest.SubscribeSuccessNotificationsGranted --PushMessagingBrowserTest.SubscribeSuccessNotificationsPrompt --PushMessagingBrowserTest.UnsubscribeSuccess --PushMessagingBrowserTestEmptySubscriptionOptions.RegisterFailureEmptyPushSubscriptionOptions --PushMessagingIncognitoBrowserTest.IncognitoGetSubscriptionDoesNotHang +-RedirectTest.Client -RedirectTest.ClientEmptyReferer -RedirectTest.ClientServerServer -RedirectTest.Server @@ -406,7 +179,6 @@ -ReferrerPolicyTest.MiddleClickOrigin -ReferrerPolicyTest.MiddleClickRedirect -RepostFormWarningTest.TestDoubleReload --RepostFormWarningTest.TestLoginAfterRepost -RestartTest.Post -SafeBrowsingBlockingPageBrowserTestWithThreatType/SafeBrowsingBlockingPageBrowserTest.DontProceed/0 -SafeBrowsingBlockingPageBrowserTestWithThreatType/SafeBrowsingBlockingPageBrowserTest.DontProceed/1 @@ -420,15 +192,21 @@ -SafeBrowsingBlockingPageBrowserTestWithThreatType/SafeBrowsingBlockingPageBrowserTest.IframeDontProceed/0 -SafeBrowsingBlockingPageBrowserTestWithThreatType/SafeBrowsingBlockingPageBrowserTest.IframeDontProceed/1 -SafeBrowsingBlockingPageBrowserTestWithThreatType/SafeBrowsingBlockingPageBrowserTest.IframeDontProceed/2 --SafeBrowsingBlockingPageBrowserTestWithThreatType/SafeBrowsingBlockingPageBrowserTest.IframeOptInAndReportMalwareDetails/0 --SafeBrowsingBlockingPageBrowserTestWithThreatType/SafeBrowsingBlockingPageBrowserTest.IframeOptInAndReportMalwareDetails/1 --SafeBrowsingBlockingPageBrowserTestWithThreatType/SafeBrowsingBlockingPageBrowserTest.IframeOptInAndReportMalwareDetails/2 +-SafeBrowsingBlockingPageBrowserTestWithThreatType/SafeBrowsingBlockingPageBrowserTest.IframeOptInAndReportThreatDetails/0 +-SafeBrowsingBlockingPageBrowserTestWithThreatType/SafeBrowsingBlockingPageBrowserTest.IframeOptInAndReportThreatDetails/1 +-SafeBrowsingBlockingPageBrowserTestWithThreatType/SafeBrowsingBlockingPageBrowserTest.IframeOptInAndReportThreatDetails/2 -SafeBrowsingBlockingPageBrowserTestWithThreatType/SafeBrowsingBlockingPageBrowserTest.IframeProceed/0 -SafeBrowsingBlockingPageBrowserTestWithThreatType/SafeBrowsingBlockingPageBrowserTest.IframeProceed/1 -SafeBrowsingBlockingPageBrowserTestWithThreatType/SafeBrowsingBlockingPageBrowserTest.IframeProceed/2 -SafeBrowsingBlockingPageBrowserTestWithThreatType/SafeBrowsingBlockingPageBrowserTest.LearnMore/0 -SafeBrowsingBlockingPageBrowserTestWithThreatType/SafeBrowsingBlockingPageBrowserTest.LearnMore/1 -SafeBrowsingBlockingPageBrowserTestWithThreatType/SafeBrowsingBlockingPageBrowserTest.LearnMore/2 +-SafeBrowsingBlockingPageBrowserTestWithThreatType/SafeBrowsingBlockingPageBrowserTest.MainFrameBlockedShouldHaveNoDOMDetailsWhenDontProceed/0 +-SafeBrowsingBlockingPageBrowserTestWithThreatType/SafeBrowsingBlockingPageBrowserTest.MainFrameBlockedShouldHaveNoDOMDetailsWhenDontProceed/1 +-SafeBrowsingBlockingPageBrowserTestWithThreatType/SafeBrowsingBlockingPageBrowserTest.MainFrameBlockedShouldHaveNoDOMDetailsWhenDontProceed/2 +-SafeBrowsingBlockingPageBrowserTestWithThreatType/SafeBrowsingBlockingPageBrowserTest.MainFrameBlockedShouldHaveNoDOMDetailsWhenProceeding/0 +-SafeBrowsingBlockingPageBrowserTestWithThreatType/SafeBrowsingBlockingPageBrowserTest.MainFrameBlockedShouldHaveNoDOMDetailsWhenProceeding/1 +-SafeBrowsingBlockingPageBrowserTestWithThreatType/SafeBrowsingBlockingPageBrowserTest.MainFrameBlockedShouldHaveNoDOMDetailsWhenProceeding/2 -SafeBrowsingBlockingPageBrowserTestWithThreatType/SafeBrowsingBlockingPageBrowserTest.Proceed/0 -SafeBrowsingBlockingPageBrowserTestWithThreatType/SafeBrowsingBlockingPageBrowserTest.Proceed/1 -SafeBrowsingBlockingPageBrowserTestWithThreatType/SafeBrowsingBlockingPageBrowserTest.Proceed/2 @@ -453,85 +231,52 @@ -SafeBrowsingBlockingPageBrowserTestWithThreatType/SafeBrowsingBlockingPageBrowserTest.WhitelistUnsaved/0 -SafeBrowsingBlockingPageBrowserTestWithThreatType/SafeBrowsingBlockingPageBrowserTest.WhitelistUnsaved/1 -SafeBrowsingBlockingPageBrowserTestWithThreatType/SafeBrowsingBlockingPageBrowserTest.WhitelistUnsaved/2 +-SafeBrowsingServiceTest.MainFrameHitWithReferrer +-SafeBrowsingServiceTest.MalwareWithWhitelist -SafeBrowsingServiceTest.Prefetch --SearchProviderTest.TestIsSearchProviderInstalled +-SaveType/SavePageMultiFrameBrowserTest.AboutBlank/0 +-SaveType/SavePageMultiFrameBrowserTest.AboutBlank/1 +-SaveType/SavePageMultiFrameBrowserTest.CrossSite/1 +-SaveType/SavePageMultiFrameBrowserTest.NestedFrames/1 +-SaveType/SavePageMultiFrameBrowserTest.RuntimeChanges/1 +-SaveType/SavePageMultiFrameBrowserTest.Style/0 +-SaveType/SavePageMultiFrameBrowserTest.Style/1 +-ScriptContextTest.GetEffectiveDocumentURL -SecurityStateModelLoadingTest.NavigationStateChanges -SecurityStateModelTest.AddedTab --SecurityStateModelTest.BrokenHTTPS -SecurityStateModelTest.HttpsPage -SecurityStateModelTest.MixedContent -SecurityStateModelTest.MixedContentWithBrokenSHA1 -SecurityStateModelTest.SHA1Broken --ServiceWorkerTest.BackgroundPageIsWokenIfAsleep --ServiceWorkerTest.BackgroundPagePostsMessageToServiceWorker --ServiceWorkerTest.FetchArbitraryPaths --ServiceWorkerTest.GetBackgroundClientFailsWithNoBackgroundPage --ServiceWorkerTest.LoadingBackgroundPageBypassesServiceWorker --ServiceWorkerTest.RegisterSucceedsOnTrunk --ServiceWorkerTest.ServiceWorkerPostsMessageToBackgroundClient --ServiceWorkerTest.ServiceWorkerSuspensionOnExtensionUnload -SSLUITest.BadCertFollowedByGoodCert --SSLUITest.InterstitialNotAffectedByHideShow --SSLUITest.SSLStatusMatchesonClockInterstitialAndAfterProceed --SSLUITest.SSLStatusMatchesOnInterstitialAndAfterProceed -SSLUITest.TestBadFrameNavigation -SSLUITest.TestBadHTTPSDownload --SSLUITest.TestBrokenHTTPSMetricsReporting_DontProceed --SSLUITest.TestBrokenHTTPSMetricsReporting_Proceed --SSLUITest.TestBrokenHTTPSWithInsecureContent -SSLUITest.TestGoodFrameNavigation --SSLUITest.TestHTTPSErrorCausedByClock --SSLUITest.TestHTTPSErrorWithNoNavEntry -SSLUITest.TestHTTPSExpiredCertAndGoBackViaButton --SSLUITest.TestHTTPSExpiredCertAndGoBackViaMenu --SSLUITest.TestHTTPSExpiredCertAndGoForward --SSLUITest.TestInterstitialJavaScriptGoesBack --SSLUITest.TestRedirectBadToGoodHTTPS --SSLUITest.TestRefNavigation --SSLUITest.TestUnsafeContentsInWorkerWithUserException -SSLUITest.TestUnsafeContentsWithUserException --SSLUITest.TestWSSInvalidCertAndGoForward --SSLUITestIgnoreLocalhostCertErrors.TestNoInterstitialOnLocalhost -SSLUITestWithClientCert.TestWSSClientCert --SSLUITestWithExtendedReporting.TestBadClockReportingWithNoOptIn --SSLUITestWithExtendedReporting.TestBadClockReportingWithOptIn --SSLUITestWithExtendedReporting.TestBrokenHTTPSGoBackReporting --SSLUITestWithExtendedReporting.TestBrokenHTTPSGoBackShowYesCheckNoParamYesReportNo --SSLUITestWithExtendedReporting.TestBrokenHTTPSInIncognitoReportNo --SSLUITestWithExtendedReporting.TestBrokenHTTPSNoReportingWhenDisallowed --SSLUITestWithExtendedReporting.TestBrokenHTTPSProceedReporting --SSLUITestWithExtendedReporting.TestBrokenHTTPSProceedReportingWithNoOptIn -StreamsPrivateApiTest.Abort -StreamsPrivateApiTest.FileURL -StreamsPrivateApiTest.Headers -StreamsPrivateApiTest.Navigate -StreamsPrivateApiTest.NavigateCrossSite --StreamsPrivateApiTest.NavigateToAnAttachment --SupervisedUserBlockModeTest.HistoryVisitRecorded --SupervisedUserBlockModeTest.OpenBlockedURLInNewTab --SupervisedUserBlockModeTest.SendAccessRequestOnBlockedURL --SupervisedUserBlockModeTest.Unblock --SupervisedUserResourceThrottleTest.NoNavigationObserverBlock --SyncFileSystemTest.AuthorizationTest --TaskManagerBrowserTest.DevToolsNewDockedWindow --TaskManagerBrowserTest.DevToolsNewUndockedWindow --TaskManagerBrowserTest.DevToolsOldDockedWindow --TaskManagerBrowserTest.DevToolsOldUnockedWindow -TemplateURLScraperTest.ScrapeWithOnSubmit -UnloadTest.CrossSiteInfiniteBeforeUnloadAsync +-WebNavigationApiTest.ClientRedirect -WebNavigationApiTest.CrossProcess -WebNavigationApiTest.CrossProcessAbort -WebNavigationApiTest.CrossProcessFragment -WebNavigationApiTest.CrossProcessHistory +-WebNavigationApiTest.CrossProcessIframe -WebNavigationApiTest.Failures --WebNavigationApiTest.History +-WebNavigationApiTest.ForwardBack -WebNavigationApiTest.IFrame -WebNavigationApiTest.OpenTab -WebNavigationApiTest.RequestOpenTab -WebNavigationApiTest.ServerRedirect -WebNavigationApiTest.ServerRedirectSingleProcess --WebSocketBrowserTest.ReuseMainPageBasicAuthCredentialsForWebSocket --WebUIWebViewBrowserTest.DisplayNone +-WebNavigationApiTest.SrcDoc +-WebUIBrowserTest.ForceSwapOnDifferenteWebUITypes -WebViewPluginTest.TestLoadPluginInternalResource -WebViewTest.InterstitialTeardown -WebViewTest.InterstitialTeardownOnBrowserShutdown @@ -546,5 +291,4 @@ -WebViewTest.Shim_TestNestedSubframes -WebViewTest.Shim_TestWebRequestAPIErrorOccurred -WebViewTest.Shim_TestWebRequestAPIGoogleProperty --WebViewTest.Shim_TestWebRequestAPIWithHeaders --WorkerDevToolsSanityTest.InspectSharedWorker \ No newline at end of file +-WebViewTest.Shim_TestWebRequestAPIWithHeaders \ No newline at end of file
diff --git a/testing/buildbot/filters/browser-side-navigation.linux.content_browsertests.filter b/testing/buildbot/filters/browser-side-navigation.linux.content_browsertests.filter index a42f5f2c..a464b2f 100644 --- a/testing/buildbot/filters/browser-side-navigation.linux.content_browsertests.filter +++ b/testing/buildbot/filters/browser-side-navigation.linux.content_browsertests.filter
@@ -1,24 +1,21 @@ --BackgroundSyncBrowserTest.CallDoneAfterSyncFails --BackgroundSyncBrowserTest.CallDoneAfterSyncSuceeds --BackgroundSyncBrowserTest.CallDoneAfterSyncUnregistered --BackgroundSyncBrowserTest.CallDoneBeforeSyncFails --BackgroundSyncBrowserTest.CallDoneBeforeSyncSucceeds --BackgroundSyncBrowserTest.GetRegistrations --BackgroundSyncBrowserTest.Incognito --BackgroundSyncBrowserTest.OneShotDelaysForNetwork --BackgroundSyncBrowserTest.OneShotFires --BackgroundSyncBrowserTest.Unregister --BackgroundSyncBrowserTest.UnregisterMidSync --BackgroundSyncBrowserTest.UnregisterTwice --BackgroundSyncBrowserTest.WaitUntil --BackgroundSyncBrowserTest.WaitUntilReject +-BackgroundSyncBrowserTest.RegisterFromNonMainFrame +-BackgroundSyncBrowserTest.RegisterFromServiceWorkerWithoutMainFrameHost -CrossSiteRedirectorBrowserTest.VerifyCrossSiteRedirectURL -CrossSiteTransferTest.NoLeakOnCrossSiteCancel -CrossSiteTransferTest.ReplaceEntryCrossProcessThenTransfer -CrossSiteTransferTest.ReplaceEntryCrossProcessTwice -CrossSiteTransferTest.ReplaceEntryInProcessThenTranfers --DevToolsProtocolTest.NavigationPreservesMessages +-DevToolsProtocolTest.CrossSitePauseInBeforeUnload +-HostZoomMapImplBrowserTest.GetZoomForView_Host +-HostZoomMapImplBrowserTest.GetZoomForView_HostAndScheme +-LoFiResourceDispatcherHostBrowserTest.ShouldEnableLoFiModeNavigateBackThenForward +-LoFiResourceDispatcherHostBrowserTest.ShouldEnableLoFiModeOff +-LoFiResourceDispatcherHostBrowserTest.ShouldEnableLoFiModeOn +-LoFiResourceDispatcherHostBrowserTest.ShouldEnableLoFiModeReload +-LoFiResourceDispatcherHostBrowserTest.ShouldEnableLoFiModeReloadDisableLoFi -NavigationControllerBrowserTest.CorrectLengthWithCurrentItemReplacement +-NavigationControllerBrowserTest.FrameNavigationEntry_RecreatedSubframeBackForward +-NavigationControllerBrowserTest.FrameNavigationEntry_RestoreViaPageState -NavigationControllerBrowserTest.FrameNavigationEntry_SubframeBackForward -NavigationControllerBrowserTest.NavigationTypeClassification_ClientSideRedirect -NavigationControllerBrowserTest.NavigationTypeClassification_EmptyGURL @@ -28,25 +25,24 @@ -NavigationControllerBrowserTest.PreventSpoofFromSubframeAndReplace -NavigationControllerBrowserTest.ReloadOriginalRequest -NavigationControllerBrowserTest.StopCausesFailureDespiteJavaScriptURL --RendererAccessibilityTest.AccessibilityMessagesQueueWhileSwappedOut +-RenderFrameHostManagerTest.ConsecutiveNavigationsToSite +-RenderFrameHostManagerTest.PopupPendingAndBackToSameSiteInstance +-RenderFrameHostManagerTest.RestoreSubframeFileAccessForHistoryNavigation +-RenderViewImplTest.BrowserNavigationStartNotUsedForHistoryNavigation -RenderViewImplTest.DecideNavigationPolicy -RenderViewImplTest.GetCompositionCharacterBoundsTest -RenderViewImplTest.OnNavigationHttpPost --RenderViewImplTest.ReloadWhileSwappedOut -RenderViewImplTest.TestBackForward --ServiceWorkerBrowserTest.CrossSiteTransfer --ServiceWorkerBrowserTest.ImportsBustMemcache --ServiceWorkerBrowserTest.Reload --ServiceWorkerBrowserTest.ResponseFromHTTPServiceWorkerIsNotMarkedAsSecure --ServiceWorkerBrowserTest.ResponseFromHTTPSServiceWorkerIsMarkedAsSecure +-ResourceDispatcherHostBrowserTest.PageTransitionClientRedirect -SessionHistoryTest.CrossFrameFormBackForward -SessionHistoryTest.FrameBackForward -SessionHistoryTest.FrameFormBackForward -SessionHistoryTest.LocationChangeInSubframe +-SitePerProcessBrowserTest.DynamicWindowName -SitePerProcessBrowserTest.NewRenderFrameProxyPreservesOpener -SitePerProcessBrowserTest.OpenPopupWithRemoteParent -SitePerProcessBrowserTest.RenderViewHostPendingDeletionIsNotReused +-SitePerProcessBrowserTest.SubframePendingAndBackToSameSiteInstance -WebContentsImplBrowserTest.ClearNonVisiblePendingOnFail -WebContentsViewAuraTest.OverscrollScreenshot --WebContentsViewAuraTest.WebContentsViewReparent -WebUIMojoTest.EndToEndPing \ No newline at end of file
diff --git a/testing/buildbot/filters/browser-side-navigation.linux.content_unittests.filter b/testing/buildbot/filters/browser-side-navigation.linux.content_unittests.filter index fa3e82e..55a7b9d 100644 --- a/testing/buildbot/filters/browser-side-navigation.linux.content_unittests.filter +++ b/testing/buildbot/filters/browser-side-navigation.linux.content_unittests.filter
@@ -1,4 +1,9 @@ -NavigationControllerTest.LoadURL_RedirectAbortDoesntShowPendingURL +-RenderFrameHostManagerTest.RestoreNavigationToWebUI +-RenderFrameHostManagerTest.SimultaneousNavigationWithOneWebUI1 +-RenderFrameHostManagerTest.SimultaneousNavigationWithOneWebUI2 +-RenderFrameHostManagerTest.SimultaneousNavigationWithTwoWebUIs1 +-RenderFrameHostManagerTest.SimultaneousNavigationWithTwoWebUIs2 -ResourceDispatcherHostTest.CancelRequestsForContext -ResourceDispatcherHostTest.CancelRequestsForContextTransferred -ResourceDispatcherHostTest.ForbiddenDownload @@ -8,4 +13,5 @@ -WebContentsImplTest.CrossSiteNavigationBackPreempted -WebContentsImplTest.CrossSiteNotPreemptedDuringBeforeUnload -WebContentsImplTest.FindOpenerRVHWhenPending --WebContentsImplTest.NoEarlyStop \ No newline at end of file +-WebContentsImplTest.NoEarlyStop +-WebContentsImplTestWithSiteIsolation.StartStopEventsBalance \ No newline at end of file
diff --git a/testing/buildbot/filters/browser-side-navigation.linux.unit_tests.filter b/testing/buildbot/filters/browser-side-navigation.linux.unit_tests.filter index 3b0f46c..137c8f3d 100644 --- a/testing/buildbot/filters/browser-side-navigation.linux.unit_tests.filter +++ b/testing/buildbot/filters/browser-side-navigation.linux.unit_tests.filter
@@ -1,95 +1,11 @@ --AppInfoDialogViewsTest.ViewInStore --BookmarkInstantExtendedTest.DetachedBookmarkBarOnNTP --BookmarkTest.DetachedBookmarkBarOnCustomNTP -BookmarkTest.DetachedBookmarkBarOnNTP -BrowserBookmarkBarTest.StateOnActiveTabChanged --BrowserCommandsTest.BackForwardInNewTab --BrowserCommandsTest.BookmarkCurrentPage --BrowserCommandsTest.DuplicateTab --BrowserCommandsTest.OnDefaultZoomLevelChanged --BrowserCommandsTest.OnMaxZoomIn --BrowserCommandsTest.OnMaxZoomOut --BrowserCommandsTest.OnZoomChangedForActiveTab --BrowserCommandsTest.OnZoomLevelChanged --BrowserCommandsTest.OnZoomReset --BrowserCommandsTest.ViewSource -BrowserInstantControllerTest.DefaultSearchProviderChanged -BrowserInstantControllerTest.GoogleBaseURLUpdated --BrowserListTest.TabContentsIteratorVerifyBrowser --BrowserListTest.TabContentsIteratorVerifyCount --BrowserProcessPowerTest.IncognitoDoesntRecordPowerUsage --BrowserProcessPowerTest.MultipleProfilesRecordSeparately --BrowserProcessPowerTest.MultipleSites --BrowserProcessPowerTest.OneSite -BrowserViewTest.BrowserViewLayout --ChromeContentBrowserClientWindowTest.OpenURL --ChromeLauncherControllerTest.AppPanels --ChromeLauncherControllerTest.BrowserMenuGeneration --ChromeLauncherControllerTest.GmailMatching --ChromeLauncherControllerTest.GmailOfflineMatching --ChromeLauncherControllerTest.PersistLauncherItemPositions --ChromeLauncherControllerTest.PersistPinned --ChromeLauncherControllerTest.V1AppMenuDeletionExecution --ChromeLauncherControllerTest.V1AppMenuExecution --ChromeLauncherControllerTest.V1AppMenuGeneration --DeclarativeContentIsBookmarkedConditionTrackerTest.AddAndRemoveBookmark --DeclarativeContentIsBookmarkedConditionTrackerTest.BookmarkedAtStartOfTracking --DeclarativeContentIsBookmarkedConditionTrackerTest.ExtensiveChanges --DeclarativeContentIsBookmarkedConditionTrackerTest.Navigation --DeclarativeContentPageUrlConditionTrackerTest.AddAndRemovePredicates --DeclarativeContentPageUrlConditionTrackerTest.NotifyWebContentsNavigation --DeclarativeContentPageUrlConditionTrackerTest.TrackWebContents --InstantNTPURLRewriteTest.UberURLHandler_InstantExtendedNewTabPage --InstantSearchPrerendererTest.CancelPendingPrerenderRequest --InstantSearchPrerendererTest.CancelPrerenderRequest_EmptySearchQueryCommitted --InstantSearchPrerendererTest.CancelPrerenderRequest_UnsupportedDispositions --InstantSearchPrerendererTest.CancelPrerenderRequestOnTabChangeEvent --InstantSearchPrerendererTest.CanCommitQuery --InstantSearchPrerendererTest.CommitQuery --InstantSearchPrerendererTest.DoNotPrefetchSearchResults --InstantSearchPrerendererTest.PrefetchSearchResults +-ExtensionContextMenuModelTest.TestPageAccessSubmenu -InstantSearchPrerendererTest.PrerenderingAllowed --InstantSearchPrerendererTest.PrerenderRequestCancelled --InstantSearchPrerendererTest.UsePrerenderedPage_SearchQueryMistmatch --InstantSearchPrerendererTest.UsePrerenderPage --MediaRouterActionUnitTest.IconPressedState --MediaRouterDialogControllerImplTest.CloseDialogFromDialogController --MediaRouterDialogControllerImplTest.CloseDialogFromWebUI --MediaRouterDialogControllerImplTest.CloseInitiator --MediaRouterDialogControllerImplTest.MultipleMediaRouterDialogs --MediaRouterDialogControllerImplTest.ShowMediaRouterDialog --MediaRouterWebUIMessageHandlerTest.OnCreateRouteResponseReceived --MediaRouterWebUIMessageHandlerTest.UpdateIssue --MediaRouterWebUIMessageHandlerTest.UpdateRoutes --MediaRouterWebUIMessageHandlerTest.UpdateSinks --PinnedTabCodecTest.NoPinnedTabs --PinnedTabCodecTest.PinnedAndNonPinned --PinnedTabServiceTest.Popup -PopupToolbarModelTest.ShouldDisplayURL --PrintPreviewDialogControllerUnitTest.ClearInitiatorDetails --PrintPreviewDialogControllerUnitTest.GetOrCreatePreviewDialog --PrintPreviewDialogControllerUnitTest.MultiplePreviewDialogs --PrintPreviewUIUnitTest.GetCurrentPrintPreviewStatus --PrintPreviewUIUnitTest.PrintPreviewData --PrintPreviewUIUnitTest.PrintPreviewDraftPages --RecentTabsSubMenuModelTest.RecentlyClosedTabsAndWindowsFromLastSession --RecentTabsSubMenuModelTest.RecentlyClosedTabsFromCurrentSession --ReuseInstantSearchBasePageTest.CanCommitQuery --ReuseInstantSearchBasePageTest.CanCommitQuery_InstantSearchBasePageLoadInProgress --SearchDelegateTest.SearchModel --SearchIPCRouterPolicyTest.AppropriateMessagesSentToIncognitoPages --SearchIPCRouterPolicyTest.DoNotProcessChromeIdentityCheck --SearchIPCRouterPolicyTest.DoNotProcessFocusOmnibox --SearchIPCRouterPolicyTest.DoNotProcessHistorySyncCheck --SearchIPCRouterPolicyTest.DoNotProcessLogEvent --SearchIPCRouterPolicyTest.DoNotProcessMessagesForInactiveTab --SearchIPCRouterPolicyTest.DoNotProcessMessagesForIncognitoPage --SearchIPCRouterPolicyTest.DoNotProcessNavigateToURL --SearchIPCRouterPolicyTest.DoNotProcessPasteIntoOmniboxMsg --SearchIPCRouterPolicyTest.DoNotSendMostVisitedItems --SearchIPCRouterPolicyTest.DoNotSendSetMessagesForIncognitoPage --SearchIPCRouterPolicyTest.DoNotSendSetPromoInformation --SearchIPCRouterPolicyTest.DoNotSendThemeBackgroundInfo -SearchIPCRouterPolicyTest.ProcessChromeIdentityCheck -SearchIPCRouterPolicyTest.ProcessDeleteMostVisitedItem -SearchIPCRouterPolicyTest.ProcessFocusOmnibox @@ -99,38 +15,18 @@ -SearchIPCRouterPolicyTest.ProcessPasteIntoOmniboxMsg -SearchIPCRouterPolicyTest.ProcessUndoAllMostVisitedDeletions -SearchIPCRouterPolicyTest.ProcessUndoMostVisitedDeletion --SearchIPCRouterPolicyTest.ProcessVoiceSearchSupportMsg -SearchIPCRouterPolicyTest.SendMostVisitedItems --SearchIPCRouterPolicyTest.SendSetDisplayInstantResults --SearchIPCRouterPolicyTest.SendSetOmniboxStartMargin -SearchIPCRouterPolicyTest.SendSetPromoInformation --SearchIPCRouterPolicyTest.SendSetSuggestionToPrefetch -SearchIPCRouterPolicyTest.SendThemeBackgroundInfo --SearchIPCRouterPolicyTest.SendToggleVoiceSearch --SearchIPCRouterPolicyTest.SubmitQuery --SearchIPCRouterTest.DoNotSendMostVisitedItemsMsg --SearchIPCRouterTest.DoNotSendOmniboxFocusChange --SearchIPCRouterTest.DoNotSendSetDisplayInstantResultsMsg --SearchIPCRouterTest.DoNotSendSetInputInProgress --SearchIPCRouterTest.DoNotSendSetOmniboxStartMargin --SearchIPCRouterTest.DoNotSendSetPromoInformationMsg --SearchIPCRouterTest.DoNotSendSetSuggestionToPrefetch --SearchIPCRouterTest.DoNotSendSubmitMsg --SearchIPCRouterTest.DoNotSendThemeBackgroundInfoMsg --SearchIPCRouterTest.DoNotSendToggleVoiceSearch --SearchIPCRouterTest.HandleTabChangedEvents -SearchIPCRouterTest.IgnoreChromeIdentityCheckMsg -SearchIPCRouterTest.IgnoreDeleteMostVisitedItemMsg -SearchIPCRouterTest.IgnoreFocusOmniboxMsg -SearchIPCRouterTest.IgnoreHistorySyncCheckMsg -SearchIPCRouterTest.IgnoreLogEventMsg --SearchIPCRouterTest.IgnoreMessageIfThePageIsNotActive --SearchIPCRouterTest.IgnoreMessagesFromNonInstantRenderers -SearchIPCRouterTest.IgnoreNavigateToURLMsg -SearchIPCRouterTest.IgnorePasteAndOpenDropdownMsg -SearchIPCRouterTest.IgnoreUndoAllMostVisitedDeletionsMsg -SearchIPCRouterTest.IgnoreUndoMostVisitedDeletionMsg --SearchIPCRouterTest.IgnoreVoiceSearchSupportMsg -SearchIPCRouterTest.ProcessChromeIdentityCheckMsg -SearchIPCRouterTest.ProcessDeleteMostVisitedItemMsg -SearchIPCRouterTest.ProcessFocusOmniboxMsg @@ -142,46 +38,13 @@ -SearchIPCRouterTest.ProcessPasteAndOpenDropdownMsg -SearchIPCRouterTest.ProcessUndoAllMostVisitedDeletionsMsg -SearchIPCRouterTest.ProcessUndoMostVisitedDeletionMsg --SearchIPCRouterTest.ProcessVoiceSearchSupportMsg --SearchIPCRouterTest.SendMostVisitedItemsMsg --SearchIPCRouterTest.SendOmniboxFocusChange -SearchIPCRouterTest.SendSetDisplayInstantResultsMsg_DisableInstantOnResultsPage --SearchIPCRouterTest.SendSetDisplayInstantResultsMsg_EnableInstantOnResultsPage --SearchIPCRouterTest.SendSetDisplayInstantResultsMsg_EnableInstantOutsideSearchResultsPage --SearchIPCRouterTest.SendSetInputInProgress --SearchIPCRouterTest.SendSetOmniboxStartMargin --SearchIPCRouterTest.SendSetPromoInformationMsg --SearchIPCRouterTest.SendSetSuggestionToPrefetch --SearchIPCRouterTest.SendSubmitMsg --SearchIPCRouterTest.SendThemeBackgroundInfoMsg --SearchIPCRouterTest.SendToggleVoiceSearch --SearchIPCRouterTest.SpuriousMessageTypesIgnored --SearchTabHelperPrerenderTest.OnOmniboxFocusPrerenderInstantURL --SearchTabHelperPrerenderTest.OnTabActivatedNoPrerenderIfOmniboxBlurred --SearchTabHelperPrerenderTest.OnTabActivatedPrerenderInstantURL -SearchTest.InstantCacheableNTPNavigationEntry -SearchTest.InstantCacheableNTPNavigationEntryNewProfile -SearchTest.InstantNTPCustomNavigationEntry -SearchTest.InstantNTPExtendedEnabled -SearchTest.ProcessIsolation -SearchTest.ProcessIsolation_RendererInitiated --SessionCrashedInfoBarDelegateUnitTest.DetachingTabWithCrashedInfoBar -SessionsSyncManagerTest.AssociateWindowsDontReloadTabs --SessionsSyncManagerTest.CheckPrerenderedWebContentsSwap --SessionsSyncManagerTest.MergeLocalSessionExistingTabs --SessionsSyncManagerTest.MergeWithLocalAndForeignTabs --SessionsSyncManagerTest.OnLocalTabModified --SessionsSyncManagerTest.ProcessRemoteDeleteOfLocalSession --SessionsSyncManagerTest.SwappedOutOnRestore --SessionsSyncManagerTest.UpdatesAfterMixedMerge --SiteEngagementServiceTest.NavigationAccumulation --SiteEngagementServiceTest.ScoreIncrementsOnPageRequest --TabMenuModelTest.Basics --TestUsePrerenderPage.DoNotUsePrerenderPage --TestUsePrerenderPage.ExtractSearchTermsAndUsePrerenderPage --TestUsePrerenderPage.SetEmbeddedSearchRequestParams --ToolbarActionsBarRedesignUnitTest.ExtensionActionWantsToRunAppearance --ToolbarActionsBarUnitTest.ExtensionActionNormalAppearance -ToolbarModelTest.GoogleBaseURL --ToolbarModelTest.SearchTermsWhileLoading -ToolbarModelTest.ShouldDisplayURL_QueryExtraction \ No newline at end of file
diff --git a/testing/buildbot/filters/site-per-process.browser_tests.filter b/testing/buildbot/filters/site-per-process.browser_tests.filter index 0c1d85e..70ca6ac 100644 --- a/testing/buildbot/filters/site-per-process.browser_tests.filter +++ b/testing/buildbot/filters/site-per-process.browser_tests.filter
@@ -1,17 +1,10 @@ +# crbug.com/417518: Get tests working with --site-per-process -AllUrlsApiTest.WhitelistedExtension -BrowserNavigatorTest.NavigateFromNTPToOptionsInSameTab -BrowserTest.OtherRedirectsDontForkProcess --BrowserTest.WindowOpenClose -ChromeRenderProcessHostTest.* -ChromeRenderProcessHostTestWithCommandLine.* -ErrorPageTest.* --ExtensionApiTest.Tabs2 --ExtensionApiTest.TabMove --ExtensionApiTest.TabsOnUpdated --ExtensionURLRewriteBrowserTest.NewTabPageURL --IsolatedAppTest.* --PhishingClassifierDelegateTest.* --PhishingDOMFeatureExtractorTest.SubFrames -PolicyTest.HomepageLocation -PrerenderBrowserTest.* -ProcessManagementTest.* @@ -24,3 +17,20 @@ -WebNavigationApiTest.ServerRedirectSingleProcess -WebNavigationApiTest.CrossProcessHistory -WebRtcBrowserTest.RunsAudioVideoWebRTCCallInTwoTabs + +# crbug.com/467126: BrowserTest.WindowOpenClose is flaky in --site-per-process +# mode: +-BrowserTest.WindowOpenClose + +# crbug.com/448592: Get extension browsertests to pass in --site-per-process +# mode: +-ExtensionApiTest.Tabs2 +-ExtensionApiTest.TabMove +-ExtensionApiTest.TabsOnUpdated +-ExtensionURLRewriteBrowserTest.NewTabPageURL +-IsolatedAppTest.* + +# crbug.com/568710: Some PhishingClassifierDelegateTest are not compatible +# with out-of-process iframes: +-PhishingClassifierDelegateTest.* +-PhishingDOMFeatureExtractorTest.SubFrames
diff --git a/testing/buildbot/filters/site-per-process.content_browsertests.filter b/testing/buildbot/filters/site-per-process.content_browsertests.filter index dc252a55..8313298 100644 --- a/testing/buildbot/filters/site-per-process.content_browsertests.filter +++ b/testing/buildbot/filters/site-per-process.content_browsertests.filter
@@ -1,3 +1,4 @@ +# crbug.com/417518: Get tests working with --site-per-process -SessionHistoryTest.FrameBackForward -NavigationControllerBrowserTest.ReloadOriginalRequest -*.RestoreSubframeFileAccessForHistoryNavigation
diff --git a/testing/variations/fieldtrial_testing_config_android.json b/testing/variations/fieldtrial_testing_config_android.json index 0311a74..2ab0706ac 100644 --- a/testing/variations/fieldtrial_testing_config_android.json +++ b/testing/variations/fieldtrial_testing_config_android.json
@@ -40,6 +40,11 @@ } } ], + "CreditCardScan": [ + { + "group_name": "Enabled" + } + ], "CustomTabs": [ { "group_name": "Enabled"
diff --git a/testing/variations/fieldtrial_testing_config_mac.json b/testing/variations/fieldtrial_testing_config_mac.json index f7502fe..3e9b883 100644 --- a/testing/variations/fieldtrial_testing_config_mac.json +++ b/testing/variations/fieldtrial_testing_config_mac.json
@@ -19,6 +19,9 @@ ], "AutomaticTabDiscarding": [ { + "enable_features": [ + "AutomaticTabDiscarding" + ], "group_name": "Enabled_Once" } ],
diff --git a/testing/variations/fieldtrial_testing_config_win.json b/testing/variations/fieldtrial_testing_config_win.json index 78a53ee8..b3f36c5 100644 --- a/testing/variations/fieldtrial_testing_config_win.json +++ b/testing/variations/fieldtrial_testing_config_win.json
@@ -24,6 +24,9 @@ ], "AutomaticTabDiscarding": [ { + "enable_features": [ + "AutomaticTabDiscarding" + ], "group_name": "Enabled_Once" } ],
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/OffScreenCanvas-constructor-in-worker-expected.txt b/third_party/WebKit/LayoutTests/fast/canvas/OffScreenCanvas-constructor-in-worker-expected.txt new file mode 100644 index 0000000..fe62ed5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/canvas/OffScreenCanvas-constructor-in-worker-expected.txt
@@ -0,0 +1,13 @@ +Tests that the OffScreenCanvas can be constructed on a worker thread. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS width is 50 +PASS height is 50 +PASS width is 100 +PASS height is 100 +PASS successfullyParsed is true + +TEST COMPLETE +
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/OffScreenCanvas-constructor-in-worker.html b/third_party/WebKit/LayoutTests/fast/canvas/OffScreenCanvas-constructor-in-worker.html new file mode 100644 index 0000000..01df0f46 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/canvas/OffScreenCanvas-constructor-in-worker.html
@@ -0,0 +1,53 @@ +<!DOCTYPE html> +<html> +<script src="../../resources/js-test.js"></script> +<body> +<script id="myWorker" type="text/worker"> +self.onmessage = function(e) { + var aCanvas = new OffScreenCanvas(50, 50); + self.postMessage({version:'first', width:aCanvas.width, height:aCanvas.height}); + + aCanvas.width = 100; + aCanvas.height = 100; + self.postMessage({version:'second', width:aCanvas.width, height:aCanvas.height}); +}; +</script> + +<script> +jsTestIsAsync = true; +description("Tests that the OffScreenCanvas can be constructed on a worker thread."); + +var width; +var height; + +function makeWorker(script) { + var blob = new Blob([script]); + return new Worker(URL.createObjectURL(blob)); +} + +function handleMessageFromWorker(msg) { + width = msg.data.width; + height = msg.data.height; + switch (msg.data.version) { + case 'first': + shouldBe('width', '50'); + shouldBe('height', '50'); + break; + case 'second': + shouldBe('width', '100'); + shouldBe('height', '100'); + finishJSTest(); + break; + default: + testFailed("Unexpected failure"); + break; + } +} + +var worker = makeWorker(document.getElementById('myWorker').textContent); +worker.addEventListener('message', handleMessageFromWorker); +worker.postMessage(""); +</script> + +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/OffScreenCanvas-invalid-args-in-worker-expected.txt b/third_party/WebKit/LayoutTests/fast/canvas/OffScreenCanvas-invalid-args-in-worker-expected.txt new file mode 100644 index 0000000..b6f502f --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/canvas/OffScreenCanvas-invalid-args-in-worker-expected.txt
@@ -0,0 +1,13 @@ +Tests that the OffScreenCanvas can handle invalid arguments on a worker + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS width is setWidth-1 +PASS height is setHeight-1 +PASS width is 0 +PASS height is 0 +PASS successfullyParsed is true + +TEST COMPLETE +
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/OffScreenCanvas-invalid-args-in-worker.html b/third_party/WebKit/LayoutTests/fast/canvas/OffScreenCanvas-invalid-args-in-worker.html new file mode 100644 index 0000000..ed55063 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/canvas/OffScreenCanvas-invalid-args-in-worker.html
@@ -0,0 +1,57 @@ +<!DOCTYPE html> +<html> +<script src="../../resources/js-test.js"></script> +<body> +<script id="myWorker" type="text/worker"> +var setWidth = Math.pow(2, 31); +var setHeight = Math.pow(2, 31); + +self.onmessage = function(e) { + var canvas1 = new OffScreenCanvas(setWidth, setHeight); + self.postMessage({version:'canvas1', width:canvas1.width, height:canvas1.height}); + + var canvas2 = new OffScreenCanvas(null, null); + self.postMessage({version:'canvas2', width:canvas2.width, height:canvas2.height}); +}; +</script> + +<script> +jsTestIsAsync = true; +description("Tests that the OffScreenCanvas can handle invalid arguments on a worker"); + +var width; +var height; +var setWidth = Math.pow(2, 31); +var setHeight = Math.pow(2, 31); + +function makeWorker(script) { + var blob = new Blob([script]); + return new Worker(URL.createObjectURL(blob)); +} + +function handleMessageFromWorker(msg) { + width = msg.data.width; + height = msg.data.height; + switch (msg.data.version) { + case 'canvas1': + shouldBe('width', 'setWidth-1'); + shouldBe('height', 'setHeight-1'); + break; + case 'canvas2': + shouldBe('width', '0'); + shouldBe('height', '0'); + finishJSTest(); + break; + default: + testFailed("Unexpected failure"); + break; + } +} + +var worker = makeWorker(document.getElementById('myWorker').textContent); +worker.addEventListener('message', handleMessageFromWorker); +worker.postMessage(""); +</script> + +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/subresourceIntegrity/subresource-integrity-load-regular-script-after-failed-integrity.html b/third_party/WebKit/LayoutTests/http/tests/security/subresourceIntegrity/subresource-integrity-load-regular-script-after-failed-integrity.html new file mode 100644 index 0000000..1e3584b --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/security/subresourceIntegrity/subresource-integrity-load-regular-script-after-failed-integrity.html
@@ -0,0 +1,32 @@ +<!DOCTYPE html> +<html> + <head> + <!-- Regression test for https://crbug.com/570340 --> + <title>Script loaded after failed integrity check should still load</title> + </head> + <body> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script> + var should_fail_test = async_test('should fail'); + var should_succeed_test = async_test('should succeed'); + + function should_fail(loaded) { + should_fail_test.step(function() { + if (loaded) + assert_unreached(); + else + this.done(); + }); + } + + function success() { + should_succeed_test.step(function() { + this.done(); + }); + } + </script> + <script onerror="should_fail(false);" onload="should_fail(true);" src="resources/simple-result.js" integrity="sha256-deadbeef"></script> + <script onerror="assert_unreached();" src="call-success.js"></script> + </body> +</html>
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 26a4cd0ff..25ff8ef 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
@@ -453,6 +453,12 @@ getter action getter notification method constructor +interface OffScreenCanvas + getter height + getter width + method constructor + setter height + setter width interface PerformanceObserverEntryList method constructor method getEntries
diff --git a/third_party/WebKit/LayoutTests/svg/filters/feImage-remove-duplicate-id-no-crash-expected.txt b/third_party/WebKit/LayoutTests/svg/filters/feImage-remove-duplicate-id-no-crash-expected.txt new file mode 100644 index 0000000..6948cb3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/svg/filters/feImage-remove-duplicate-id-no-crash-expected.txt
@@ -0,0 +1 @@ +PASS: Removing svg element contain duplicate IDs do not trigger a crash.
diff --git a/third_party/WebKit/LayoutTests/svg/filters/feImage-remove-duplicate-id-no-crash.html b/third_party/WebKit/LayoutTests/svg/filters/feImage-remove-duplicate-id-no-crash.html new file mode 100644 index 0000000..1a1c736 --- /dev/null +++ b/third_party/WebKit/LayoutTests/svg/filters/feImage-remove-duplicate-id-no-crash.html
@@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<body> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<use id="A"></use> +<use id="A"><feimage xlink:href="#A"</svg> +<script> +if (window.testRunner) + testRunner.dumpAsText(); +var svg = document.querySelector("svg"); +document.body.removeChild(svg); +</script> +<p>PASS: Removing svg element contain duplicate IDs do not trigger a crash.</p> +</body> +</html>
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 3b723f5c..86a17e14 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
@@ -435,6 +435,12 @@ [Worker] setter onclose [Worker] setter onerror [Worker] setter onshow +[Worker] interface OffScreenCanvas +[Worker] getter height +[Worker] getter width +[Worker] method constructor +[Worker] setter height +[Worker] setter width [Worker] interface PerformanceObserverEntryList [Worker] method constructor [Worker] method getEntries
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 6727997..e4383977 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
@@ -425,6 +425,12 @@ [Worker] setter onclose [Worker] setter onerror [Worker] setter onshow +[Worker] interface OffScreenCanvas +[Worker] getter height +[Worker] getter width +[Worker] method constructor +[Worker] setter height +[Worker] setter width [Worker] interface PerformanceObserverEntryList [Worker] method constructor [Worker] method getEntries
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.cpp b/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.cpp index 50e98e4..055380e 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.cpp
@@ -56,6 +56,7 @@ static void useCounterCallback(v8::Isolate* isolate, v8::Isolate::UseCounterFeature feature) { UseCounter::Feature blinkFeature; + bool deprecated = false; switch (feature) { case v8::Isolate::kUseAsm: blinkFeature = UseCounter::UseAsm; @@ -68,6 +69,7 @@ break; case v8::Isolate::kObjectObserve: blinkFeature = UseCounter::ObjectObserve; + deprecated = true; break; case v8::Isolate::kSloppyMode: blinkFeature = UseCounter::V8SloppyMode; @@ -89,7 +91,10 @@ // does not know about. It's harmless. return; } - UseCounter::count(callingExecutionContext(isolate), blinkFeature); + if (deprecated) + UseCounter::countDeprecation(callingExecutionContext(isolate), blinkFeature); + else + UseCounter::count(callingExecutionContext(isolate), blinkFeature); } V8PerIsolateData::V8PerIsolateData()
diff --git a/third_party/WebKit/Source/core/animation/SVGPathInterpolationType.cpp b/third_party/WebKit/Source/core/animation/SVGPathInterpolationType.cpp index e44c6f4..9525f660 100644 --- a/third_party/WebKit/Source/core/animation/SVGPathInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/SVGPathInterpolationType.cpp
@@ -157,7 +157,7 @@ PassRefPtrWillBeRawPtr<SVGPropertyBase> SVGPathInterpolationType::appliedSVGValue(const InterpolableValue& interpolableValue, const NonInterpolableValue* nonInterpolableValue) const { - OwnPtr<SVGPathByteStream> pathByteStream = SVGPathByteStream::create(); + RefPtr<SVGPathByteStream> pathByteStream = SVGPathByteStream::create(); InterpolatedSVGPathSource source( toInterpolableList(*toInterpolableList(interpolableValue).get(PathArgsIndex)), toSVGPathNonInterpolableValue(nonInterpolableValue)->pathSegTypes());
diff --git a/third_party/WebKit/Source/core/animation/animatable/AnimatablePath.cpp b/third_party/WebKit/Source/core/animation/animatable/AnimatablePath.cpp index 95bf245b..21f06be 100644 --- a/third_party/WebKit/Source/core/animation/animatable/AnimatablePath.cpp +++ b/third_party/WebKit/Source/core/animation/animatable/AnimatablePath.cpp
@@ -7,7 +7,6 @@ #include "core/svg/SVGPathBlender.h" #include "core/svg/SVGPathByteStreamBuilder.h" #include "core/svg/SVGPathByteStreamSource.h" -#include "core/svg/SVGPathUtilities.h" namespace blink { @@ -16,8 +15,8 @@ // Default interpolation is used if the paths have different lengths, // or the paths have a segment with different types (ignoring "relativeness"). - SVGPathByteStreamSource fromSource(pathValue()->byteStream()); - SVGPathByteStreamSource toSource(toAnimatablePath(value)->pathValue()->byteStream()); + SVGPathByteStreamSource fromSource(path()->byteStream()); + SVGPathByteStreamSource toSource(toAnimatablePath(value)->path()->byteStream()); while (fromSource.hasMoreData()) { if (!toSource.hasMoreData()) @@ -40,21 +39,26 @@ if (usesDefaultInterpolationWith(value)) return defaultInterpolateTo(this, value, fraction); - OwnPtr<SVGPathByteStream> byteStream = SVGPathByteStream::create(); + RefPtr<SVGPathByteStream> byteStream = SVGPathByteStream::create(); SVGPathByteStreamBuilder builder(*byteStream); - SVGPathByteStreamSource fromSource(pathValue()->byteStream()); - SVGPathByteStreamSource toSource(toAnimatablePath(value)->pathValue()->byteStream()); + SVGPathByteStreamSource fromSource(path()->byteStream()); + SVGPathByteStreamSource toSource(toAnimatablePath(value)->path()->byteStream()); SVGPathBlender blender(&fromSource, &toSource, &builder); bool ok = blender.blendAnimatedPath(fraction); ASSERT_UNUSED(ok, ok); - return AnimatablePath::create(CSSPathValue::create(byteStream.release())); + return AnimatablePath::create(StylePath::create(byteStream.release())); +} + +StylePath* AnimatablePath::path() const +{ + return m_path.get(); } bool AnimatablePath::equalTo(const AnimatableValue* value) const { - return pathValue()->equals(*toAnimatablePath(value)->pathValue()); + return m_path->equals(*toAnimatablePath(value)->path()); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/animation/animatable/AnimatablePath.h b/third_party/WebKit/Source/core/animation/animatable/AnimatablePath.h index 27c38a6..1608b38 100644 --- a/third_party/WebKit/Source/core/animation/animatable/AnimatablePath.h +++ b/third_party/WebKit/Source/core/animation/animatable/AnimatablePath.h
@@ -7,33 +7,33 @@ #include "core/CoreExport.h" #include "core/animation/animatable/AnimatableValue.h" -#include "core/css/CSSPathValue.h" +#include "core/style/StylePath.h" namespace blink { class CORE_EXPORT AnimatablePath final : public AnimatableValue { public: ~AnimatablePath() override { } - static PassRefPtr<AnimatablePath> create(PassRefPtrWillBeRawPtr<CSSPathValue> pathValue) + static PassRefPtr<AnimatablePath> create(PassRefPtr<StylePath> path) { - return adoptRef(new AnimatablePath(pathValue)); + return adoptRef(new AnimatablePath(path)); } - CSSPathValue* pathValue() const { return m_pathValue.get(); } + StylePath* path() const; protected: PassRefPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const override; bool usesDefaultInterpolationWith(const AnimatableValue*) const override; private: - explicit AnimatablePath(PassRefPtrWillBeRawPtr<CSSPathValue> pathValue) - : m_pathValue(pathValue) + explicit AnimatablePath(PassRefPtr<StylePath> path) + : m_path(path) { - ASSERT(m_pathValue); + ASSERT(m_path); } AnimatableType type() const override { return TypePath; } bool equalTo(const AnimatableValue*) const override; - const RefPtrWillBePersistent<CSSPathValue> m_pathValue; + const RefPtr<StylePath> m_path; }; DEFINE_ANIMATABLE_VALUE_TYPE_CASTS(AnimatablePath, isPath());
diff --git a/third_party/WebKit/Source/core/animation/css/CSSAnimatableValueFactory.cpp b/third_party/WebKit/Source/core/animation/css/CSSAnimatableValueFactory.cpp index 27d1e8f4..4a20ef3 100644 --- a/third_party/WebKit/Source/core/animation/css/CSSAnimatableValueFactory.cpp +++ b/third_party/WebKit/Source/core/animation/css/CSSAnimatableValueFactory.cpp
@@ -247,9 +247,9 @@ return AnimatableUnknown::create(CSSValueNone); } -static PassRefPtr<AnimatableValue> createFromPath(CSSPathValue* pathValue) +static PassRefPtr<AnimatableValue> createFromPath(StylePath* path) { - return AnimatablePath::create(pathValue); + return AnimatablePath::create(path); } static double fontStretchToDouble(FontStretch fontStretch)
diff --git a/third_party/WebKit/Source/core/core.gypi b/third_party/WebKit/Source/core/core.gypi index c894383..b922499 100644 --- a/third_party/WebKit/Source/core/core.gypi +++ b/third_party/WebKit/Source/core/core.gypi
@@ -790,6 +790,8 @@ 'style/StyleMotionData.h', 'style/StyleMotionPath.h', 'style/StyleMultiColData.cpp', + 'style/StylePath.cpp', + 'style/StylePath.h', 'style/StylePendingImage.h', 'style/StyleRareInheritedData.cpp', 'style/StyleRareNonInheritedData.cpp',
diff --git a/third_party/WebKit/Source/core/css/CSSPathValue.cpp b/third_party/WebKit/Source/core/css/CSSPathValue.cpp index d455751..dcfbf15a 100644 --- a/third_party/WebKit/Source/core/css/CSSPathValue.cpp +++ b/third_party/WebKit/Source/core/css/CSSPathValue.cpp
@@ -4,31 +4,61 @@ #include "core/css/CSSPathValue.h" +#include "core/style/StylePath.h" #include "core/svg/SVGPathUtilities.h" namespace blink { +PassRefPtrWillBeRawPtr<CSSPathValue> CSSPathValue::create(PassRefPtr<SVGPathByteStream> pathByteStream, StylePath* cachedPath) +{ + return adoptRefWillBeNoop(new CSSPathValue(pathByteStream, cachedPath)); +} + PassRefPtrWillBeRawPtr<CSSPathValue> CSSPathValue::create(const String& pathString) { - OwnPtr<SVGPathByteStream> byteStream = SVGPathByteStream::create(); + RefPtr<SVGPathByteStream> byteStream = SVGPathByteStream::create(); buildByteStreamFromString(pathString, *byteStream); return CSSPathValue::create(byteStream.release()); } -CSSPathValue::CSSPathValue(PassOwnPtr<SVGPathByteStream> pathByteStream) +CSSPathValue::CSSPathValue(PassRefPtr<SVGPathByteStream> pathByteStream, StylePath* cachedPath) : CSSValue(PathClass) , m_pathByteStream(pathByteStream) + , m_cachedPath(cachedPath) { ASSERT(m_pathByteStream); - buildPathFromByteStream(*m_pathByteStream, m_path); +} + +CSSPathValue::~CSSPathValue() +{ +} + +namespace { + +PassRefPtrWillBeRawPtr<CSSPathValue> createPathValue() +{ + RefPtr<SVGPathByteStream> pathByteStream = SVGPathByteStream::create(); + // Need to be registered as LSan ignored, as it will be reachable and + // separately referred to by emptyPathValue() callers. + LEAK_SANITIZER_IGNORE_OBJECT(pathByteStream.get()); + return CSSPathValue::create(pathByteStream.release()); +} + } CSSPathValue* CSSPathValue::emptyPathValue() { - DEFINE_STATIC_LOCAL(RefPtrWillBePersistent<CSSPathValue>, empty, (CSSPathValue::create(SVGPathByteStream::create()))); + DEFINE_STATIC_LOCAL(RefPtrWillBePersistent<CSSPathValue>, empty, (createPathValue())); return empty.get(); } +StylePath* CSSPathValue::cachedPath() +{ + if (!m_cachedPath) + m_cachedPath = StylePath::create(m_pathByteStream); + return m_cachedPath.get(); +} + String CSSPathValue::customCSSText() const { return "path('" + pathString() + "')";
diff --git a/third_party/WebKit/Source/core/css/CSSPathValue.h b/third_party/WebKit/Source/core/css/CSSPathValue.h index 21d6a36..f80acbb 100644 --- a/third_party/WebKit/Source/core/css/CSSPathValue.h +++ b/third_party/WebKit/Source/core/css/CSSPathValue.h
@@ -7,23 +7,22 @@ #include "core/css/CSSValue.h" #include "core/svg/SVGPathByteStream.h" -#include "platform/graphics/Path.h" #include "wtf/PassRefPtr.h" #include "wtf/RefPtr.h" namespace blink { +class StylePath; + class CSSPathValue : public CSSValue { public: - static PassRefPtrWillBeRawPtr<CSSPathValue> create(PassOwnPtr<SVGPathByteStream> pathByteStream) - { - return adoptRefWillBeNoop(new CSSPathValue(pathByteStream)); - } - + static PassRefPtrWillBeRawPtr<CSSPathValue> create(PassRefPtr<SVGPathByteStream>, StylePath* = nullptr); static PassRefPtrWillBeRawPtr<CSSPathValue> create(const String&); + ~CSSPathValue(); static CSSPathValue* emptyPathValue(); + StylePath* cachedPath(); String customCSSText() const; bool equals(const CSSPathValue&) const; @@ -32,13 +31,12 @@ const SVGPathByteStream& byteStream() const { return *m_pathByteStream; } String pathString() const; - const Path& path() const { return m_path; } private: - CSSPathValue(PassOwnPtr<SVGPathByteStream>); + CSSPathValue(PassRefPtr<SVGPathByteStream>, StylePath*); - OwnPtr<SVGPathByteStream> m_pathByteStream; - Path m_path; + RefPtr<SVGPathByteStream> m_pathByteStream; + RefPtr<StylePath> m_cachedPath; }; DEFINE_CSS_VALUE_TYPE_CASTS(CSSPathValue, isPathValue());
diff --git a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp index 0bb2a88..e9dfd35 100644 --- a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp +++ b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
@@ -2636,7 +2636,7 @@ // the above properties are not yet implemented in the engine return nullptr; case CSSPropertyD: - return svgStyle.d(); + return svgStyle.d()->computedCSSValue(); case CSSPropertyCx: return zoomAdjustedPixelValueForLength(svgStyle.cx(), style); case CSSPropertyCy:
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp index e38f5b4..120a490 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp +++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -1934,7 +1934,7 @@ return nullptr; String pathString = functionArgs.consumeIncludingWhitespace().value(); - OwnPtr<SVGPathByteStream> byteStream = SVGPathByteStream::create(); + RefPtr<SVGPathByteStream> byteStream = SVGPathByteStream::create(); if (!buildByteStreamFromString(pathString, *byteStream) || !functionArgs.atEnd()) return nullptr;
diff --git a/third_party/WebKit/Source/core/css/resolver/AnimatedStyleBuilder.cpp b/third_party/WebKit/Source/core/css/resolver/AnimatedStyleBuilder.cpp index e02bf93..b6fa606 100644 --- a/third_party/WebKit/Source/core/css/resolver/AnimatedStyleBuilder.cpp +++ b/third_party/WebKit/Source/core/css/resolver/AnimatedStyleBuilder.cpp
@@ -682,7 +682,7 @@ style->setZIndex(clampTo<int>(round(toAnimatableDouble(value)->toDouble()))); return; case CSSPropertyD: - style->setD(toAnimatablePath(value)->pathValue()); + style->setD(toAnimatablePath(value)->path()); return; case CSSPropertyCx: style->setCx(animatableValueToLength(value, state));
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp b/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp index 4ca4f2a..d69f79e7 100644 --- a/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp +++ b/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp
@@ -32,6 +32,7 @@ #include "core/css/CSSFontFeatureValue.h" #include "core/css/CSSFunctionValue.h" #include "core/css/CSSGridLineNamesValue.h" +#include "core/css/CSSPathValue.h" #include "core/css/CSSPrimitiveValueMappings.h" #include "core/css/CSSQuadValue.h" #include "core/css/CSSReflectValue.h" @@ -953,9 +954,9 @@ return primitiveValue.getValueID() == CSSValueFromImage ? RespectImageOrientation : DoNotRespectImageOrientation; } -CSSPathValue* StyleBuilderConverter::convertPath(StyleResolverState&, CSSValue& value) +PassRefPtr<StylePath> StyleBuilderConverter::convertPath(StyleResolverState&, CSSValue& value) { - return toCSSPathValue(&value); + return toCSSPathValue(value).cachedPath(); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.h b/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.h index 9b3027b7..f2f8ff5e 100644 --- a/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.h +++ b/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.h
@@ -46,6 +46,7 @@ class RotateTransformOperation; class TranslateTransformOperation; class ScaleTransformOperation; +class StylePath; // Note that we assume the parser only allows valid CSSValue types. class StyleBuilderConverter { @@ -104,7 +105,7 @@ static PassRefPtr<RotateTransformOperation> convertRotate(StyleResolverState&, const CSSValue&); static PassRefPtr<ScaleTransformOperation> convertScale(StyleResolverState&, const CSSValue&); static RespectImageOrientationEnum convertImageOrientation(StyleResolverState&, const CSSValue&); - static CSSPathValue* convertPath(StyleResolverState&, CSSValue&); + static PassRefPtr<StylePath> convertPath(StyleResolverState&, CSSValue&); }; template <typename T>
diff --git a/third_party/WebKit/Source/core/dom/ContainerNode.cpp b/third_party/WebKit/Source/core/dom/ContainerNode.cpp index 25dfd46..3b39dfee 100644 --- a/third_party/WebKit/Source/core/dom/ContainerNode.cpp +++ b/third_party/WebKit/Source/core/dom/ContainerNode.cpp
@@ -586,6 +586,7 @@ { HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates; + DocumentOrderedMap::RemoveScope treeRemoveScope; Node* prev = child->previousSibling(); Node* next = child->nextSibling(); @@ -638,6 +639,8 @@ oldChild.notifyMutationObserversNodeWillDetach(); HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates; + DocumentOrderedMap::RemoveScope treeRemoveScope; + Node* prev = oldChild.previousSibling(); Node* next = oldChild.nextSibling(); removeBetween(prev, next, oldChild); @@ -685,7 +688,7 @@ #endif { HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates; - + DocumentOrderedMap::RemoveScope treeRemoveScope; { EventDispatchForbiddenScope assertNoEventDispatch; ScriptForbiddenScope forbidScript;
diff --git a/third_party/WebKit/Source/core/dom/DocumentOrderedMap.cpp b/third_party/WebKit/Source/core/dom/DocumentOrderedMap.cpp index 85495be..0d310c4 100644 --- a/third_party/WebKit/Source/core/dom/DocumentOrderedMap.cpp +++ b/third_party/WebKit/Source/core/dom/DocumentOrderedMap.cpp
@@ -50,10 +50,23 @@ { } -DocumentOrderedMap::~DocumentOrderedMap() +DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(DocumentOrderedMap); + +#if ENABLE(ASSERT) +static int s_removeScopeLevel = 0; + +DocumentOrderedMap::RemoveScope::RemoveScope() { + s_removeScopeLevel++; } +DocumentOrderedMap::RemoveScope::~RemoveScope() +{ + ASSERT(s_removeScopeLevel); + s_removeScopeLevel--; +} +#endif + inline bool keyMatchesId(const AtomicString& key, const Element& element) { return element.getIdAttribute() == key; @@ -114,14 +127,6 @@ } } -#if ENABLE(ASSERT) -void DocumentOrderedMap::willRemoveId(const AtomicString& key) -{ - ASSERT(m_removingId.isNull() || key.isNull()); - m_removingId = key; -} -#endif - template<bool keyMatches(const AtomicString&, const Element&)> inline Element* DocumentOrderedMap::get(const AtomicString& key, const TreeScope* scope) const { @@ -138,20 +143,17 @@ // Iterate to find the node that matches. Nothing will match iff an element // with children having duplicate IDs is being removed -- the tree traversal - // will be over an updated tree not having that element. In all other cases, + // will be over an updated tree not having that subtree. In all other cases, // a match is expected. - // - // Such calls to get()/getElementById() while handling element removals will - // legitimately happen when e.g., adjusting form ID associations. Quietly - // allow those lookups to (expectedly) fail by having the tree scope removal - // register the element ID it is in the process of removing. for (Element& element : ElementTraversal::startsAfter(scope->rootNode())) { if (!keyMatches(key, element)) continue; entry->element = &element; return &element; } - ASSERT(key == m_removingId); + // As get()/getElementById() can legitimately be called while handling element + // removals, allow failure iff we're in the scope of node removals. + ASSERT(s_removeScopeLevel); return 0; }
diff --git a/third_party/WebKit/Source/core/dom/DocumentOrderedMap.h b/third_party/WebKit/Source/core/dom/DocumentOrderedMap.h index 0877b71..5b25d3f 100644 --- a/third_party/WebKit/Source/core/dom/DocumentOrderedMap.h +++ b/third_party/WebKit/Source/core/dom/DocumentOrderedMap.h
@@ -44,11 +44,11 @@ class Element; class TreeScope; -class DocumentOrderedMap : public NoBaseWillBeGarbageCollectedFinalized<DocumentOrderedMap> { +class DocumentOrderedMap : public NoBaseWillBeGarbageCollected<DocumentOrderedMap> { USING_FAST_MALLOC_WILL_BE_REMOVED(DocumentOrderedMap); + DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(DocumentOrderedMap); public: static PassOwnPtrWillBeRawPtr<DocumentOrderedMap> create(); - ~DocumentOrderedMap(); void add(const AtomicString&, Element*); void remove(const AtomicString&, Element*); @@ -65,7 +65,24 @@ DECLARE_TRACE(); #if ENABLE(ASSERT) - void willRemoveId(const AtomicString&); + // While removing a ContainerNode, ID lookups won't be precise should the tree + // have elements with duplicate IDs contained in the element being removed. + // Rare trees, but ID lookups may legitimately fail across such removals; + // this scope object informs DocumentOrderedMaps about the transitory + // state of the underlying tree. + class RemoveScope { + STACK_ALLOCATED(); + public: + RemoveScope(); + ~RemoveScope(); + }; +#else + class RemoveScope { + STACK_ALLOCATED(); + public: + RemoveScope() { } + ~RemoveScope() { } + }; #endif private: @@ -92,9 +109,6 @@ using Map = WillBeHeapHashMap<AtomicString, OwnPtrWillBeMember<MapEntry>>; mutable Map m_map; -#if ENABLE(ASSERT) - AtomicString m_removingId; -#endif }; inline bool DocumentOrderedMap::contains(const AtomicString& id) const
diff --git a/third_party/WebKit/Source/core/dom/PendingScript.cpp b/third_party/WebKit/Source/core/dom/PendingScript.cpp index 2a688e2..ba3e8a5 100644 --- a/third_party/WebKit/Source/core/dom/PendingScript.cpp +++ b/third_party/WebKit/Source/core/dom/PendingScript.cpp
@@ -117,6 +117,7 @@ setScriptResource(0); m_watchingForLoad = false; m_startingPosition = TextPosition::belowRangePosition(); + m_integrityFailure = false; if (m_streamer) m_streamer->cancel(); m_streamer.release();
diff --git a/third_party/WebKit/Source/core/dom/ScriptRunnerTest.cpp b/third_party/WebKit/Source/core/dom/ScriptRunnerTest.cpp index bb2bec7..862955d 100644 --- a/third_party/WebKit/Source/core/dom/ScriptRunnerTest.cpp +++ b/third_party/WebKit/Source/core/dom/ScriptRunnerTest.cpp
@@ -39,116 +39,6 @@ } }; -class MockWebThread : public WebThread { -public: - explicit MockWebThread(WebScheduler* webScheduler) : m_webScheduler(webScheduler) { } - ~MockWebThread() override { } - - bool isCurrentThread() const override - { - ASSERT_NOT_REACHED(); - return false; - } - - PlatformThreadId threadId() const override - { - ASSERT_NOT_REACHED(); - return 0; - } - - WebTaskRunner* taskRunner() override - { - ASSERT_NOT_REACHED(); - return nullptr; - } - - void addTaskObserver(TaskObserver*) override { ASSERT_NOT_REACHED(); } - void removeTaskObserver(TaskObserver*) override { ASSERT_NOT_REACHED(); } - - WebScheduler* scheduler() const override { return m_webScheduler; } - -private: - WebScheduler* m_webScheduler; -}; - -class MockWebTaskRunner : public WebTaskRunner { -public: - explicit MockWebTaskRunner(Deque<OwnPtr<WebTaskRunner::Task>>* tasks) : m_tasks(tasks) { } - ~MockWebTaskRunner() override { } - - void postTask(const WebTraceLocation&, Task* task) override - { - m_tasks->append(adoptPtr(task)); - } - - void postDelayedTask(const WebTraceLocation&, Task* task, double delayMs) override - { - ASSERT_NOT_REACHED(); - } - - WebTaskRunner* clone() override - { - ASSERT_NOT_REACHED(); - return nullptr; - } - - Deque<OwnPtr<WebTaskRunner::Task>>* m_tasks; // NOT OWNED -}; - -class MockPlatform : public TestingPlatformSupport, public WebScheduler { -public: - MockPlatform() - : m_mockWebThread(this) - , m_mockWebTaskRunner(&m_tasks) - { - } - - WebThread* currentThread() override { return &m_mockWebThread; } - - void runSingleTask() - { - if (m_tasks.isEmpty()) - return; - m_tasks.takeFirst()->run(); - } - - void runAllTasks() - { - while (!m_tasks.isEmpty()) - m_tasks.takeFirst()->run(); - } - - // WebScheduler implementation. - WebTaskRunner* loadingTaskRunner() override - { - return &m_mockWebTaskRunner; - } - - WebTaskRunner* timerTaskRunner() override - { - ASSERT_NOT_REACHED(); - return nullptr; - } - - void shutdown() override {} - bool shouldYieldForHighPriorityWork() override { return false; } - bool canExceedIdleDeadlineIfRequired() override { return false; } - void postIdleTask(const WebTraceLocation&, WebThread::IdleTask*) override { } - void postNonNestableIdleTask(const WebTraceLocation&, WebThread::IdleTask*) override { } - void postIdleTaskAfterWakeup(const WebTraceLocation&, WebThread::IdleTask*) override { } - WebPassOwnPtr<WebViewScheduler> createWebViewScheduler(blink::WebView*) override { return nullptr; } - void suspendTimerQueue() override { } - void resumeTimerQueue() override { } - void addPendingNavigation() override { } - void removePendingNavigation() override { } - void onNavigationStarted() override { } - -private: - MockWebThread m_mockWebThread; - Deque<OwnPtr<WebTaskRunner::Task>> m_tasks; - MockWebTaskRunner m_mockWebTaskRunner; -}; - class ScriptRunnerTest : public testing::Test { public: ScriptRunnerTest() @@ -172,7 +62,7 @@ RefPtrWillBePersistent<Document> m_document; RefPtrWillBePersistent<Element> m_element; - MockPlatform m_platform; + TestingPlatformSupportWithMockScheduler m_platform; OwnPtrWillBePersistent<ScriptRunner> m_scriptRunner; WTF::Vector<int> m_order; }; @@ -184,7 +74,7 @@ m_scriptRunner->notifyScriptReady(scriptLoader.get(), ScriptRunner::ASYNC_EXECUTION); EXPECT_CALL(*scriptLoader, execute()); - m_platform.runAllTasks(); + m_platform.mockWebScheduler()->runAllTasks(); } TEST_F(ScriptRunnerTest, QueueSingleScript_InOrder) @@ -197,7 +87,7 @@ m_scriptRunner->notifyScriptReady(scriptLoader.get(), ScriptRunner::IN_ORDER_EXECUTION); - m_platform.runAllTasks(); + m_platform.mockWebScheduler()->runAllTasks(); } TEST_F(ScriptRunnerTest, QueueMultipleScripts_InOrder) @@ -235,7 +125,7 @@ for (int i = 2; i >= 0; i--) { isReady[i] = true; m_scriptRunner->notifyScriptReady(scriptLoaders[i], ScriptRunner::IN_ORDER_EXECUTION); - m_platform.runAllTasks(); + m_platform.mockWebScheduler()->runAllTasks(); } // But ensure the scripts were run in the expected order. @@ -290,7 +180,7 @@ m_order.append(5); })); - m_platform.runAllTasks(); + m_platform.mockWebScheduler()->runAllTasks(); // Async tasks are expected to run first. EXPECT_THAT(m_order, ElementsAre(4, 5, 1, 2, 3)); @@ -325,13 +215,13 @@ // Make sure that re-entrant calls to notifyScriptReady don't cause ScriptRunner::execute to do // more work than expected. - m_platform.runSingleTask(); + m_platform.mockWebScheduler()->runSingleTask(); EXPECT_THAT(m_order, ElementsAre(1)); - m_platform.runSingleTask(); + m_platform.mockWebScheduler()->runSingleTask(); EXPECT_THAT(m_order, ElementsAre(1, 2)); - m_platform.runSingleTask(); + m_platform.mockWebScheduler()->runSingleTask(); EXPECT_THAT(m_order, ElementsAre(1, 2, 3)); } @@ -370,13 +260,13 @@ // Make sure that re-entrant calls to queueScriptForExecution don't cause ScriptRunner::execute to do // more work than expected. - m_platform.runSingleTask(); + m_platform.mockWebScheduler()->runSingleTask(); EXPECT_THAT(m_order, ElementsAre(1)); - m_platform.runSingleTask(); + m_platform.mockWebScheduler()->runSingleTask(); EXPECT_THAT(m_order, ElementsAre(1, 2)); - m_platform.runSingleTask(); + m_platform.mockWebScheduler()->runSingleTask(); EXPECT_THAT(m_order, ElementsAre(1, 2, 3)); } @@ -408,7 +298,7 @@ m_order.append(0); })); - m_platform.runAllTasks(); + m_platform.mockWebScheduler()->runAllTasks(); int expected[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 @@ -458,10 +348,10 @@ .WillRepeatedly(Return(true)); m_scriptRunner->notifyScriptReady(scriptLoader3.get(), ScriptRunner::IN_ORDER_EXECUTION); - m_platform.runSingleTask(); + m_platform.mockWebScheduler()->runSingleTask(); m_scriptRunner->suspend(); m_scriptRunner->resume(); - m_platform.runAllTasks(); + m_platform.mockWebScheduler()->runAllTasks(); // Make sure elements are correct and in right order. EXPECT_THAT(m_order, ElementsAre(1, 2, 3)); @@ -494,10 +384,10 @@ m_order.append(3); })); - m_platform.runSingleTask(); + m_platform.mockWebScheduler()->runSingleTask(); m_scriptRunner->suspend(); m_scriptRunner->resume(); - m_platform.runAllTasks(); + m_platform.mockWebScheduler()->runAllTasks(); // Make sure elements are correct. EXPECT_THAT(m_order, WhenSorted(ElementsAre(1, 2, 3))); @@ -522,11 +412,11 @@ })); m_scriptRunner->notifyScriptReady(scriptLoader1.get(), ScriptRunner::IN_ORDER_EXECUTION); - m_platform.runAllTasks(); + m_platform.mockWebScheduler()->runAllTasks(); // At this moment all tasks can be already executed. Make sure that we do not crash here. m_scriptRunner->notifyScriptReady(scriptLoader2.get(), ScriptRunner::IN_ORDER_EXECUTION); - m_platform.runAllTasks(); + m_platform.mockWebScheduler()->runAllTasks(); EXPECT_THAT(m_order, ElementsAre(1, 2)); } @@ -555,7 +445,7 @@ EXPECT_CALL(*scriptLoader1, execute()).Times(0); EXPECT_CALL(*scriptLoader2, execute()).Times(0); - m_platform.runAllTasks(); + m_platform.mockWebScheduler()->runAllTasks(); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/TreeScope.cpp b/third_party/WebKit/Source/core/dom/TreeScope.cpp index d536fa33..59ea102 100644 --- a/third_party/WebKit/Source/core/dom/TreeScope.cpp +++ b/third_party/WebKit/Source/core/dom/TreeScope.cpp
@@ -186,43 +186,11 @@ } -#if ENABLE(ASSERT) -namespace { - -class RemovingElementIdScope { - STACK_ALLOCATED(); -public: - RemovingElementIdScope(DocumentOrderedMap& elementsById, const AtomicString& id) - : m_elementsById(&elementsById) - { - m_elementsById->willRemoveId(id); - } - ~RemovingElementIdScope() - { - m_elementsById->willRemoveId(nullAtom); - } - -private: - RawPtrWillBeMember<DocumentOrderedMap> m_elementsById; -}; - -} -#endif - void TreeScope::removeElementById(const AtomicString& elementId, Element* element) { if (!m_elementsById) return; m_elementsById->remove(elementId, element); -#if ENABLE(ASSERT) - // Register 'elementId' as being removed. This is done should observers - // attempt to also look it up, something that the underlying DocumentOrderedMap - // is incapable of answering precisely while an element (and its - // children) are being removed from the tree. This is _only_ done to avoid - // an assert in DocumentOrderedMap::get() from falsely triggering for such - // unusual and unexpected lookups. - RemovingElementIdScope removalScope(*m_elementsById, elementId); -#endif m_idTargetObserverRegistry->notifyObservers(elementId); }
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.cpp b/third_party/WebKit/Source/core/frame/UseCounter.cpp index 795ccce..8e65609f 100644 --- a/third_party/WebKit/Source/core/frame/UseCounter.cpp +++ b/third_party/WebKit/Source/core/frame/UseCounter.cpp
@@ -968,6 +968,15 @@ case V8TouchEvent_InitTouchEvent_Method: return replacedWillBeRemoved("'TouchEvent.initTouchEvent'", "the TouchEvent constructor", 53, "5730982598541312"); + case RTCPeerConnectionCreateAnswerLegacyNoFailureCallback: + return "RTCPeerConnection.CreateAnswer without a failure callback is deprecated. The failure callback will be a required parameter in M50. See https://www.chromestatus.com/feature/5663288008376320 for more details"; + + case RTCPeerConnectionCreateOfferLegacyNoFailureCallback: + return "RTCPeerConnection.CreateOffer without a failure callback is deprecated. The failure callback will be a required parameter in M50. See https://www.chromestatus.com/feature/5663288008376320 for more details"; + + case ObjectObserve: + return willBeRemoved("'Object.observe'", 50, "6147094632988672"); + // Features that aren't deprecated don't have a deprecation message. default: return String();
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.h b/third_party/WebKit/Source/core/html/HTMLMediaElement.h index 5a29fd6b..4c7126a 100644 --- a/third_party/WebKit/Source/core/html/HTMLMediaElement.h +++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.h
@@ -455,10 +455,10 @@ // TODO(liberato): remove once autoplay gesture override experiment concludes. void triggerAutoplayViewportCheckForTesting(); - Timer<HTMLMediaElement> m_loadTimer; - Timer<HTMLMediaElement> m_progressEventTimer; - Timer<HTMLMediaElement> m_playbackProgressTimer; - Timer<HTMLMediaElement> m_audioTracksTimer; + UnthrottledTimer<HTMLMediaElement> m_loadTimer; + UnthrottledTimer<HTMLMediaElement> m_progressEventTimer; + UnthrottledTimer<HTMLMediaElement> m_playbackProgressTimer; + UnthrottledTimer<HTMLMediaElement> m_audioTracksTimer; PersistentWillBeMember<TimeRanges> m_playedTimeRanges; OwnPtrWillBeMember<GenericEventQueue> m_asyncEventQueue;
diff --git a/third_party/WebKit/Source/core/html/canvas/OffScreenCanvas.idl b/third_party/WebKit/Source/core/html/canvas/OffScreenCanvas.idl index 32afa8a..bfa5acc5 100644 --- a/third_party/WebKit/Source/core/html/canvas/OffScreenCanvas.idl +++ b/third_party/WebKit/Source/core/html/canvas/OffScreenCanvas.idl
@@ -5,6 +5,7 @@ [ Constructor([EnforceRange] unsigned long width, [EnforceRange] unsigned long height), GarbageCollected, + Exposed=(Window,Worker), RuntimeEnabled=ExperimentalCanvasFeatures, ] interface OffScreenCanvas { [EnforceRange] attribute unsigned long width;
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.h b/third_party/WebKit/Source/core/style/ComputedStyle.h index 4872531..e44f182d 100644 --- a/third_party/WebKit/Source/core/style/ComputedStyle.h +++ b/third_party/WebKit/Source/core/style/ComputedStyle.h
@@ -115,6 +115,7 @@ class ShadowList; class StyleImage; class StyleInheritedData; +class StylePath; class StyleResolver; class TransformationMatrix; class TranslateTransformOperation; @@ -1498,7 +1499,7 @@ float strokeMiterLimit() const { return svgStyle().strokeMiterLimit(); } void setStrokeMiterLimit(float f) { accessSVGStyle().setStrokeMiterLimit(f); } - void setD(PassRefPtrWillBeRawPtr<CSSPathValue> d) { accessSVGStyle().setD(d); } + void setD(PassRefPtr<StylePath> d) { accessSVGStyle().setD(d); } void setCx(const Length& cx) { accessSVGStyle().setCx(cx); } void setCy(const Length& cy) { accessSVGStyle().setCy(cy); } void setX(const Length& x) { accessSVGStyle().setX(x); }
diff --git a/third_party/WebKit/Source/core/style/SVGComputedStyle.h b/third_party/WebKit/Source/core/style/SVGComputedStyle.h index 9db42be..925300f 100644 --- a/third_party/WebKit/Source/core/style/SVGComputedStyle.h +++ b/third_party/WebKit/Source/core/style/SVGComputedStyle.h
@@ -89,7 +89,7 @@ static const AtomicString& initialMarkerEndResource() { return nullAtom; } static EMaskType initialMaskType() { return MT_LUMINANCE; } static EPaintOrder initialPaintOrder() { return PaintOrderNormal; } - static CSSPathValue* initialD() { return CSSPathValue::emptyPathValue(); } + static StylePath* initialD() { return StylePath::emptyPath(); } static Length initialCx() { return Length(Fixed); } static Length initialCy() { return Length(Fixed); } static Length initialX() { return Length(Fixed); } @@ -115,7 +115,7 @@ void setTextAnchor(ETextAnchor val) { svg_inherited_flags.textAnchor = val; } void setMaskType(EMaskType val) { svg_noninherited_flags.f.maskType = val; } void setPaintOrder(EPaintOrder val) { svg_inherited_flags.paintOrder = (int)val; } - void setD(PassRefPtrWillBeRawPtr<CSSPathValue> d) + void setD(PassRefPtr<StylePath> d) { if (!(layout->d == d)) layout.access()->d = d; @@ -338,7 +338,7 @@ const Color& floodColor() const { return misc->floodColor; } const Color& lightingColor() const { return misc->lightingColor; } const Length& baselineShiftValue() const { return misc->baselineShiftValue; } - CSSPathValue* d() const { return layout->d.get(); } + StylePath* d() const { return layout->d.get(); } const Length& cx() const { return layout->cx; } const Length& cy() const { return layout->cy; } const Length& x() const { return layout->x; }
diff --git a/third_party/WebKit/Source/core/style/SVGComputedStyleDefs.cpp b/third_party/WebKit/Source/core/style/SVGComputedStyleDefs.cpp index 4a508a8..e8d29cc 100644 --- a/third_party/WebKit/Source/core/style/SVGComputedStyleDefs.cpp +++ b/third_party/WebKit/Source/core/style/SVGComputedStyleDefs.cpp
@@ -200,7 +200,7 @@ } StyleLayoutData::StyleLayoutData() - : d(CSSPathValue::emptyPathValue()) + : d(SVGComputedStyle::initialD()) , cx(SVGComputedStyle::initialCx()) , cy(SVGComputedStyle::initialCy()) , x(SVGComputedStyle::initialX())
diff --git a/third_party/WebKit/Source/core/style/SVGComputedStyleDefs.h b/third_party/WebKit/Source/core/style/SVGComputedStyleDefs.h index 88d38aa..5adcb8c 100644 --- a/third_party/WebKit/Source/core/style/SVGComputedStyleDefs.h +++ b/third_party/WebKit/Source/core/style/SVGComputedStyleDefs.h
@@ -29,7 +29,7 @@ #define SVGComputedStyleDefs_h #include "core/CoreExport.h" -#include "core/css/CSSPathValue.h" +#include "core/style/StylePath.h" #include "platform/Length.h" #include "platform/graphics/Color.h" #include "wtf/Allocator.h" @@ -290,7 +290,7 @@ { return !(*this == other); } - RefPtrWillBePersistent<CSSPathValue> d; + RefPtr<StylePath> d; Length cx; Length cy; Length x;
diff --git a/third_party/WebKit/Source/core/style/StylePath.cpp b/third_party/WebKit/Source/core/style/StylePath.cpp new file mode 100644 index 0000000..674ba45 --- /dev/null +++ b/third_party/WebKit/Source/core/style/StylePath.cpp
@@ -0,0 +1,50 @@ +// Copyright 2016 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 "core/style/StylePath.h" + +#include "core/css/CSSPathValue.h" +#include "core/svg/SVGPathByteStream.h" +#include "core/svg/SVGPathUtilities.h" + +namespace blink { + +StylePath::StylePath(PassRefPtr<SVGPathByteStream> pathByteStream) + : m_byteStream(pathByteStream) +{ + ASSERT(m_byteStream); + buildPathFromByteStream(*m_byteStream, m_path); +} + +StylePath::~StylePath() +{ +} + +PassRefPtr<StylePath> StylePath::create(PassRefPtr<SVGPathByteStream> pathByteStream) +{ + return adoptRef(new StylePath(pathByteStream)); +} + +StylePath* StylePath::emptyPath() +{ + DEFINE_STATIC_REF(StylePath, emptyPath, StylePath::create(SVGPathByteStream::create())); + return emptyPath; +} + +const SVGPathByteStream& StylePath::byteStream() const +{ + return *m_byteStream; +} + +PassRefPtrWillBeRawPtr<CSSValue> StylePath::computedCSSValue() const +{ + return CSSPathValue::create(m_byteStream, const_cast<StylePath*>(this)); +} + +bool StylePath::equals(const StylePath& other) const +{ + return *m_byteStream == *other.m_byteStream; +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/style/StylePath.h b/third_party/WebKit/Source/core/style/StylePath.h new file mode 100644 index 0000000..f8d5781 --- /dev/null +++ b/third_party/WebKit/Source/core/style/StylePath.h
@@ -0,0 +1,42 @@ +// Copyright 2016 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 StylePath_h +#define StylePath_h + +#include "platform/graphics/Path.h" +#include "platform/heap/Handle.h" +#include "wtf/PassRefPtr.h" +#include "wtf/RefCounted.h" +#include "wtf/RefPtr.h" + +namespace blink { + +class CSSValue; +class SVGPathByteStream; + +class StylePath : public RefCounted<StylePath> { +public: + static PassRefPtr<StylePath> create(PassRefPtr<SVGPathByteStream>); + ~StylePath(); + + static StylePath* emptyPath(); + + const Path& path() const { return m_path; } + const SVGPathByteStream& byteStream() const; + + PassRefPtrWillBeRawPtr<CSSValue> computedCSSValue() const; + + bool equals(const StylePath&) const; + +private: + explicit StylePath(PassRefPtr<SVGPathByteStream>); + + RefPtr<SVGPathByteStream> m_byteStream; + Path m_path; +}; + +} // namespace blink + +#endif // StylePath_h
diff --git a/third_party/WebKit/Source/core/svg/SVGPath.cpp b/third_party/WebKit/Source/core/svg/SVGPath.cpp index 0f6500a6..c6b00ba 100644 --- a/third_party/WebKit/Source/core/svg/SVGPath.cpp +++ b/third_party/WebKit/Source/core/svg/SVGPath.cpp
@@ -35,9 +35,9 @@ namespace { -PassOwnPtr<SVGPathByteStream> blendPathByteStreams(const SVGPathByteStream& fromStream, const SVGPathByteStream& toStream, float progress) +PassRefPtr<SVGPathByteStream> blendPathByteStreams(const SVGPathByteStream& fromStream, const SVGPathByteStream& toStream, float progress) { - OwnPtr<SVGPathByteStream> resultStream = SVGPathByteStream::create(); + RefPtr<SVGPathByteStream> resultStream = SVGPathByteStream::create(); SVGPathByteStreamBuilder builder(*resultStream); SVGPathByteStreamSource fromSource(fromStream); SVGPathByteStreamSource toSource(toStream); @@ -46,9 +46,9 @@ return resultStream.release(); } -PassOwnPtr<SVGPathByteStream> addPathByteStreams(const SVGPathByteStream& fromStream, const SVGPathByteStream& byStream, unsigned repeatCount = 1) +PassRefPtr<SVGPathByteStream> addPathByteStreams(const SVGPathByteStream& fromStream, const SVGPathByteStream& byStream, unsigned repeatCount = 1) { - OwnPtr<SVGPathByteStream> resultStream = SVGPathByteStream::create(); + RefPtr<SVGPathByteStream> resultStream = SVGPathByteStream::create(); SVGPathByteStreamBuilder builder(*resultStream); SVGPathByteStreamSource fromSource(fromStream); SVGPathByteStreamSource bySource(byStream); @@ -57,7 +57,7 @@ return resultStream.release(); } -PassOwnPtr<SVGPathByteStream> conditionallyAddPathByteStreams(PassOwnPtr<SVGPathByteStream> fromStream, const SVGPathByteStream& byStream, unsigned repeatCount = 1) +PassRefPtr<SVGPathByteStream> conditionallyAddPathByteStreams(PassRefPtr<SVGPathByteStream> fromStream, const SVGPathByteStream& byStream, unsigned repeatCount = 1) { if (fromStream->isEmpty() || byStream.isEmpty()) return fromStream; @@ -96,7 +96,7 @@ SVGParsingError SVGPath::setValueAsString(const String& string) { SVGParsingError parseStatus = NoError; - OwnPtr<SVGPathByteStream> byteStream = SVGPathByteStream::create(); + RefPtr<SVGPathByteStream> byteStream = SVGPathByteStream::create(); if (!buildByteStreamFromString(string, *byteStream)) parseStatus = ParsingAttributeFailedError; m_pathValue = CSSPathValue::create(byteStream.release()); @@ -134,9 +134,9 @@ const RefPtrWillBeRawPtr<SVGPath> from = toSVGPath(fromValue); const SVGPathByteStream* fromStream = &from->byteStream(); - OwnPtr<SVGPathByteStream> copy; + RefPtr<SVGPathByteStream> copy; if (isToAnimation) { - copy = byteStream().copy(); + copy = byteStream().clone(); fromStream = copy.get(); } @@ -153,7 +153,7 @@ } } - OwnPtr<SVGPathByteStream> newStream = blendPathByteStreams(*fromStream, toStream, percentage); + RefPtr<SVGPathByteStream> newStream = blendPathByteStreams(*fromStream, toStream, percentage); // Handle additive='sum'. if (animationElement->isAdditive() && !isToAnimation)
diff --git a/third_party/WebKit/Source/core/svg/SVGPathByteStream.h b/third_party/WebKit/Source/core/svg/SVGPathByteStream.h index e7bec8b..0442474 100644 --- a/third_party/WebKit/Source/core/svg/SVGPathByteStream.h +++ b/third_party/WebKit/Source/core/svg/SVGPathByteStream.h
@@ -21,7 +21,8 @@ #define SVGPathByteStream_h #include "wtf/Noncopyable.h" -#include "wtf/PassOwnPtr.h" +#include "wtf/PassRefPtr.h" +#include "wtf/RefCounted.h" #include "wtf/Vector.h" namespace blink { @@ -32,17 +33,17 @@ unsigned char bytes[sizeof(DataType)]; }; -class SVGPathByteStream { +class SVGPathByteStream : public RefCounted<SVGPathByteStream> { USING_FAST_MALLOC(SVGPathByteStream); public: - static PassOwnPtr<SVGPathByteStream> create() + static PassRefPtr<SVGPathByteStream> create() { - return adoptPtr(new SVGPathByteStream); + return adoptRef(new SVGPathByteStream); } - PassOwnPtr<SVGPathByteStream> copy() const + PassRefPtr<SVGPathByteStream> clone() const { - return adoptPtr(new SVGPathByteStream(m_data)); + return adoptRef(new SVGPathByteStream(m_data)); } typedef Vector<unsigned char> Data;
diff --git a/third_party/WebKit/Source/core/svg/SVGPathElement.cpp b/third_party/WebKit/Source/core/svg/SVGPathElement.cpp index cd50481..fb1f808c 100644 --- a/third_party/WebKit/Source/core/svg/SVGPathElement.cpp +++ b/third_party/WebKit/Source/core/svg/SVGPathElement.cpp
@@ -75,7 +75,7 @@ return svgStyle.d()->path(); } - return m_path->currentValue()->pathValue()->path(); + return m_path->currentValue()->pathValue()->cachedPath()->path(); } const SVGPathByteStream& SVGPathElement::pathByteStream() const
diff --git a/third_party/WebKit/Source/modules/mediastream/MediaDeviceInfo.cpp b/third_party/WebKit/Source/modules/mediastream/MediaDeviceInfo.cpp index bdbd5d25..11e9110 100644 --- a/third_party/WebKit/Source/modules/mediastream/MediaDeviceInfo.cpp +++ b/third_party/WebKit/Source/modules/mediastream/MediaDeviceInfo.cpp
@@ -25,6 +25,9 @@ #include "modules/mediastream/MediaDeviceInfo.h" +#include "bindings/core/v8/ScriptState.h" +#include "bindings/core/v8/ScriptValue.h" +#include "bindings/core/v8/V8ObjectBuilder.h" #include "wtf/text/WTFString.h" namespace blink { @@ -70,4 +73,14 @@ return m_webMediaDeviceInfo.groupId(); } +ScriptValue MediaDeviceInfo::toJSONForBinding(ScriptState* scriptState) +{ + V8ObjectBuilder result(scriptState); + result.addString("deviceId", deviceId()); + result.addString("kind", kind()); + result.addString("label", label()); + result.addString("groupId", groupId()); + return result.scriptValue(); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/modules/mediastream/MediaDeviceInfo.h b/third_party/WebKit/Source/modules/mediastream/MediaDeviceInfo.h index 9c893fb4..3de7534c 100644 --- a/third_party/WebKit/Source/modules/mediastream/MediaDeviceInfo.h +++ b/third_party/WebKit/Source/modules/mediastream/MediaDeviceInfo.h
@@ -33,6 +33,9 @@ namespace blink { +class ScriptState; +class ScriptValue; + class MODULES_EXPORT MediaDeviceInfo final : public GarbageCollectedFinalized<MediaDeviceInfo>, public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: @@ -43,6 +46,8 @@ String label() const; String groupId() const; + ScriptValue toJSONForBinding(ScriptState*); + DEFINE_INLINE_TRACE() { } private:
diff --git a/third_party/WebKit/Source/modules/mediastream/MediaDeviceInfo.idl b/third_party/WebKit/Source/modules/mediastream/MediaDeviceInfo.idl index 4d441f41..34b0e0c8 100644 --- a/third_party/WebKit/Source/modules/mediastream/MediaDeviceInfo.idl +++ b/third_party/WebKit/Source/modules/mediastream/MediaDeviceInfo.idl
@@ -37,4 +37,5 @@ readonly attribute MediaDeviceKind kind; readonly attribute DOMString label; readonly attribute DOMString groupId; + serializer = {attribute}; };
diff --git a/third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.cpp b/third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.cpp index 0ed5610..61c476fc 100644 --- a/third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.cpp +++ b/third_party/WebKit/Source/modules/mediastream/RTCPeerConnection.cpp
@@ -392,7 +392,7 @@ if (errorCallback) UseCounter::count(context, UseCounter::RTCPeerConnectionCreateOfferLegacyFailureCallback); else - UseCounter::count(context, UseCounter::RTCPeerConnectionCreateOfferLegacyNoFailureCallback); + UseCounter::countDeprecation(context, UseCounter::RTCPeerConnectionCreateOfferLegacyNoFailureCallback); if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState)) return; @@ -431,7 +431,7 @@ if (errorCallback) UseCounter::count(context, UseCounter::RTCPeerConnectionCreateAnswerLegacyFailureCallback); else - UseCounter::count(context, UseCounter::RTCPeerConnectionCreateAnswerLegacyNoFailureCallback); + UseCounter::countDeprecation(context, UseCounter::RTCPeerConnectionCreateAnswerLegacyNoFailureCallback); if (mediaConstraints.isObject()) UseCounter::count(context, UseCounter::RTCPeerConnectionCreateAnswerLegacyConstraints);
diff --git a/third_party/WebKit/Source/platform/Timer.cpp b/third_party/WebKit/Source/platform/Timer.cpp index 481cc31..4dbaea66 100644 --- a/third_party/WebKit/Source/platform/Timer.cpp +++ b/third_party/WebKit/Source/platform/Timer.cpp
@@ -40,15 +40,18 @@ namespace blink { -TimerBase::TimerBase() +TimerBase::TimerBase() : TimerBase(Platform::current()->currentThread()->scheduler()->timerTaskRunner()) { } + +TimerBase::TimerBase(WebTaskRunner* webTaskRunner) : m_nextFireTime(0) , m_repeatInterval(0) , m_cancellableTimerTask(nullptr) - , m_webScheduler(Platform::current()->currentThread()->scheduler()) + , m_webTaskRunner(webTaskRunner) #if ENABLE(ASSERT) , m_thread(currentThread()) #endif { + ASSERT(m_webTaskRunner); } TimerBase::~TimerBase() @@ -87,7 +90,7 @@ WebTaskRunner* TimerBase::timerTaskRunner() { - return m_webScheduler->timerTaskRunner(); + return m_webTaskRunner; } void TimerBase::setNextFireTime(double now, double delay) @@ -137,4 +140,10 @@ return a->m_nextFireTime < b->m_nextFireTime; } +// static +WebTaskRunner* TimerBase::UnthrottledWebTaskRunner() +{ + return Platform::current()->currentThread()->taskRunner(); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/platform/Timer.h b/third_party/WebKit/Source/platform/Timer.h index 558aefbb..0afafe7 100644 --- a/third_party/WebKit/Source/platform/Timer.h +++ b/third_party/WebKit/Source/platform/Timer.h
@@ -44,6 +44,7 @@ WTF_MAKE_NONCOPYABLE(TimerBase); public: TimerBase(); + explicit TimerBase(WebTaskRunner*); virtual ~TimerBase(); void start(double nextFireInterval, double repeatInterval, const WebTraceLocation&); @@ -74,6 +75,9 @@ bool operator()(const TimerBase* a, const TimerBase* b) const; }; +protected: + static WebTaskRunner* UnthrottledWebTaskRunner(); + private: virtual void fired() = 0; @@ -122,7 +126,7 @@ double m_repeatInterval; // 0 if not repeating WebTraceLocation m_location; CancellableTimerTask* m_cancellableTimerTask; // NOT OWNED - WebScheduler* m_webScheduler; // Not owned. + WebTaskRunner* m_webTaskRunner; // Not owned. #if ENABLE(ASSERT) ThreadIdentifier m_thread; @@ -151,13 +155,15 @@ template <typename TimerFiredClass> class Timer : public TimerBase { public: - typedef void (TimerFiredClass::*TimerFiredFunction)(Timer*); + using TimerFiredFunction = void (TimerFiredClass::*)(Timer<TimerFiredClass>*); Timer(TimerFiredClass* o, TimerFiredFunction f) : m_object(o), m_function(f) { } + ~Timer() override { } + protected: void fired() override { @@ -173,6 +179,11 @@ return TimerIsObjectAliveTrait<TimerFiredClass>::isHeapObjectAlive(m_object); } + Timer(TimerFiredClass* o, TimerFiredFunction f, WebTaskRunner* webTaskRunner) + : TimerBase(webTaskRunner), m_object(o), m_function(f) + { + } + private: // FIXME: Oilpan: TimerBase should be moved to the heap and m_object should be traced. // This raw pointer is safe as long as Timer<X> is held by the X itself (That's the case @@ -182,6 +193,21 @@ TimerFiredFunction m_function; }; +// This subclass of Timer posts its tasks on the current thread's default task runner. +// Tasks posted on there are not throttled when the tab is in the background. +template <typename TimerFiredClass> +class UnthrottledTimer : public Timer<TimerFiredClass> { +public: + using TimerFiredFunction = void (TimerFiredClass::*)(Timer<TimerFiredClass>*); + + ~UnthrottledTimer() override { } + + UnthrottledTimer(TimerFiredClass* timerFiredClass, TimerFiredFunction timerFiredFunction) + : Timer<TimerFiredClass>(timerFiredClass, timerFiredFunction, TimerBase::UnthrottledWebTaskRunner()) + { + } +}; + NO_LAZY_SWEEP_SANITIZE_ADDRESS inline bool TimerBase::isActive() const {
diff --git a/third_party/WebKit/Source/platform/TimerTest.cpp b/third_party/WebKit/Source/platform/TimerTest.cpp index 68096b0..9bbb0a71 100644 --- a/third_party/WebKit/Source/platform/TimerTest.cpp +++ b/third_party/WebKit/Source/platform/TimerTest.cpp
@@ -734,5 +734,30 @@ m_startTime + 28.0)); } +template <typename TimerFiredClass> +class TimerForTest : public Timer<TimerFiredClass> { +public: + using TimerFiredFunction = void (TimerFiredClass::*)(Timer<TimerFiredClass>*); + + ~TimerForTest() override { } + + TimerForTest(TimerFiredClass* timerFiredClass, TimerFiredFunction timerFiredFunction, WebTaskRunner* webTaskRunner) + : Timer<TimerFiredClass>(timerFiredClass, timerFiredFunction, webTaskRunner) + { + } +}; + +TEST_F(TimerTest, UserSuppliedWebTaskRunner) +{ + std::priority_queue<DelayedTask> timerTasks; + MockWebTaskRunner taskRunner(&timerTasks); + TimerForTest<TimerTest> timer(this, &TimerTest::countingTask, &taskRunner); + timer.startOneShot(0, BLINK_FROM_HERE); + + // Make sure the task was posted on taskRunner. + EXPECT_FALSE(timerTasks.empty()); +} + + } // namespace } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/ContiguousContainer.h b/third_party/WebKit/Source/platform/graphics/ContiguousContainer.h index ca63329..cd75242 100644 --- a/third_party/WebKit/Source/platform/graphics/ContiguousContainer.h +++ b/third_party/WebKit/Source/platform/graphics/ContiguousContainer.h
@@ -12,10 +12,10 @@ #include "wtf/Noncopyable.h" #include "wtf/OwnPtr.h" #include "wtf/TypeTraits.h" -#include "wtf/Utility.h" #include "wtf/Vector.h" #include <cstddef> #include <iterator> +#include <utility> namespace blink { @@ -151,7 +151,7 @@ static_assert(alignment % WTF_ALIGN_OF(DerivedElementType) == 0, "Derived type requires stronger alignment."); size_t allocSize = align(sizeof(DerivedElementType)); - return *new (allocate(allocSize, WTF_HEAP_PROFILER_TYPE_NAME(DerivedElementType))) DerivedElementType(WTF::forward<Args>(args)...); + return *new (allocate(allocSize, WTF_HEAP_PROFILER_TYPE_NAME(DerivedElementType))) DerivedElementType(std::forward<Args>(args)...); } void removeLast()
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintController.h b/third_party/WebKit/Source/platform/graphics/paint/PaintController.h index 844f9d8..627b16a 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/PaintController.h +++ b/third_party/WebKit/Source/platform/graphics/paint/PaintController.h
@@ -21,8 +21,8 @@ #include "wtf/HashMap.h" #include "wtf/HashSet.h" #include "wtf/PassOwnPtr.h" -#include "wtf/Utility.h" #include "wtf/Vector.h" +#include <utility> namespace blink { @@ -77,7 +77,7 @@ if (displayItemConstructionIsDisabled()) return; - DisplayItemClass& displayItem = m_newDisplayItemList.allocateAndConstruct<DisplayItemClass>(WTF::forward<Args>(args)...); + DisplayItemClass& displayItem = m_newDisplayItemList.allocateAndConstruct<DisplayItemClass>(std::forward<Args>(args)...); processNewItem(displayItem); } @@ -94,7 +94,7 @@ if (lastDisplayItemIsNoopBegin()) removeLastDisplayItem(); else - createAndAppend<DisplayItemClass>(WTF::forward<Args>(args)...); + createAndAppend<DisplayItemClass>(std::forward<Args>(args)...); } // Scopes must be used to avoid duplicated display item ids when we paint some object
diff --git a/third_party/WebKit/Source/platform/heap/Handle.h b/third_party/WebKit/Source/platform/heap/Handle.h index d340213..49d3f33 100644 --- a/third_party/WebKit/Source/platform/heap/Handle.h +++ b/third_party/WebKit/Source/platform/heap/Handle.h
@@ -52,6 +52,14 @@ namespace blink { +// Marker used to annotate persistent objects and collections with, +// so as to enable reliable testing for persistent references via +// a type trait (see TypeTraits.h's IsPersistentReferenceType<>.) +#define IS_PERSISTENT_REFERENCE_TYPE() \ + public: \ + using IsPersistentReferenceTypeMarker = int; \ + private: + enum WeaknessPersistentConfiguration { NonWeakPersistentConfiguration, WeakPersistentConfiguration @@ -64,6 +72,7 @@ template<typename T, WeaknessPersistentConfiguration weaknessConfiguration, CrossThreadnessPersistentConfiguration crossThreadnessConfiguration> class PersistentBase { + IS_PERSISTENT_REFERENCE_TYPE(); public: PersistentBase() : m_raw(nullptr) { @@ -531,6 +540,7 @@ // heap collections are always allocated off-heap. This allows persistent collections to be used in // DEFINE_STATIC_LOCAL et. al. WTF_USE_ALLOCATOR(PersistentHeapCollectionBase, WTF::PartitionAllocator); + IS_PERSISTENT_REFERENCE_TYPE(); public: PersistentHeapCollectionBase() {
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollableAreaTest.cpp b/third_party/WebKit/Source/platform/scroll/ScrollableAreaTest.cpp index 8f4b977..cbff9c0 100644 --- a/third_party/WebKit/Source/platform/scroll/ScrollableAreaTest.cpp +++ b/third_party/WebKit/Source/platform/scroll/ScrollableAreaTest.cpp
@@ -9,8 +9,6 @@ #include "platform/scroll/ScrollbarThemeMock.h" #include "platform/testing/TestingPlatformSupport.h" #include "public/platform/Platform.h" -#include "public/platform/WebScheduler.h" -#include "public/platform/WebThread.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -64,46 +62,6 @@ IntPoint m_maximumScrollPosition; }; -class FakeWebThread : public WebThread { -public: - FakeWebThread() { } - ~FakeWebThread() override { } - - WebTaskRunner* taskRunner() override - { - ASSERT_NOT_REACHED(); - return nullptr; - } - - bool isCurrentThread() const override - { - ASSERT_NOT_REACHED(); - return true; - } - - WebScheduler* scheduler() const override - { - return nullptr; - } -}; - -// The FakePlatform is needed because ScrollAnimatorMac's constructor creates several timers. -// We need just enough scaffolding for the Timer constructor to not segfault. -class FakePlatform : public TestingPlatformSupport { -public: - explicit FakePlatform(Config& config) : TestingPlatformSupport(config) { } - - ~FakePlatform() override { } - - WebThread* currentThread() override - { - return &m_webThread; - } - -private: - FakeWebThread m_webThread; -}; - } // namespace class ScrollableAreaTest : public testing::Test { @@ -115,7 +73,7 @@ m_oldPlatform = Platform::current(); TestingPlatformSupport::Config config; config.compositorSupport = m_oldPlatform->compositorSupport(); - m_fakePlatform = adoptPtr(new FakePlatform(config)); + m_fakePlatform = adoptPtr(new TestingPlatformSupportWithMockScheduler(config)); Platform::initialize(m_fakePlatform.get()); } @@ -126,7 +84,7 @@ } private: - OwnPtr<FakePlatform> m_fakePlatform; + OwnPtr<TestingPlatformSupportWithMockScheduler> m_fakePlatform; Platform* m_oldPlatform; // Not owned. };
diff --git a/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.cpp b/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.cpp index e62d6721..2382843 100644 --- a/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.cpp +++ b/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.cpp
@@ -120,4 +120,112 @@ return m_oldPlatform ? m_oldPlatform->currentThread() : nullptr; } +class TestingPlatformMockWebTaskRunner : public WebTaskRunner { + WTF_MAKE_NONCOPYABLE(TestingPlatformMockWebTaskRunner); +public: + explicit TestingPlatformMockWebTaskRunner(Deque<OwnPtr<WebTaskRunner::Task>>* tasks) : m_tasks(tasks) { } + ~TestingPlatformMockWebTaskRunner() override { } + + void postTask(const WebTraceLocation&, Task* task) override + { + m_tasks->append(adoptPtr(task)); + } + + void postDelayedTask(const WebTraceLocation&, Task*, double delayMs) override + { + ASSERT_NOT_REACHED(); + } + + WebTaskRunner* clone() override + { + ASSERT_NOT_REACHED(); + return nullptr; + } + +private: + Deque<OwnPtr<WebTaskRunner::Task>>* m_tasks; // NOT OWNED +}; + +// TestingPlatformMockScheduler definition: + +TestingPlatformMockScheduler::TestingPlatformMockScheduler() + : m_mockWebTaskRunner(adoptPtr(new TestingPlatformMockWebTaskRunner(&m_tasks))) { } + +TestingPlatformMockScheduler::~TestingPlatformMockScheduler() { } + +WebTaskRunner* TestingPlatformMockScheduler::loadingTaskRunner() +{ + return m_mockWebTaskRunner.get(); +} + +WebTaskRunner* TestingPlatformMockScheduler::timerTaskRunner() +{ + return m_mockWebTaskRunner.get(); +} + +void TestingPlatformMockScheduler::runSingleTask() +{ + if (m_tasks.isEmpty()) + return; + m_tasks.takeFirst()->run(); +} + +void TestingPlatformMockScheduler::runAllTasks() +{ + while (!m_tasks.isEmpty()) + m_tasks.takeFirst()->run(); +} + +class TestingPlatformMockWebThread : public WebThread { + WTF_MAKE_NONCOPYABLE(TestingPlatformMockWebThread); +public: + TestingPlatformMockWebThread() : m_mockWebScheduler(adoptPtr(new TestingPlatformMockScheduler)) { } + ~TestingPlatformMockWebThread() override { } + + WebTaskRunner* taskRunner() override + { + return m_mockWebScheduler->timerTaskRunner(); + } + + bool isCurrentThread() const override + { + ASSERT_NOT_REACHED(); + return true; + } + + WebScheduler* scheduler() const override + { + return m_mockWebScheduler.get(); + } + + TestingPlatformMockScheduler* mockWebScheduler() + { + return m_mockWebScheduler.get(); + } + +private: + OwnPtr<TestingPlatformMockScheduler> m_mockWebScheduler; +}; + +// TestingPlatformSupportWithMockScheduler definition: + +TestingPlatformSupportWithMockScheduler::TestingPlatformSupportWithMockScheduler() + : m_mockWebThread(adoptPtr(new TestingPlatformMockWebThread())) { } + +TestingPlatformSupportWithMockScheduler::TestingPlatformSupportWithMockScheduler(const Config& config) + : TestingPlatformSupport(config) + , m_mockWebThread(adoptPtr(new TestingPlatformMockWebThread())) { } + +TestingPlatformSupportWithMockScheduler::~TestingPlatformSupportWithMockScheduler() { } + +WebThread* TestingPlatformSupportWithMockScheduler::currentThread() +{ + return m_mockWebThread.get(); +} + +TestingPlatformMockScheduler* TestingPlatformSupportWithMockScheduler::mockWebScheduler() +{ + return m_mockWebThread->mockWebScheduler(); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.h b/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.h index 7759157..9ab6623 100644 --- a/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.h +++ b/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.h
@@ -35,10 +35,14 @@ #include "public/platform/Platform.h" #include "public/platform/WebCompositorSupport.h" #include "public/platform/WebDiscardableMemory.h" +#include "public/platform/WebScheduler.h" +#include "public/platform/WebThread.h" #include "wtf/Vector.h" namespace blink { +class TestingPlatformMockWebTaskRunner; +class TestingPlatformMockWebThread; class WebCompositorSupport; class WebThread; @@ -61,7 +65,38 @@ class TestingCompositorSupport : public WebCompositorSupport { }; +class TestingPlatformMockScheduler : public WebScheduler { + WTF_MAKE_NONCOPYABLE(TestingPlatformMockScheduler); +public: + TestingPlatformMockScheduler(); + ~TestingPlatformMockScheduler() override; + + void runSingleTask(); + void runAllTasks(); + + // WebScheduler implementation: + WebTaskRunner* loadingTaskRunner() override; + WebTaskRunner* timerTaskRunner() override; + void shutdown() override {} + bool shouldYieldForHighPriorityWork() override { return false; } + bool canExceedIdleDeadlineIfRequired() override { return false; } + void postIdleTask(const WebTraceLocation&, WebThread::IdleTask*) override { } + void postNonNestableIdleTask(const WebTraceLocation&, WebThread::IdleTask*) override { } + void postIdleTaskAfterWakeup(const WebTraceLocation&, WebThread::IdleTask*) override { } + WebPassOwnPtr<WebViewScheduler> createWebViewScheduler(blink::WebView*) override { return nullptr; } + void suspendTimerQueue() override { } + void resumeTimerQueue() override { } + void addPendingNavigation() override { } + void removePendingNavigation() override { } + void onNavigationStarted() override { } + +private: + Deque<OwnPtr<WebTaskRunner::Task>> m_tasks; + OwnPtr<TestingPlatformMockWebTaskRunner> m_mockWebTaskRunner; +}; + class TestingPlatformSupport : public Platform { + WTF_MAKE_NONCOPYABLE(TestingPlatformSupport); public: struct Config { Config() @@ -91,6 +126,21 @@ Platform* const m_oldPlatform; }; +class TestingPlatformSupportWithMockScheduler : public TestingPlatformSupport { + WTF_MAKE_NONCOPYABLE(TestingPlatformSupportWithMockScheduler); +public: + TestingPlatformSupportWithMockScheduler(); + explicit TestingPlatformSupportWithMockScheduler(const Config&); + ~TestingPlatformSupportWithMockScheduler() override; + + // Platform: + WebThread* currentThread() override; + TestingPlatformMockScheduler* mockWebScheduler(); + +protected: + OwnPtr<TestingPlatformMockWebThread> m_mockWebThread; +}; + } // namespace blink #endif // TestingPlatformSupport_h
diff --git a/third_party/WebKit/Source/platform/threading/BackgroundTaskRunner.cpp b/third_party/WebKit/Source/platform/threading/BackgroundTaskRunner.cpp index d5f9bdf42..8a757d4 100644 --- a/third_party/WebKit/Source/platform/threading/BackgroundTaskRunner.cpp +++ b/third_party/WebKit/Source/platform/threading/BackgroundTaskRunner.cpp
@@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/location.h" #include "base/threading/worker_pool.h" +#include "public/platform/WebTraceLocation.h" namespace blink { @@ -15,9 +16,10 @@ (*closure)(); } -void BackgroundTaskRunner::postOnBackgroundThread(PassOwnPtr<Closure> closure, TaskSize taskSize) +void BackgroundTaskRunner::postOnBackgroundThread(const WebTraceLocation& location, PassOwnPtr<Closure> closure, TaskSize taskSize) { - base::WorkerPool::PostTask(FROM_HERE, base::Bind(&RunBackgroundTask, closure), taskSize == TaskSizeLongRunningTask); + tracked_objects::Location baseLocation(location.functionName(), location.fileName(), 0, nullptr); + base::WorkerPool::PostTask(baseLocation, base::Bind(&RunBackgroundTask, closure), taskSize == TaskSizeLongRunningTask); } } // namespace blink
diff --git a/third_party/WebKit/Source/platform/threading/BackgroundTaskRunner.h b/third_party/WebKit/Source/platform/threading/BackgroundTaskRunner.h index ff2e94a..4f650052 100644 --- a/third_party/WebKit/Source/platform/threading/BackgroundTaskRunner.h +++ b/third_party/WebKit/Source/platform/threading/BackgroundTaskRunner.h
@@ -11,6 +11,8 @@ namespace blink { +class WebTraceLocation; + namespace BackgroundTaskRunner { enum TaskSize { @@ -18,7 +20,7 @@ TaskSizeLongRunningTask, }; -PLATFORM_EXPORT void postOnBackgroundThread(PassOwnPtr<Closure>, TaskSize); +PLATFORM_EXPORT void postOnBackgroundThread(const WebTraceLocation&, PassOwnPtr<Closure>, TaskSize); } // BackgroundTaskRunner
diff --git a/third_party/WebKit/Source/platform/threading/BackgroundTaskRunnerTest.cpp b/third_party/WebKit/Source/platform/threading/BackgroundTaskRunnerTest.cpp index fde843f..dd26598 100644 --- a/third_party/WebKit/Source/platform/threading/BackgroundTaskRunnerTest.cpp +++ b/third_party/WebKit/Source/platform/threading/BackgroundTaskRunnerTest.cpp
@@ -6,6 +6,7 @@ #include "platform/ThreadSafeFunctional.h" #include "public/platform/Platform.h" +#include "public/platform/WebTraceLocation.h" #include "testing/gtest/include/gtest/gtest.h" @@ -24,7 +25,7 @@ TEST_F(BackgroundTaskRunnerTest, RunShortTaskOnBackgroundThread) { OwnPtr<WebWaitableEvent> doneEvent = adoptPtr(Platform::current()->createWaitableEvent()); - BackgroundTaskRunner::postOnBackgroundThread(threadSafeBind(&PingPongTask, AllowCrossThreadAccess(doneEvent.get())), BackgroundTaskRunner::TaskSizeShortRunningTask); + BackgroundTaskRunner::postOnBackgroundThread(BLINK_FROM_HERE, threadSafeBind(&PingPongTask, AllowCrossThreadAccess(doneEvent.get())), BackgroundTaskRunner::TaskSizeShortRunningTask); // Test passes by not hanging on the following wait(). doneEvent->wait(); } @@ -32,7 +33,7 @@ TEST_F(BackgroundTaskRunnerTest, RunLongTaskOnBackgroundThread) { OwnPtr<WebWaitableEvent> doneEvent = adoptPtr(Platform::current()->createWaitableEvent()); - BackgroundTaskRunner::postOnBackgroundThread(threadSafeBind(&PingPongTask, AllowCrossThreadAccess(doneEvent.get())), BackgroundTaskRunner::TaskSizeLongRunningTask); + BackgroundTaskRunner::postOnBackgroundThread(BLINK_FROM_HERE, threadSafeBind(&PingPongTask, AllowCrossThreadAccess(doneEvent.get())), BackgroundTaskRunner::TaskSizeLongRunningTask); // Test passes by not hanging on the following wait(). doneEvent->wait(); }
diff --git a/third_party/WebKit/Source/wtf/LeakAnnotations.h b/third_party/WebKit/Source/wtf/LeakAnnotations.h index c19e56d..6697ee4d 100644 --- a/third_party/WebKit/Source/wtf/LeakAnnotations.h +++ b/third_party/WebKit/Source/wtf/LeakAnnotations.h
@@ -103,7 +103,7 @@ } NoType; // Check if class T has public method "T* registerAsStaticReference()". - template<typename V> static YesType checkHasRegisterAsStaticReferenceMethod(V* p, typename std::enable_if<IsSubclass<V, typename std::remove_pointer<decltype(p->registerAsStaticReference())>::type>::value>::Type* = 0); + template<typename V> static YesType checkHasRegisterAsStaticReferenceMethod(V* p, typename std::enable_if<IsSubclass<V, typename std::remove_pointer<decltype(p->registerAsStaticReference())>::type>::value>::type* = 0); template<typename V> static NoType checkHasRegisterAsStaticReferenceMethod(...); public:
diff --git a/third_party/WebKit/Source/wtf/Optional.h b/third_party/WebKit/Source/wtf/Optional.h index b64af3c..c4f931e 100644 --- a/third_party/WebKit/Source/wtf/Optional.h +++ b/third_party/WebKit/Source/wtf/Optional.h
@@ -9,9 +9,9 @@ #include "wtf/Assertions.h" #include "wtf/Noncopyable.h" #include "wtf/StdLibExtras.h" -#include "wtf/Utility.h" #include <new> +#include <utility> namespace WTF { @@ -54,7 +54,7 @@ { RELEASE_ASSERT(!m_ptr); m_ptr = reinterpret_cast_ptr<T*>(&m_storage.buffer); - new (m_ptr) T(forward<Args>(args)...); + new (m_ptr) T(std::forward<Args>(args)...); } private:
diff --git a/third_party/WebKit/Source/wtf/StdLibExtras.h b/third_party/WebKit/Source/wtf/StdLibExtras.h index 623fd15a..824c579a 100644 --- a/third_party/WebKit/Source/wtf/StdLibExtras.h +++ b/third_party/WebKit/Source/wtf/StdLibExtras.h
@@ -59,6 +59,14 @@ }; #endif +// A direct static local to a Blink garbage collected objects isn't allowed; +// must be wrapped up with a persistent reference. +#define STATIC_ASSERT_FOR_LOCAL_WITH_GARBAGE_COLLECTED_TYPE(Name, Type) \ + using Name##NoConstType = std::remove_const<Type>::type; \ + using Name##NoPointerType = std::remove_pointer<Name##NoConstType>::type; \ + using Name##NoReferenceType = std::remove_reference<Name##NoPointerType>::type; \ + static_assert(!WTF::IsGarbageCollectedType<Name##NoReferenceType>::value || WTF::IsPersistentReferenceType<Name##NoReferenceType>::value, "Garbage collected static local needs to be wrapped up with a persistent reference") + // Use DEFINE_STATIC_LOCAL() to declare and define a static local variable (static T;) // so that it is leaked and its destructors are not called at exit. // @@ -68,13 +76,15 @@ // LEAK_SANITIZER_REGISTER_STATIC_LOCAL() takes care of the details. // #if ENABLE(ASSERT) -#define DEFINE_STATIC_LOCAL(type, name, arguments) \ - static StaticLocalVerifier name##StaticLocalVerifier; \ - ASSERT(name##StaticLocalVerifier.isNotRacy()); \ - static type& name = *LEAK_SANITIZER_REGISTER_STATIC_LOCAL(type, new type arguments) +#define DEFINE_STATIC_LOCAL(Type, Name, Arguments) \ + STATIC_ASSERT_FOR_LOCAL_WITH_GARBAGE_COLLECTED_TYPE(Name, Type); \ + static StaticLocalVerifier Name##StaticLocalVerifier; \ + ASSERT(Name##StaticLocalVerifier.isNotRacy()); \ + static Type& Name = *LEAK_SANITIZER_REGISTER_STATIC_LOCAL(Type, new Type Arguments) #else -#define DEFINE_STATIC_LOCAL(type, name, arguments) \ - static type& name = *LEAK_SANITIZER_REGISTER_STATIC_LOCAL(type, new type arguments) +#define DEFINE_STATIC_LOCAL(Type, Name, Arguments) \ + STATIC_ASSERT_FOR_LOCAL_WITH_GARBAGE_COLLECTED_TYPE(Name, Type); \ + static Type& Name = *LEAK_SANITIZER_REGISTER_STATIC_LOCAL(Type, new Type Arguments) #endif // Use this to declare and define a static local pointer to a ref-counted object so that
diff --git a/third_party/WebKit/Source/wtf/TypeTraits.h b/third_party/WebKit/Source/wtf/TypeTraits.h index 1d938b5..002ec4f 100644 --- a/third_party/WebKit/Source/wtf/TypeTraits.h +++ b/third_party/WebKit/Source/wtf/TypeTraits.h
@@ -228,6 +228,19 @@ }; template<typename T> +class IsPersistentReferenceType { + typedef char YesType; + typedef struct NoType { + char padding[8]; + } NoType; + + template <typename U> static YesType checkPersistentReferenceType(typename U::IsPersistentReferenceTypeMarker*); + template <typename U> static NoType checkPersistentReferenceType(...); +public: + static const bool value = (sizeof(YesType) == sizeof(checkPersistentReferenceType<T>(nullptr))); +}; + +template<typename T> class IsPointerToGarbageCollectedType { public: static const bool value = false;
diff --git a/third_party/WebKit/Source/wtf/Utility.h b/third_party/WebKit/Source/wtf/Utility.h deleted file mode 100644 index c5fea33..0000000 --- a/third_party/WebKit/Source/wtf/Utility.h +++ /dev/null
@@ -1,23 +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 Utility_h -#define Utility_h - -#include "wtf/TypeTraits.h" - -namespace WTF { - -// TODO(jbroman): When a C++11 standard library is available, replace this with -// std::forward from <utility>. - -template <typename T> -T&& forward(typename std::remove_reference<T>::type& t) { return static_cast<T&&>(t); } - -template <typename T> -T&& forward(typename std::remove_reference<T>::type&& t) { return static_cast<T&&>(t); } - -} // namespace WTF - -#endif // Utility_h
diff --git a/third_party/WebKit/Source/wtf/wtf.gypi b/third_party/WebKit/Source/wtf/wtf.gypi index 305d9fc..6560461 100644 --- a/third_party/WebKit/Source/wtf/wtf.gypi +++ b/third_party/WebKit/Source/wtf/wtf.gypi
@@ -124,7 +124,6 @@ 'Uint16Array.h', 'Uint32Array.h', 'Uint8Array.h', - 'Utility.h', 'Vector.h', 'VectorTraits.h', 'WTF.cpp',
diff --git a/third_party/WebKit/public/blink_headers.gypi b/third_party/WebKit/public/blink_headers.gypi index 6831803..fcb9d72 100644 --- a/third_party/WebKit/public/blink_headers.gypi +++ b/third_party/WebKit/public/blink_headers.gypi
@@ -479,7 +479,7 @@ "web/WebSharedWorker.h", "web/WebSharedWorkerClient.h", "web/WebSharedWorkerConnector.h", - "web/WebWorkerCreationErrors.h", + "web/WebSharedWorkerCreationErrors.h", "web/WebSharedWorkerRepositoryClient.h", "web/WebSocket.h", "web/WebSocketClient.h",
diff --git a/third_party/widevine/cdm/BUILD.gn b/third_party/widevine/cdm/BUILD.gn index 66034cc..af0dd6c 100644 --- a/third_party/widevine/cdm/BUILD.gn +++ b/third_party/widevine/cdm/BUILD.gn
@@ -134,7 +134,6 @@ if (is_linux) { ldflags = [ rebase_path("$root_out_dir/libwidevinecdm.so", root_build_dir) ] - libs = [ "rt" ] } else if (is_win) { ldflags = [ rebase_path("$root_out_dir/widevinecdm.dll.lib", root_build_dir) ]
diff --git a/tools/android/customtabs_benchmark/OWNERS b/tools/android/customtabs_benchmark/OWNERS new file mode 100644 index 0000000..c319c21 --- /dev/null +++ b/tools/android/customtabs_benchmark/OWNERS
@@ -0,0 +1,3 @@ +lizeb@chromium.org +pasko@chromium.org +yusufo@chromium.org
diff --git a/tools/android/customtabs_benchmark/scripts/__init__.py b/tools/android/customtabs_benchmark/scripts/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tools/android/customtabs_benchmark/scripts/__init__.py
diff --git a/tools/android/customtabs_benchmark/scripts/customtabs_benchmark.py b/tools/android/customtabs_benchmark/scripts/customtabs_benchmark.py new file mode 100755 index 0000000..9bf4343a2 --- /dev/null +++ b/tools/android/customtabs_benchmark/scripts/customtabs_benchmark.py
@@ -0,0 +1,170 @@ +#!/usr/bin/python +# +# 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. + +"""Loops Custom Tabs tests and outputs the results into a CSV file.""" + +import logging +import optparse +import os +import re +import sys +import time + +sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, + os.pardir, os.pardir, 'build', 'android')) + +from pylib.device import device_errors +from pylib.device import device_utils +from pylib.device import intent +from pylib.perf import cache_control + + +def RunOnce(device, url, warmup, no_prerendering, delay_to_may_launch_url, + delay_to_launch_url, cold): + """Runs a test on a device once. + + Args: + device: (DeviceUtils) device to run the tests on. + warmup: (bool) Whether to call warmup. + no_prerendering: (bool) Whether to disable prerendering. + delay_to_may_launch_url: (int) Delay to mayLaunchUrl() in ms. + delay_to_launch_url: (int) Delay to launchUrl() in ms. + cold: (bool) Whether the page cache should be dropped. + + Returns: + The output line (str), like this (one line only): + <warmup>,<no_prerendering>,<delay_to_may_launch_url>,<intent_sent_ms>, + <page_load_started_ms>,<page_load_finished_ms> + or None on error. + """ + launch_intent = intent.Intent( + action='android.intent.action.MAIN', + package='org.chromium.customtabsclient.test', + activity='org.chromium.customtabs.test.MainActivity', + extras={'url': url, 'warmup': warmup, 'no_prerendering': no_prerendering, + 'delay_to_may_launch_url': delay_to_may_launch_url, + 'delay_to_launch_url': delay_to_launch_url}) + result_line_re = re.compile(r'W/CUSTOMTABSBENCH.*: (.*)') + logcat_monitor = device.GetLogcatMonitor(clear=True) + logcat_monitor.Start() + device.ForceStop('com.google.android.apps.chrome') + device.ForceStop('org.chromium.customtabsclient.test') + if cold: + if not device.HasRoot(): + device.EnableRoot() + cache_control.CacheControl(device).DropRamCaches() + device.StartActivity(launch_intent, blocking=True) + match = None + try: + match = logcat_monitor.WaitFor(result_line_re, timeout=10) + except device_errors.CommandTimeoutError as e: + logging.warning('Timeout waiting for the result line') + return match.group(1) if match is not None else None + + +def LoopOnDevice(device, url, warmup, no_prerendering, delay_to_may_launch_url, + delay_to_launch_url, cold, output_filename, once=False): + """Loops the tests on a device. + + Args: + device: (DeviceUtils) device to run the tests on. + url: (str) URL to navigate to. + warmup: (bool) Whether to call warmup. + no_prerendering: (bool) Whether to disable prerendering. + delay_to_may_launch_url: (int) Delay to mayLaunchUrl() in ms. + delay_to_launch_url: (int) Delay to launchUrl() in ms. + cold: (bool) Whether the page cache should be dropped. + output_filename: (str) Output filename. '-' for stdout. + once: (bool) Run only once. + """ + while True: + out = sys.stdout if output_filename == '-' else open(output_filename, 'a') + try: + result = RunOnce(device, url, warmup, no_prerendering, + delay_to_may_launch_url, delay_to_launch_url, cold) + if result is not None: + out.write(result + '\n') + out.flush() + if once: + return + time.sleep(10) + finally: + if output_filename != '-': + out.close() + + +def ProcessOutput(filename): + """Reads an output file, and returns a processed numpy array. + + Args: + filename: (str) file to process. + + Returns: + A numpy structured array. + """ + import numpy as np + data = np.genfromtxt(filename, delimiter=',') + result = np.array(np.zeros(len(data)), + dtype=[('warmup', bool), ('no_prerendering', bool), + ('delay_to_may_launch_url', np.int32), + ('delay_to_launch_url', np.int32), + ('commit', np.int32), ('plt', np.int32)]) + result['warmup'] = data[:, 0] + result['no_prerendering'] = data[:, 1] + result['delay_to_may_launch_url'] = data[:, 2] + result['delay_to_launch_url'] = data[:, 3] + result['commit'] = data[:, 5] - data[:, 4] + result['plt'] = data[:, 6] - data[:, 4] + return result + + +def _CreateOptionParser(): + parser = optparse.OptionParser(description='Loops Custom Tabs tests on a ' + 'device, and outputs the navigation timings ' + 'in a CSV file.') + parser.add_option('--device', help='Device ID') + parser.add_option('--url', help='URL to navigate to.', + default='https://www.android.com') + parser.add_option('--warmup', help='Call warmup.', default=False, + action='store_true') + parser.add_option('--no_prerendering', help='Disable prerendering.', + default=False, action='store_true') + parser.add_option('--delay_to_may_launch_url', + help='Delay before calling mayLaunchUrl() in ms.', + type='int') + parser.add_option('--delay_to_launch_url', + help='Delay before calling launchUrl() in ms.', + type='int') + parser.add_option('--cold', help='Purge the page cache before each run.', + default=False, action='store_true') + parser.add_option('--output_file', help='Output file (append). "-" for ' + 'stdout') + parser.add_option('--once', help='Run only one iteration.', + action='store_true', default=False) + return parser + + +def main(): + parser = _CreateOptionParser() + options, _ = parser.parse_args() + devices = device_utils.DeviceUtils.HealthyDevices() + device = devices[0] + if len(devices) != 1 and options.device is None: + logging.error('Several devices attached, must specify one with --device.') + sys.exit(0) + if options.device is not None: + matching_devices = [d for d in devices if str(d) == options.device] + if len(matching_devices) == 0: + logging.error('Device not found.') + sys.exit(0) + device = matching_devices[0] + LoopOnDevice(device, options.url, options.warmup, options.no_prerendering, + options.delay_to_may_launch_url, options.delay_to_launch_url, + options.cold, options.output_file, options.once) + + +if __name__ == '__main__': + main()
diff --git a/tools/android/customtabs_benchmark/scripts/run_benchmark.py b/tools/android/customtabs_benchmark/scripts/run_benchmark.py new file mode 100755 index 0000000..5df547b --- /dev/null +++ b/tools/android/customtabs_benchmark/scripts/run_benchmark.py
@@ -0,0 +1,140 @@ +#!/usr/bin/env python +# +# 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. + +"""Loops Custom Tabs tests and outputs the results into a CSV file.""" + +import copy +import json +import logging +import optparse +import os +import random +import sys +import threading + +sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, + os.pardir, os.pardir, 'build', 'android')) + +from pylib.device import device_utils + +import customtabs_benchmark + + +_KEYS = ['url', 'warmup', 'no_prerendering', 'delay_to_may_launch_url', + 'delay_to_launch_url', 'cold'] + + +def _ParseConfiguration(filename): + """Reads a JSON file and returns a list of configurations. + + Each valid value in the JSON file can be either a scalar or a list of + values. This function expands the scalar values to be lists. All list must + have the same length. + + Sample configuration: + { + "url": "https://www.android.com", + "warmup": [false, true], + "no_prerendering": false, + "delay_to_may_launch_url": [-1, 1000], + "delay_to_launch_url": [-1, 1000], + "cold": true + } + + Args: + filename: (str) Point to a file containins a JSON dictionnary of config + values. + + Returns: + A list of configurations, where each value is specified. + """ + config = json.load(open(filename, 'r')) + has_all_values = all(k in config for k in _KEYS) + assert has_all_values + config['url'] = str(config['url']) # Intents don't like unicode. + has_list = any(isinstance(config[k], list) for k in _KEYS) + if not has_list: + return [config] + list_keys = [k for k in _KEYS if isinstance(config[k], list)] + list_length = len(config[list_keys[0]]) + assert all(len(config[k]) == list_length for k in list_keys) + result = [] + for i in range(list_length): + result.append(copy.deepcopy(config)) + for k in list_keys: + result[-1][k] = result[-1][k][i] + return result + + +def _CreateOptionParser(): + parser = optparse.OptionParser(description='Loops tests on all attached ' + 'devices, with randomly selected ' + 'configurations, and outputs the results in ' + 'CSV files.') + parser.add_option('--config', help='JSON configuration file. Required.') + parser.add_option('--output_file_prefix', help='Output file prefix. Actual ' + 'output file is prefix_<device ID>.csv', default='result') + return parser + + +def _RunOnDevice(device, output_filename, configs, should_stop): + """Loops the tests described by configs on a device. + + Args: + device: (DeviceUtils) device to run the tests on. + output_filename: (str) Output file name. + configs: (list of dict) List of configurations. + should_stop: (Event) When set, this function should return. + """ + with open(output_filename, 'a') as f: + while not should_stop.is_set(): + config = configs[random.randint(0, len(configs) - 1)] + result = customtabs_benchmark.RunOnce( + device, config['url'], config['warmup'], config['no_prerendering'], + config['delay_to_may_launch_url'], config['delay_to_launch_url'], + config['cold']) + if result is not None: + f.write(result + '\n') + f.flush() + should_stop.wait(10.) + + +def _Run(output_file_prefix, configs): + """Loops the tests described by the configs on connected devices. + + Args: + output_file_prefix: (str) Prefix for the output file name. + configs: (list of dict) List of configurations. + """ + devices = device_utils.DeviceUtils.HealthyDevices() + should_stop = threading.Event() + threads = [] + for device in devices: + output_filename = '%s_%s.csv' % (output_file_prefix, str(device)) + thread = threading.Thread( + target=_RunOnDevice, + args=(device, output_filename, configs, should_stop)) + thread.start() + threads.append(thread) + for thread in threads: + try: + thread.join() + except KeyboardInterrupt as e: + should_stop.set() + + +def main(): + parser = _CreateOptionParser() + options, _ = parser.parse_args() + if options.config is None: + logging.error('A configuration file must be provided.') + sys.exit(0) + configs = _ParseConfiguration(options.config) + _Run(options.output_file_prefix, configs) + + +if __name__ == '__main__': + main()
diff --git a/tools/cr/cr/commands/init.py b/tools/cr/cr/commands/init.py index 7b09330..04692ba 100644 --- a/tools/cr/cr/commands/init.py +++ b/tools/cr/cr/commands/init.py
@@ -87,7 +87,7 @@ # substrings. This is done to support "linuxchromeos" and "linux". platform = max(matches, key=len) all_matches_are_substrings = all(p in platform for p in matches) - if all_matches_are_substrings or not matches: + if not all_matches_are_substrings or not matches: print 'Platform is not set, and could not be guessed from', base print 'Should be one of', ','.join(platforms) if len(matches) > 1:
diff --git a/tools/gritsettings/resource_ids b/tools/gritsettings/resource_ids index 9324518c..c1f41e0 100644 --- a/tools/gritsettings/resource_ids +++ b/tools/gritsettings/resource_ids
@@ -205,9 +205,10 @@ }, "ios/chrome/app/resources/ios_resources.grd": { "structures": [26150], + "includes": [26160], }, "ios/chrome/app/theme/ios_theme_resources.grd": { - "structures": [26155], + "structures": [26170], }, "ios/chrome/today_extension/strings/ios_today_extension_strings.grd": { "messages": [26635],
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index e7833c3..6ba4135 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -510,7 +510,7 @@ 'WebKit Linux': 'swarming_gn_release_bot_x64', 'WebKit Linux Trusty': 'swarming_gn_release_bot_x64', 'WebKit Linux 32': 'swarming_gyp_release_bot_x86', - 'WebKit Linux Oilpan': 'swarming_gn_oilpan_release_bot_x64', + 'WebKit Linux Oilpan Builder': 'swarming_gn_oilpan_release_bot_x64', 'WebKit Linux ASAN': 'swarming_gyp_asan_lsan_release_bot_x64', 'WebKit Linux Oilpan ASAN': 'swarming_gyp_oilpan_asan_lsan_release_bot_x64', 'WebKit Linux MSAN': 'swarming_gyp_msan_release_bot_x64',
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 5303c257..d2b4dd32 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -12095,6 +12095,13 @@ <description>Please enter the description of this user action.</description> </action> +<action name="Signin_AddAccountToDevice"> + <owner>gogerald@chromium.org</owner> + <description> + Recorded when the user chooses to add an account to device. + </description> +</action> + <action name="Signin_EnterpriseAccountPrompt_Cancel"> <owner>gogerald@chromium.org</owner> <description> @@ -12157,6 +12164,13 @@ </description> </action> +<action name="Signin_Impression_FromBookmarkManager"> + <owner>gogerald@chromium.org</owner> + <description> + Recorded when showing sign in entry in the bookmark manager. + </description> +</action> + <action name="Signin_Impression_FromCloudPrint"> <owner>gogerald@chromium.org</owner> <description> @@ -12190,6 +12204,27 @@ </description> </action> +<action name="Signin_Impression_FromRecentTabs"> + <owner>gogerald@chromium.org</owner> + <description> + Recorded when showing sign in entry in the recent tabs page. + </description> +</action> + +<action name="Signin_Impression_FromSigninPromo"> + <owner>gogerald@chromium.org</owner> + <description> + Recorded when showing sign in entry in the sign in promo. + </description> +</action> + +<action name="Signin_Impression_FromStartPage"> + <owner>gogerald@chromium.org</owner> + <description> + Recorded when showing sign in entry in the first run experience. + </description> +</action> + <action name="Signin_Show_EnterpriseAccountPrompt"> <owner>gogerald@chromium.org</owner> <description>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index f8929d4..8eded3c8 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -26870,7 +26870,7 @@ <histogram name="Net.SpdyVersion" enum="ProtocolVersion"> <obsolete> Deprecated on 2014-09-11, because the uploaded values were changing as - protocols were removed, therefore statistics couldn't be combined accross + protocols were removed, therefore statistics couldn't be combined across different builds. Replaced by Net.SpdyVersion2. </obsolete> <owner>rch@chromium.org</owner> @@ -43803,7 +43803,7 @@ </histogram> <histogram name="ServiceWorker.RequestTimeouts.Count" - enum="ServiceWorkerVersion.RequestType"> + enum="ServiceWorkerMetrics.EventType"> <owner>jeremyarcher@google.com</owner> <summary> The number of Service Worker request timeouts, by request type. @@ -44595,6 +44595,15 @@ </summary> </histogram> +<histogram name="Settings.TimeToFirstSearch" units="milliseconds"> + <owner>dschuyler@chromium.org</owner> + <summary> + The time between when the chrome://settings page is opened to the first time + a search is done within that page. This is intended to evaluate how long a + user looks for a setting before giving up and searching for it. + </summary> +</histogram> + <histogram name="Settings.TrackedPreferenceChanged" enum="TrackedPreference"> <owner>gab@chromium.org</owner> <summary> @@ -47713,6 +47722,14 @@ </summary> </histogram> +<histogram name="Startup.TimeSinceLastStartup" units="minutes"> + <owner>fdoray@chromium.org</owner> + <summary> + Time elapsed since the last startup that went up to the main message loop + start. This is recorded just before the main message loop starts. + </summary> +</histogram> + <histogram name="Startup.WarmStartTimeFromRemoteProcessStart" units="milliseconds"> <owner>jeremy@chromium.org</owner> @@ -76455,6 +76472,17 @@ <int value="2" label="All"/> </enum> +<enum name="ServiceWorkerMetrics.EventType" type="int"> + <int value="0" label="ACTIVATE"/> + <int value="1" label="INSTALL"/> + <int value="2" label="FETCH"/> + <int value="3" label="SYNC"/> + <int value="4" label="NOTIFICATION_CLICK"/> + <int value="5" label="PUSH"/> + <int value="6" label="GEOFENCING"/> + <int value="7" label="SERVICE_PORT_CONNECT"/> +</enum> + <enum name="ServiceWorkerReadResponseResult" type="int"> <int value="0" label="OK"/> <int value="1" label="Read headers error"/> @@ -76540,17 +76568,6 @@ <int value="18" label="REQUEST_JOB_ERROR_DESTROYED_WITH_STREAM"/> </enum> -<enum name="ServiceWorkerVersion.RequestType" type="int"> - <int value="0" label="REQUEST_ACTIVATE"/> - <int value="1" label="REQUEST_INSTALL"/> - <int value="2" label="REQUEST_FETCH"/> - <int value="3" label="REQUEST_SYNC"/> - <int value="4" label="REQUEST_NOTIFICATION_CLICK"/> - <int value="5" label="REQUEST_PUSH"/> - <int value="6" label="REQUEST_GEOFENCING"/> - <int value="7" label="REQUEST_SERVICE_PORT_CONNECT"/> -</enum> - <enum name="ServiceWorkerWriteResponseResult" type="int"> <int value="0" label="OK"/> <int value="1" label="Write headers error"/> @@ -85573,6 +85590,7 @@ <affected-histogram name="Startup.LoadTime.ProcessCreateToDllMain"/> <affected-histogram name="Startup.LoadTime.ProcessCreateToExeMain"/> <affected-histogram name="Startup.SystemUptime"/> + <affected-histogram name="Startup.TimeSinceLastStartup"/> </histogram_suffixes> <histogram_suffixes name="StartupTimeBombAlarm" separator=".">
diff --git a/tools/metrics/rappor/rappor.xml b/tools/metrics/rappor/rappor.xml index 6cc04ad..d5d39fb 100644 --- a/tools/metrics/rappor/rappor.xml +++ b/tools/metrics/rappor/rappor.xml
@@ -481,6 +481,22 @@ </summary> </rappor-metric> +<rappor-metric name="Net.ErrAborted.Fast" type="ETLD_PLUS_ONE"> + <owner>csharrison@chromium.org</owner> + <summary> + The domain and registry of the URL that leads to a main frame ERR_ABORTED + error less than 100 ms after the request is created. + </summary> +</rappor-metric> + +<rappor-metric name="Net.ErrAborted.Slow" type="ETLD_PLUS_ONE"> + <owner>csharrison@chromium.org</owner> + <summary> + The domain and registry of the URL that leads to a main frame ERR_ABORTED + error more than 100 ms after the request is created. + </summary> +</rappor-metric> + <rappor-metric name="PageLoad.CoarseTiming.NavigationToFirstContentfulPaint" type="UMA_RAPPOR_TYPE"> <owner>csharrison@chromium.org</owner>
diff --git a/tools/valgrind/drmemory/suppressions_full.txt b/tools/valgrind/drmemory/suppressions_full.txt index 7a2b10e..e7122072 100644 --- a/tools/valgrind/drmemory/suppressions_full.txt +++ b/tools/valgrind/drmemory/suppressions_full.txt
@@ -1897,7 +1897,8 @@ *!base::File::WriteAtCurrentPos *!sessions::SessionBackend::AppendCommandsToFile *!sessions::SessionBackend::AppendCommands -*!base::internal::RunnableAdapter<>::Run +*!base::internal::InvokeHelper<>::MakeItSo +*!base::internal::Invoker<>::Run UNADDRESSABLE ACCESS name=bug_505734
diff --git a/tools/valgrind/gtest_exclude/content_unittests.gtest.txt b/tools/valgrind/gtest_exclude/content_unittests.gtest.txt index a3497d0..60e98f2 100644 --- a/tools/valgrind/gtest_exclude/content_unittests.gtest.txt +++ b/tools/valgrind/gtest_exclude/content_unittests.gtest.txt
@@ -14,6 +14,3 @@ # Flaky: https://crbug.com/460578 DesktopCaptureDeviceTest.InvertedFrame DesktopCaptureDeviceTest.UnpackedFrame - -# https://crbug.com/571271 -ServiceWorkerWaitForeverInFetchTest.MixedRequestTimeouts
diff --git a/ui/ozone/common/display_mode_proxy.h b/ui/ozone/common/display_mode_proxy.h index c1821acb..0b35379 100644 --- a/ui/ozone/common/display_mode_proxy.h +++ b/ui/ozone/common/display_mode_proxy.h
@@ -7,12 +7,13 @@ #include "base/macros.h" #include "ui/display/types/display_mode.h" +#include "ui/ozone/ozone_base_export.h" namespace ui { struct DisplayMode_Params; -class DisplayModeProxy : public DisplayMode { +class OZONE_BASE_EXPORT DisplayModeProxy : public DisplayMode { public: DisplayModeProxy(const DisplayMode_Params& params); ~DisplayModeProxy() override;
diff --git a/ui/ozone/common/display_snapshot_proxy.h b/ui/ozone/common/display_snapshot_proxy.h index 6a5c4c9..f2a53eb7 100644 --- a/ui/ozone/common/display_snapshot_proxy.h +++ b/ui/ozone/common/display_snapshot_proxy.h
@@ -7,12 +7,13 @@ #include "base/macros.h" #include "ui/display/types/display_snapshot.h" +#include "ui/ozone/ozone_base_export.h" namespace ui { struct DisplaySnapshot_Params; -class DisplaySnapshotProxy : public DisplaySnapshot { +class OZONE_BASE_EXPORT DisplaySnapshotProxy : public DisplaySnapshot { public: DisplaySnapshotProxy(const DisplaySnapshot_Params& params); ~DisplaySnapshotProxy() override;
diff --git a/ui/ozone/common/display_util.h b/ui/ozone/common/display_util.h index 9887126..efa4e91 100644 --- a/ui/ozone/common/display_util.h +++ b/ui/ozone/common/display_util.h
@@ -10,6 +10,7 @@ #include <vector> #include "ui/ozone/common/gpu/ozone_gpu_message_params.h" +#include "ui/ozone/ozone_base_export.h" namespace base { class FilePath; @@ -32,7 +33,8 @@ int64_t display_id_; }; -DisplayMode_Params GetDisplayModeParams(const DisplayMode& mode); +DisplayMode_Params OZONE_BASE_EXPORT +GetDisplayModeParams(const DisplayMode& mode); DisplaySnapshot_Params GetDisplaySnapshotParams(const DisplaySnapshot& display); // Create a display using the Ozone command line parameters.
diff --git a/ui/ozone/common/gpu/ozone_gpu_message_params.h b/ui/ozone/common/gpu/ozone_gpu_message_params.h index d6c6523..abd2387 100644 --- a/ui/ozone/common/gpu/ozone_gpu_message_params.h +++ b/ui/ozone/common/gpu/ozone_gpu_message_params.h
@@ -15,12 +15,12 @@ #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/overlay_transform.h" -#include "ui/ozone/ozone_export.h" +#include "ui/ozone/ozone_base_export.h" #include "ui/ozone/public/overlay_candidates_ozone.h" namespace ui { -struct OZONE_EXPORT DisplayMode_Params { +struct OZONE_BASE_EXPORT DisplayMode_Params { DisplayMode_Params(); ~DisplayMode_Params(); @@ -29,7 +29,7 @@ float refresh_rate = 0.0f; }; -struct OZONE_EXPORT DisplaySnapshot_Params { +struct OZONE_BASE_EXPORT DisplaySnapshot_Params { DisplaySnapshot_Params(); ~DisplaySnapshot_Params(); @@ -49,7 +49,7 @@ std::string string_representation; }; -struct OZONE_EXPORT OverlayCheck_Params { +struct OZONE_BASE_EXPORT OverlayCheck_Params { OverlayCheck_Params(); OverlayCheck_Params( const OverlayCandidatesOzone::OverlaySurfaceCandidate& candidate);
diff --git a/ui/ozone/common/gpu/ozone_gpu_messages.h b/ui/ozone/common/gpu/ozone_gpu_messages.h index 0edd20a..c3baa4f 100644 --- a/ui/ozone/common/gpu/ozone_gpu_messages.h +++ b/ui/ozone/common/gpu/ozone_gpu_messages.h
@@ -20,10 +20,10 @@ #include "ui/gfx/ipc/gfx_param_traits_macros.h" #include "ui/gfx/native_widget_types.h" #include "ui/ozone/common/gpu/ozone_gpu_message_params.h" -#include "ui/ozone/ozone_export.h" +#include "ui/ozone/ozone_base_export.h" #undef IPC_MESSAGE_EXPORT -#define IPC_MESSAGE_EXPORT OZONE_EXPORT +#define IPC_MESSAGE_EXPORT OZONE_BASE_EXPORT #define IPC_MESSAGE_START OzoneGpuMsgStart
diff --git a/ui/ozone/ozone.gyp b/ui/ozone/ozone.gyp index d116c70..a878f8e 100644 --- a/ui/ozone/ozone.gyp +++ b/ui/ozone/ozone.gyp
@@ -31,23 +31,49 @@ 'type': '<(component)', 'dependencies': [ '<(DEPTH)/base/base.gyp:base', + '<(DEPTH)/ipc/ipc.gyp:ipc', '<(DEPTH)/skia/skia.gyp:skia', + '<(DEPTH)/ui/display/display.gyp:display_types', + '<(DEPTH)/ui/display/display.gyp:display_util', '<(DEPTH)/ui/gfx/gfx.gyp:gfx_geometry', + '<(DEPTH)/ui/gfx/ipc/gfx_ipc.gyp:gfx_ipc', ], 'defines': [ 'OZONE_BASE_IMPLEMENTATION', ], 'sources': [ + 'common/display_mode_proxy.cc', + 'common/display_mode_proxy.h', + 'common/display_snapshot_proxy.cc', + 'common/display_snapshot_proxy.h', + 'common/display_util.cc', + 'common/display_util.h', + 'common/egl_util.cc', + 'common/egl_util.h', + 'common/gpu/ozone_gpu_message_generator.cc', + 'common/gpu/ozone_gpu_message_generator.h', + 'common/gpu/ozone_gpu_message_params.cc', + 'common/gpu/ozone_gpu_message_params.h', + 'common/gpu/ozone_gpu_messages.h', + 'common/native_display_delegate_ozone.cc', + 'common/native_display_delegate_ozone.h', + 'common/stub_overlay_manager.cc', + 'common/stub_overlay_manager.h', + 'public/client_native_pixmap.h', 'public/cursor_factory_ozone.cc', 'public/cursor_factory_ozone.h', 'public/gpu_platform_support.cc', 'public/gpu_platform_support.h', 'public/gpu_platform_support_host.cc', 'public/gpu_platform_support_host.h', + 'public/input_controller.cc', + 'public/input_controller.h', 'public/native_pixmap.h', 'public/overlay_candidates_ozone.cc', 'public/overlay_candidates_ozone.h', 'public/overlay_manager_ozone.h', + 'public/ozone_switches.cc', + 'public/ozone_switches.h', 'public/surface_factory_ozone.cc', 'public/surface_factory_ozone.h', 'public/surface_ozone_canvas.h', @@ -97,38 +123,16 @@ '<(platform_list_h_file)', '<(constructor_list_cc_file)', - 'common/display_mode_proxy.cc', - 'common/display_mode_proxy.h', - 'common/display_snapshot_proxy.cc', - 'common/display_snapshot_proxy.h', - 'common/display_util.cc', - 'common/display_util.h', - 'common/egl_util.cc', - 'common/egl_util.h', - 'common/gpu/ozone_gpu_message_generator.cc', - 'common/gpu/ozone_gpu_message_generator.h', - 'common/gpu/ozone_gpu_message_params.cc', - 'common/gpu/ozone_gpu_message_params.h', - 'common/gpu/ozone_gpu_messages.h', - 'common/native_display_delegate_ozone.cc', - 'common/native_display_delegate_ozone.h', 'common/stub_client_native_pixmap_factory.cc', 'common/stub_client_native_pixmap_factory.h', - 'common/stub_overlay_manager.cc', - 'common/stub_overlay_manager.h', 'platform_selection.cc', 'platform_selection.h', - 'public/client_native_pixmap.h', 'public/client_native_pixmap_factory.cc', 'public/client_native_pixmap_factory.h', - 'public/input_controller.cc', - 'public/input_controller.h', 'public/ozone_gpu_test_helper.cc', 'public/ozone_gpu_test_helper.h', 'public/ozone_platform.cc', 'public/ozone_platform.h', - 'public/ozone_switches.cc', - 'public/ozone_switches.h', '<@(external_ozone_platform_files)', ], 'actions': [
diff --git a/ui/views/controls/button/label_button.cc b/ui/views/controls/button/label_button.cc index a5b139e..8480fd2 100644 --- a/ui/views/controls/button/label_button.cc +++ b/ui/views/controls/button/label_button.cc
@@ -134,14 +134,6 @@ label_->SetSubpixelRenderingEnabled(enabled); } -bool LabelButton::GetTextMultiLine() const { - return label_->multi_line(); -} - -void LabelButton::SetTextMultiLine(bool text_multi_line) { - label_->SetMultiLine(text_multi_line); -} - const gfx::FontList& LabelButton::GetFontList() const { return label_->font_list(); } @@ -231,7 +223,6 @@ // Use a temporary label copy for sizing to avoid calculation side-effects. Label label(GetText(), cached_normal_font_list_); label.SetShadows(label_->shadows()); - label.SetMultiLine(GetTextMultiLine()); if (style() == STYLE_BUTTON) { // Some text appears wider when rendered normally than when rendered bold.
diff --git a/ui/views/controls/button/label_button.h b/ui/views/controls/button/label_button.h index 6e5bc50..a086fe8c 100644 --- a/ui/views/controls/button/label_button.h +++ b/ui/views/controls/button/label_button.h
@@ -57,10 +57,6 @@ // Sets whether subpixel rendering is used on the label. void SetTextSubpixelRenderingEnabled(bool enabled); - // Gets or sets the text's multi-line property to break on '\n', etc. - bool GetTextMultiLine() const; - void SetTextMultiLine(bool text_multi_line); - // Gets or sets the font list used by this button. const gfx::FontList& GetFontList() const; void SetFontList(const gfx::FontList& font_list);
diff --git a/ui/views/examples/button_example.cc b/ui/views/examples/button_example.cc index b053c76a..5fc6ce4 100644 --- a/ui/views/examples/button_example.cc +++ b/ui/views/examples/button_example.cc
@@ -20,7 +20,6 @@ namespace { const char kLabelButton[] = "Label Button"; -const char kMultiLineText[] = "Multi-Line\nButton Text Is Here To Stay!\n123"; const char kLongText[] = "Start of Really Really Really Really Really Really " "Really Really Really Really Really Really Really " "Really Really Really Really Really Long Button Text"; @@ -79,15 +78,10 @@ PrintStatus("Label Button Pressed! count: %d", ++count_); if (event.IsControlDown()) { if (event.IsShiftDown()) { - if (event.IsAltDown()) { - label_button_->SetTextMultiLine(!label_button_->GetTextMultiLine()); - label_button_->SetText(ASCIIToUTF16( - label_button_->GetTextMultiLine() ? kMultiLineText : kLabelButton)); - } else { - label_button_->SetText(ASCIIToUTF16( - label_button_->GetText().empty() ? kLongText : - label_button_->GetText().length() > 50 ? kLabelButton : "")); - } + label_button_->SetText(ASCIIToUTF16( + label_button_->GetText().empty() + ? kLongText + : label_button_->GetText().length() > 50 ? kLabelButton : "")); } else if (event.IsAltDown()) { label_button_->SetImage(Button::STATE_NORMAL, label_button_->GetImage(Button::STATE_NORMAL).isNull() ?
diff --git a/ui/views/mus/native_widget_mus.cc b/ui/views/mus/native_widget_mus.cc index abe4462..6c644a8 100644 --- a/ui/views/mus/native_widget_mus.cc +++ b/ui/views/mus/native_widget_mus.cc
@@ -239,6 +239,12 @@ void NativeWidgetMus::ConfigurePropertiesForNewWindow( const Widget::InitParams& init_params, std::map<std::string, std::vector<uint8_t>>* properties) { + if (!init_params.bounds.IsEmpty()) { + (*properties)[mus::mojom::WindowManager::kUserSetBounds_Property] = + mojo::TypeConverter<const std::vector<uint8_t>, gfx::Rect>::Convert( + init_params.bounds); + } + if (!Widget::RequiresNonClientView(init_params.type)) return; @@ -434,13 +440,13 @@ } gfx::Rect NativeWidgetMus::GetWindowBoundsInScreen() const { - // NOTIMPLEMENTED(); - return gfx::Rect(); + return window_ ? window_->GetBoundsInRoot() : gfx::Rect(); } gfx::Rect NativeWidgetMus::GetClientAreaBoundsInScreen() const { - // NOTIMPLEMENTED(); - return gfx::Rect(); + // View-to-screen coordinate system transformations depend on this returning + // the full window bounds, for example View::ConvertPointToScreen(). + return GetWindowBoundsInScreen(); } gfx::Rect NativeWidgetMus::GetRestoredBounds() const {
diff --git a/ui/views/view.cc b/ui/views/view.cc index 375cff4..45467ab2 100644 --- a/ui/views/view.cc +++ b/ui/views/view.cc
@@ -935,7 +935,7 @@ return GetEffectiveViewTargeter()->DoesIntersectRect(this, rect); } -bool View::IsMouseHovered() { +bool View::IsMouseHovered() const { // If we haven't yet been placed in an onscreen view hierarchy, we can't be // hovered. if (!GetWidget()) @@ -1611,8 +1611,8 @@ drag_controller_->WriteDragDataForView(this, press_pt, data); } -bool View::InDrag() { - Widget* widget = GetWidget(); +bool View::InDrag() const { + const Widget* widget = GetWidget(); return widget ? widget->dragged_view() == this : false; }
diff --git a/ui/views/view.h b/ui/views/view.h index 12ed0f10..a5ef00d 100644 --- a/ui/views/view.h +++ b/ui/views/view.h
@@ -596,7 +596,7 @@ // Returns true if the mouse cursor is over |view| and mouse events are // enabled. - bool IsMouseHovered(); + bool IsMouseHovered() const; // This method is invoked when the user clicks on this view. // The provided event is in the receiver's coordinate system. @@ -1189,7 +1189,7 @@ // Returns whether we're in the middle of a drag session that was initiated // by us. - bool InDrag(); + bool InDrag() const; // Returns how much the mouse needs to move in one direction to start a // drag. These methods cache in a platform-appropriate way. These values are
diff --git a/ui/views/widget/widget.h b/ui/views/widget/widget.h index 4ad8c2b2..80aaddee 100644 --- a/ui/views/widget/widget.h +++ b/ui/views/widget/widget.h
@@ -589,7 +589,10 @@ // Returns the view that requested the current drag operation via // RunShellDrag(), or NULL if there is no such view or drag operation. - View* dragged_view() { return dragged_view_; } + View* dragged_view() { + return const_cast<View*>(const_cast<const Widget*>(this)->dragged_view()); + } + const View* dragged_view() const { return dragged_view_; } // Adds the specified |rect| in client area coordinates to the rectangle to be // redrawn.