diff --git a/AUTHORS b/AUTHORS index 2694366..7085b7b7 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -835,6 +835,7 @@ Yong Wang <ccyongwang@tencent.com> Charles Vaughn <cvaughn@gmail.com> +ACCESS CO., LTD. <*@access-company.com> BlackBerry Limited <*@blackberry.com> Code Aurora Forum <*@codeaurora.org> Comodo CA Limited
diff --git a/DEPS b/DEPS index 53a75fd..be08e7a4 100644 --- a/DEPS +++ b/DEPS
@@ -40,7 +40,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'c7be00366bb0171e2d247ea71e291a64e3d10254', + 'skia_revision': '459c9679a221bbe66a735080728afb9599fa5ed7', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -64,7 +64,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '2bbb55162f0c9490a2085ed6eaa38038a7605609', + 'pdfium_revision': '2e2a4fcd43677c5882dcf00cb4b99635cb2cfcd3', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -72,7 +72,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. - 'boringssl_revision': '777fdd6443d5f01420b67137118febdf56a1c8e4', + 'boringssl_revision': 'afd88c27f2fe9f8f1a6d5b287cc16b1bc8f06198', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling google-toolbox-for-mac # and whatever else without interference from each other. @@ -96,7 +96,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '380124f4ad9d972449c81462ec99a4c916fcd2d8', + 'catapult_revision': 'abff3b4929c74e4eb90a877520b82570853ac5c5', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -208,7 +208,7 @@ Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + '28a5cdde5c32bcf66715343c10f74e85713f7aaf', 'src/third_party/usrsctp/usrsctplib': - Var('chromium_git') + '/external/github.com/sctplab/usrsctp' + '@' + '8679f2b0bf063ac894dc473debefd61dbbebf622', + Var('chromium_git') + '/external/github.com/sctplab/usrsctp' + '@' + '2f6478eb8d40f1766a96b5b033ed26c0c2244589', 'src/third_party/libsrtp': Var('chromium_git') + '/chromium/deps/libsrtp.git' + '@' + 'ccf84786f8ef803cb9c75e919e5a3976b9f5a672', @@ -409,7 +409,7 @@ # For Linux and Chromium OS. 'src/third_party/cros_system_api': - Var('chromium_git') + '/chromiumos/platform/system_api.git' + '@' + 'f425c1c372b0077a67937855f03f1089d0df7970', + Var('chromium_git') + '/chromiumos/platform/system_api.git' + '@' + 'c6eab9e4d0b4f56176df23d30b815dc94b774a3d', 'src/third_party/freetype/src': Var('chromium_git') + '/chromium/src/third_party/freetype2.git' + '@' + Var('freetype_revision'), @@ -466,7 +466,7 @@ Var('chromium_git') + '/external/android_protobuf.git' + '@' + '999188d0dc72e97f7fe08bb756958a2cf090f4e7', 'src/third_party/android_tools': - Var('chromium_git') + '/android_tools.git' + '@' + 'b65c4776dac2cf1b80e969b3b2d4e081b9c84f29', + Var('chromium_git') + '/android_tools.git' + '@' + 'cb6bc21107001e2f2eeee2707b482b2b755baf51', 'src/third_party/apache-portable-runtime/src': Var('chromium_git') + '/external/apache-portable-runtime.git' + '@' + 'c76a8c4277e09a82eaa229e35246edea1ee0a6a1', @@ -957,6 +957,17 @@ '-s', 'src/third_party/gvr-android-sdk/common_library.aar.sha1', ], }, + { + 'name': 'vr_controller_test_api', + 'pattern': '\\.sha1', + 'action': [ 'download_from_google_storage', + '--no_resume', + '--platform=linux*', + '--no_auth', + '--bucket', 'chromium-gvr-static-shim/controller_test_api', + '-s', 'src/third_party/gvr-android-sdk/test-libraries/controller_test_api.aar.sha1', + ], + }, # Pull luci-go binaries (isolate, swarming) using checked-in hashes. { 'name': 'luci-go_win',
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java index 5c824d2..2b2e0a4 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java
@@ -598,7 +598,7 @@ } @Override - public void determinedVisibility(int pid) {} + public void onDeterminedVisibility(int pid) {} @Override public void onSentToBackground() {}
diff --git a/apps/app_restore_service_browsertest.cc b/apps/app_restore_service_browsertest.cc index acdea78..9946a8a87 100644 --- a/apps/app_restore_service_browsertest.cc +++ b/apps/app_restore_service_browsertest.cc
@@ -5,6 +5,7 @@ #include "apps/app_restore_service.h" #include "apps/app_restore_service_factory.h" #include "apps/saved_files_service.h" +#include "base/threading/thread_restrictions.h" #include "chrome/browser/apps/app_browsertest_util.h" #include "chrome/browser/extensions/api/file_system/file_system_api.h" #include "content/public/browser/browser_context.h" @@ -114,6 +115,7 @@ extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED, content::NotificationService::AllSources()); + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temp_directory; ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); base::FilePath temp_file; @@ -154,6 +156,7 @@ extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED, content::NotificationService::AllSources()); + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temp_directory; ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); base::FilePath temp_file;
diff --git a/base/BUILD.gn b/base/BUILD.gn index b284bec..43897be 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -2585,6 +2585,7 @@ "//testing/android/reporter:reporter_java", "//third_party/android_support_test_runner:exposed_instrumentation_api_publish_java", "//third_party/android_support_test_runner:runner_java", + "//third_party/android_tools:android_support_chromium_java", "//third_party/hamcrest:hamcrest_core_java", "//third_party/junit", ] @@ -2594,6 +2595,7 @@ "test/android/javatests/src/org/chromium/base/test/BaseInstrumentationTestRunner.java", "test/android/javatests/src/org/chromium/base/test/BaseJUnit4ClassRunner.java", "test/android/javatests/src/org/chromium/base/test/BaseChromiumAndroidJUnitRunner.java", + "test/android/javatests/src/org/chromium/base/test/BaseChromiumRunnerCommon.java", "test/android/javatests/src/org/chromium/base/test/BaseTestResult.java", "test/android/javatests/src/org/chromium/base/test/SetUpTestRule.java", "test/android/javatests/src/org/chromium/base/test/SetUpStatement.java",
diff --git a/base/android/java/src/org/chromium/base/BaseChromiumApplication.java b/base/android/java/src/org/chromium/base/BaseChromiumApplication.java index 6b97bdd..61109f1 100644 --- a/base/android/java/src/org/chromium/base/BaseChromiumApplication.java +++ b/base/android/java/src/org/chromium/base/BaseChromiumApplication.java
@@ -44,7 +44,9 @@ super.attachBaseContext(base); assert getBaseContext() != null; checkAppBeingReplaced(); - ChromiumMultiDexInstaller.install(this); + if (BuildConfig.isMultidexEnabled()) { + ChromiumMultiDexInstaller.install(this); + } } /**
diff --git a/base/android/java/src/org/chromium/base/multidex/ChromiumMultiDexInstaller.java b/base/android/java/src/org/chromium/base/multidex/ChromiumMultiDexInstaller.java index 3d036c2..9049cb0 100644 --- a/base/android/java/src/org/chromium/base/multidex/ChromiumMultiDexInstaller.java +++ b/base/android/java/src/org/chromium/base/multidex/ChromiumMultiDexInstaller.java
@@ -12,7 +12,6 @@ import android.os.Build; import android.support.multidex.MultiDex; -import org.chromium.base.BuildConfig; import org.chromium.base.Log; import org.chromium.base.VisibleForTesting; @@ -48,8 +47,6 @@ */ @VisibleForTesting public static void install(Context context) { - if (!BuildConfig.isMultidexEnabled()) return; - // TODO(jbudorick): Back out this version check once support for K & below works. // http://crbug.com/512357 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP
diff --git a/base/metrics/histogram.cc b/base/metrics/histogram.cc index 3e4cebe4..2643793 100644 --- a/base/metrics/histogram.cc +++ b/base/metrics/histogram.cc
@@ -388,13 +388,31 @@ *bucket_count = kBucketCount_MAX - 1; } - if (*minimum >= *maximum) - return false; - if (*bucket_count < 3) - return false; - if (*bucket_count > static_cast<uint32_t>(*maximum - *minimum + 2)) - return false; - return true; + bool check_okay = true; + + if (*minimum > *maximum) { + check_okay = false; + std::swap(*minimum, *maximum); + } + if (*maximum == *minimum) { + check_okay = false; + *maximum = *minimum + 1; + } + if (*bucket_count < 3) { + check_okay = false; + *bucket_count = 3; + } + if (*bucket_count > static_cast<uint32_t>(*maximum - *minimum + 2)) { + check_okay = false; + *bucket_count = static_cast<uint32_t>(*maximum - *minimum + 2); + } + + if (!check_okay) { + UMA_HISTOGRAM_SPARSE_SLOWLY("Histogram.BadConstructionArguments", + static_cast<Sample>(HashMetricName(name))); + } + + return check_okay; } uint64_t Histogram::name_hash() const {
diff --git a/base/metrics/histogram.h b/base/metrics/histogram.h index a76dd632..20d5104 100644 --- a/base/metrics/histogram.h +++ b/base/metrics/histogram.h
@@ -179,11 +179,12 @@ const BucketRanges* bucket_ranges() const { return bucket_ranges_; } // This function validates histogram construction arguments. It returns false - // if some of the arguments are totally bad. + // if some of the arguments are bad but also corrects them so they should + // function on non-dcheck builds without crashing. // Note. Currently it allow some bad input, e.g. 0 as minimum, but silently // converts it to good input: 1. - // TODO(kaiwang): Be more restrict and return false for any bad input, and - // make this a readonly validating function. + // TODO(bcwhite): Use false returns to create "sink" histograms so that bad + // data doesn't create confusion on the servers. static bool InspectConstructionArguments(const std::string& name, Sample* minimum, Sample* maximum,
diff --git a/base/test/android/javatests/src/org/chromium/base/test/BaseChromiumAndroidJUnitRunner.java b/base/test/android/javatests/src/org/chromium/base/test/BaseChromiumAndroidJUnitRunner.java index fcd60869..a48c4ab 100644 --- a/base/test/android/javatests/src/org/chromium/base/test/BaseChromiumAndroidJUnitRunner.java +++ b/base/test/android/javatests/src/org/chromium/base/test/BaseChromiumAndroidJUnitRunner.java
@@ -4,7 +4,8 @@ package org.chromium.base.test; -import android.os.Bundle; +import android.app.Application; +import android.content.Context; import android.support.test.runner.AndroidJUnitRunner; import org.chromium.base.multidex.ChromiumMultiDexInstaller; @@ -18,8 +19,11 @@ */ public class BaseChromiumAndroidJUnitRunner extends AndroidJUnitRunner { @Override - public void onCreate(Bundle arguments) { - ChromiumMultiDexInstaller.install(getTargetContext()); - super.onCreate(arguments); + public Application newApplication(ClassLoader cl, String className, Context context) + throws ClassNotFoundException, IllegalAccessException, InstantiationException { + ChromiumMultiDexInstaller.install(new BaseChromiumRunnerCommon.MultiDexContextWrapper( + getContext(), getTargetContext())); + BaseChromiumRunnerCommon.reorderDexPathElements(cl, getContext(), getTargetContext()); + return super.newApplication(cl, className, context); } }
diff --git a/base/test/android/javatests/src/org/chromium/base/test/BaseChromiumInstrumentationTestRunner.java b/base/test/android/javatests/src/org/chromium/base/test/BaseChromiumInstrumentationTestRunner.java index d44c9dd..693bb62 100644 --- a/base/test/android/javatests/src/org/chromium/base/test/BaseChromiumInstrumentationTestRunner.java +++ b/base/test/android/javatests/src/org/chromium/base/test/BaseChromiumInstrumentationTestRunner.java
@@ -4,7 +4,8 @@ package org.chromium.base.test; -import android.os.Bundle; +import android.app.Application; +import android.content.Context; import org.chromium.base.multidex.ChromiumMultiDexInstaller; import org.chromium.base.test.util.CommandLineFlags; @@ -16,9 +17,12 @@ */ public class BaseChromiumInstrumentationTestRunner extends BaseInstrumentationTestRunner { @Override - public void onCreate(Bundle arguments) { - ChromiumMultiDexInstaller.install(getTargetContext()); - super.onCreate(arguments); + public Application newApplication(ClassLoader cl, String className, Context context) + throws ClassNotFoundException, IllegalAccessException, InstantiationException { + ChromiumMultiDexInstaller.install(new BaseChromiumRunnerCommon.MultiDexContextWrapper( + getContext(), getTargetContext())); + BaseChromiumRunnerCommon.reorderDexPathElements(cl, getContext(), getTargetContext()); + return super.newApplication(cl, className, context); } /**
diff --git a/base/test/android/javatests/src/org/chromium/base/test/BaseChromiumRunnerCommon.java b/base/test/android/javatests/src/org/chromium/base/test/BaseChromiumRunnerCommon.java new file mode 100644 index 0000000..fcda9103 --- /dev/null +++ b/base/test/android/javatests/src/org/chromium/base/test/BaseChromiumRunnerCommon.java
@@ -0,0 +1,162 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.base.test; + +import android.content.Context; +import android.content.ContextWrapper; +import android.content.SharedPreferences; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; + +import org.chromium.android.support.PackageManagerWrapper; +import org.chromium.base.Log; +import org.chromium.base.annotations.MainDex; + +import java.io.File; +import java.io.IOException; +import java.io.Serializable; +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.Comparator; + +/** + * Functionality common to the JUnit3 and JUnit4 runners. + */ +@MainDex +class BaseChromiumRunnerCommon { + private static final String TAG = "base_test"; + + /** + * A ContextWrapper that allows multidex test APKs to extract secondary dexes into + * the APK under test's data directory. + */ + @MainDex + static class MultiDexContextWrapper extends ContextWrapper { + private Context mAppContext; + + MultiDexContextWrapper(Context instrContext, Context appContext) { + super(instrContext); + mAppContext = appContext; + } + + @Override + public File getFilesDir() { + return mAppContext.getFilesDir(); + } + + @Override + public SharedPreferences getSharedPreferences(String name, int mode) { + return mAppContext.getSharedPreferences(name, mode); + } + + @Override + public PackageManager getPackageManager() { + return new PackageManagerWrapper(super.getPackageManager()) { + @Override + public ApplicationInfo getApplicationInfo(String packageName, int flags) { + try { + ApplicationInfo ai = super.getApplicationInfo(packageName, flags); + if (packageName.equals(getPackageName())) { + ApplicationInfo appAi = + super.getApplicationInfo(mAppContext.getPackageName(), flags); + File dataDir = new File(appAi.dataDir, "test-multidex"); + if (!dataDir.exists() && !dataDir.mkdirs()) { + throw new IOException(String.format( + "Unable to create test multidex directory \"%s\"", + dataDir.getPath())); + } + ai.dataDir = dataDir.getPath(); + } + return ai; + } catch (Exception e) { + Log.e(TAG, "Failed to get application info for %s", packageName, e); + } + return null; + } + }; + } + } + + /** + * Ensure all test dex entries precede app dex entries. + * + * @param cl ClassLoader to modify. Assumed to be a derivative of + * {@link dalvik.system.BaseDexClassLoader}. If this isn't + * the case, reordering will fail. + */ + static void reorderDexPathElements(ClassLoader cl, Context context, Context targetContext) { + try { + Log.i(TAG, + "Reordering dex files. If you're building a multidex test APK and see a " + + "class resolving to an unexpected implementation, this may be why."); + Field pathListField = findField(cl, "pathList"); + Object dexPathList = pathListField.get(cl); + Field dexElementsField = findField(dexPathList, "dexElements"); + Object[] dexElementsList = (Object[]) dexElementsField.get(dexPathList); + Arrays.sort(dexElementsList, + new DexListReorderingComparator( + context.getPackageName(), targetContext.getPackageName())); + dexElementsField.set(dexPathList, dexElementsList); + } catch (Exception e) { + Log.e(TAG, "Failed to reorder dex elements for testing.", e); + } + } + + /** + * Comparator for sorting dex list entries. + * + * Using this to sort a list of dex list entries will result in the following order: + * - Strings that contain neither the test package nor the app package in lexicographical + * order. + * - Strings that contain the test package in lexicographical order. + * - Strings that contain the app package but not the test package in lexicographical order. + */ + private static class DexListReorderingComparator implements Comparator<Object>, Serializable { + private String mTestPackage; + private String mAppPackage; + + public DexListReorderingComparator(String testPackage, String appPackage) { + mTestPackage = testPackage; + mAppPackage = appPackage; + } + + @Override + public int compare(Object o1, Object o2) { + String s1 = o1.toString(); + String s2 = o2.toString(); + if (s1.contains(mTestPackage)) { + if (!s2.contains(mTestPackage)) { + if (s2.contains(mAppPackage)) { + return -1; + } else { + return 1; + } + } + } else if (s1.contains(mAppPackage)) { + if (s2.contains(mTestPackage)) { + return 1; + } else if (!s2.contains(mAppPackage)) { + return 1; + } + } else if (s2.contains(mTestPackage) || s2.contains(mAppPackage)) { + return -1; + } + return s1.compareTo(s2); + } + } + + private static Field findField(Object instance, String name) throws NoSuchFieldException { + for (Class<?> clazz = instance.getClass(); clazz != null; clazz = clazz.getSuperclass()) { + try { + Field f = clazz.getDeclaredField(name); + f.setAccessible(true); + return f; + } catch (NoSuchFieldException e) { + } + } + throw new NoSuchFieldException( + "Unable to find field " + name + " in " + instance.getClass()); + } +}
diff --git a/base/test/multiprocess_test.cc b/base/test/multiprocess_test.cc index 9da243347..d45e3a8 100644 --- a/base/test/multiprocess_test.cc +++ b/base/test/multiprocess_test.cc
@@ -8,6 +8,7 @@ #include "base/command_line.h" #include "base/files/file_path.h" #include "base/files/file_util.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" namespace base { @@ -44,6 +45,7 @@ #endif // !defined(OS_ANDROID) CommandLine GetMultiProcessTestChildBaseCommandLine() { + base::ThreadRestrictions::ScopedAllowIO allow_io; CommandLine cmd_line = *CommandLine::ForCurrentProcess(); cmd_line.SetProgram(MakeAbsoluteFilePath(cmd_line.GetProgram())); return cmd_line;
diff --git a/base/test/scoped_task_environment.cc b/base/test/scoped_task_environment.cc index b18bf6a..1e8782e 100644 --- a/base/test/scoped_task_environment.cc +++ b/base/test/scoped_task_environment.cc
@@ -12,7 +12,12 @@ namespace base { namespace test { -ScopedTaskEnvironment::ScopedTaskEnvironment() { +ScopedTaskEnvironment::ScopedTaskEnvironment(MainThreadType main_thread_type) + : message_loop_(main_thread_type == MainThreadType::DEFAULT + ? MessageLoop::TYPE_DEFAULT + : (main_thread_type == MainThreadType::UI + ? MessageLoop::TYPE_UI + : MessageLoop::TYPE_IO)) { DCHECK(!TaskScheduler::GetInstance()); // Instantiate a TaskScheduler with 1 thread in each of its 4 pools. Threads
diff --git a/base/test/scoped_task_environment.h b/base/test/scoped_task_environment.h index 2887d07..b0a6db3 100644 --- a/base/test/scoped_task_environment.h +++ b/base/test/scoped_task_environment.h
@@ -32,7 +32,17 @@ // https://docs.google.com/document/d/1QabRo8c7D9LsYY3cEcaPQbOCLo8Tu-6VLykYXyl3Pkk/edit class ScopedTaskEnvironment { public: - ScopedTaskEnvironment(); + enum class MainThreadType { + // The main thread doesn't pump messages. + DEFAULT, + // The main thread pumps UI messages. + UI, + // The main thread pumps asynchronous IO messages. + IO, + }; + + ScopedTaskEnvironment( + MainThreadType main_thread_type = MainThreadType::DEFAULT); // Runs pending (Thread|Sequenced)TaskRunnerHandle tasks and pending // BLOCK_SHUTDOWN TaskScheduler tasks. Then, unregisters the TaskScheduler and
diff --git a/build/android/main_dex_classes.flags b/build/android/main_dex_classes.flags index 81152dc..9bb7977a 100644 --- a/build/android/main_dex_classes.flags +++ b/build/android/main_dex_classes.flags
@@ -1,3 +1,10 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Proguard flags for what should be kept in the main dex. Only used +# during main dex list determination, not during actual proguarding. + -keep @**.MainDex class * { *; }
diff --git a/build/android/multidex.flags b/build/android/multidex.flags new file mode 100644 index 0000000..59e7e85 --- /dev/null +++ b/build/android/multidex.flags
@@ -0,0 +1,12 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Proguard flags for what to keep through proguarding when multidex is +# enabled. Not used during main dex list determination. + +-keepattributes *Annotations* +-keep @interface org.chromium.base.annotations.MainDex +-keep @**.MainDex class * { + *; +}
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index 4455732..eddbbf3 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -1935,6 +1935,9 @@ if (defined(invoker.proguard_configs)) { _proguard_configs += invoker.proguard_configs } + if (enable_multidex) { + _proguard_configs += [ "//build/android/multidex.flags" ] + } assert(_proguard_configs != []) # Mark as used. _proguard_target = "${_template_name}__proguard" proguard(_proguard_target) {
diff --git a/build/linux/unbundle/opus.gn b/build/linux/unbundle/opus.gn new file mode 100644 index 0000000..e779a97d --- /dev/null +++ b/build/linux/unbundle/opus.gn
@@ -0,0 +1,45 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/linux/pkg_config.gni") +import("//build/shim_headers.gni") + +pkg_config("system_opus") { + packages = [ "opus" ] +} + +shim_headers("opus_shim") { + root_path = "src/include" + headers = [ + "opus.h", + "opus_defines.h", + "opus_multistream.h", + "opus_types.h", + ] +} + +source_set("opus") { + deps = [ + ":opus_shim", + ] + public_configs = [ ":system_opus" ] +} + +source_set("opus_compare") { +} + +source_set("opus_demo") { +} + +source_set("test_opus_api") { +} + +source_set("test_opus_decode") { +} + +source_set("test_opus_encode") { +} + +source_set("test_opus_padding") { +}
diff --git a/build/linux/unbundle/replace_gn_files.py b/build/linux/unbundle/replace_gn_files.py index 7570a8b..3b457146 100755 --- a/build/linux/unbundle/replace_gn_files.py +++ b/build/linux/unbundle/replace_gn_files.py
@@ -29,6 +29,7 @@ 'libwebp': 'third_party/libwebp/BUILD.gn', 'libxml': 'third_party/libxml/BUILD.gn', 'libxslt': 'third_party/libxslt/BUILD.gn', + 'opus': 'third_party/opus/BUILD.gn', 're2': 'third_party/re2/BUILD.gn', 'snappy': 'third_party/snappy/BUILD.gn', 'yasm': 'third_party/yasm/yasm_assemble.gni',
diff --git a/build/secondary/third_party/android_tools/BUILD.gn b/build/secondary/third_party/android_tools/BUILD.gn index 853b040..3161db12 100644 --- a/build/secondary/third_party/android_tools/BUILD.gn +++ b/build/secondary/third_party/android_tools/BUILD.gn
@@ -193,6 +193,11 @@ aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar" } +android_library("android_support_chromium_java") { + testonly = true + java_files = [ "$android_sdk_root/extras/chromium/support/src/org/chromium/android/support/PackageManagerWrapper.java" ] +} + # TODO(dgn): Remove this once no other target has a dependency on it java_group("google_play_services_default_resources") { deps = []
diff --git a/cc/layers/texture_layer_unittest.cc b/cc/layers/texture_layer_unittest.cc index 0f3ba5c0..1fa9929 100644 --- a/cc/layers/texture_layer_unittest.cc +++ b/cc/layers/texture_layer_unittest.cc
@@ -641,15 +641,11 @@ bool synchronous_composite = !HasImplThread() && !layer_tree_host()->GetSettings().single_thread_proxy_scheduler; - // Allow relaim resources for this test so that mailboxes in the display - // will be returned inside the commit that replaces them. - bool force_disable_reclaim_resources = false; return base::MakeUnique<TestCompositorFrameSink>( compositor_context_provider, std::move(worker_context_provider), shared_bitmap_manager(), gpu_memory_buffer_manager(), layer_tree_host()->GetSettings().renderer_settings, - ImplThreadTaskRunner(), synchronous_composite, - force_disable_reclaim_resources); + ImplThreadTaskRunner(), synchronous_composite); } void AdvanceTestCase() {
diff --git a/cc/output/compositor_frame_sink.h b/cc/output/compositor_frame_sink.h index 650f7191..f8b7a47 100644 --- a/cc/output/compositor_frame_sink.h +++ b/cc/output/compositor_frame_sink.h
@@ -41,9 +41,13 @@ struct Capabilities { Capabilities() = default; - // Whether ForceReclaimResources can be called to reclaim all resources - // from the CompositorFrameSink. - bool can_force_reclaim_resources = false; + // True if we must always swap, even if there is no damage to the frame. + // Needed for both the browser compositor as well as layout tests. + // TODO(ericrk): This should be test-only for layout tests, but tab + // capture has issues capturing offscreen tabs whithout this. We should + // remove this dependency. crbug.com/680196 + bool must_always_swap = false; + // True if sync points for resources are needed when swapping delegated // frames. bool delegated_sync_points_required = true; @@ -102,10 +106,6 @@ return shared_bitmap_manager_; } - // If supported, this causes a ReclaimResources for all resources that are - // currently in use. - virtual void ForceReclaimResources() {} - // If supported, this sets the LocalSurfaceId the CompositorFrameSink will use // to submit a CompositorFrame. virtual void SetLocalSurfaceId(const LocalSurfaceId& local_surface_id) {}
diff --git a/cc/surfaces/compositor_frame_sink_support.cc b/cc/surfaces/compositor_frame_sink_support.cc index 39b7fbd..09bfdbc7 100644 --- a/cc/surfaces/compositor_frame_sink_support.cc +++ b/cc/surfaces/compositor_frame_sink_support.cc
@@ -206,11 +206,6 @@ client_->WillDrawSurface(local_surface_id, damage_rect); } -void CompositorFrameSinkSupport::ForceReclaimResources() { - DCHECK(surface_factory_); - surface_factory_->ClearSurface(); -} - void CompositorFrameSinkSupport::ClaimTemporaryReference( const SurfaceId& surface_id) { surface_manager_->AssignTemporaryReference(surface_id, frame_sink_id_);
diff --git a/cc/surfaces/compositor_frame_sink_support.h b/cc/surfaces/compositor_frame_sink_support.h index 75f5605d..33e44f9 100644 --- a/cc/surfaces/compositor_frame_sink_support.h +++ b/cc/surfaces/compositor_frame_sink_support.h
@@ -69,7 +69,6 @@ void SubmitCompositorFrame(const LocalSurfaceId& local_surface_id, CompositorFrame frame); void RequestCopyOfSurface(std::unique_ptr<CopyOutputRequest> request); - void ForceReclaimResources(); void ClaimTemporaryReference(const SurfaceId& surface_id); protected:
diff --git a/cc/surfaces/direct_compositor_frame_sink.cc b/cc/surfaces/direct_compositor_frame_sink.cc index 13b6c62..505d38a 100644 --- a/cc/surfaces/direct_compositor_frame_sink.cc +++ b/cc/surfaces/direct_compositor_frame_sink.cc
@@ -31,7 +31,7 @@ surface_manager_(surface_manager), display_(display) { DCHECK(thread_checker_.CalledOnValidThread()); - capabilities_.can_force_reclaim_resources = true; + capabilities_.must_always_swap = true; // Display and DirectCompositorFrameSink share a GL context, so sync // points aren't needed when passing resources between them. capabilities_.delegated_sync_points_required = false; @@ -47,7 +47,7 @@ surface_manager_(surface_manager), display_(display) { DCHECK(thread_checker_.CalledOnValidThread()); - capabilities_.can_force_reclaim_resources = true; + capabilities_.must_always_swap = true; } DirectCompositorFrameSink::~DirectCompositorFrameSink() { @@ -110,10 +110,6 @@ std::move(frame)); } -void DirectCompositorFrameSink::ForceReclaimResources() { - support_->ForceReclaimResources(); -} - void DirectCompositorFrameSink::DisplayOutputSurfaceLost() { is_lost_ = true; client_->DidLoseCompositorFrameSink();
diff --git a/cc/surfaces/direct_compositor_frame_sink.h b/cc/surfaces/direct_compositor_frame_sink.h index 5aa021b4..98d4cecd 100644 --- a/cc/surfaces/direct_compositor_frame_sink.h +++ b/cc/surfaces/direct_compositor_frame_sink.h
@@ -51,7 +51,6 @@ bool BindToClient(CompositorFrameSinkClient* client) override; void DetachFromClient() override; void SubmitCompositorFrame(CompositorFrame frame) override; - void ForceReclaimResources() override; // DisplayClient implementation. void DisplayOutputSurfaceLost() override;
diff --git a/cc/surfaces/direct_compositor_frame_sink_unittest.cc b/cc/surfaces/direct_compositor_frame_sink_unittest.cc index 5f1b8b8..bfb3875 100644 --- a/cc/surfaces/direct_compositor_frame_sink_unittest.cc +++ b/cc/surfaces/direct_compositor_frame_sink_unittest.cc
@@ -171,19 +171,6 @@ EXPECT_EQ(2u, display_output_surface_->num_sent_frames()); } -TEST_F(DirectCompositorFrameSinkTest, - LockingResourcesDoesNotIndirectlyCauseDamage) { - compositor_frame_sink_->ForceReclaimResources(); - EXPECT_EQ(1u, display_output_surface_->num_sent_frames()); - task_runner_->RunPendingTasks(); - EXPECT_EQ(1u, display_output_surface_->num_sent_frames()); - - SwapBuffersWithDamage(gfx::Rect()); - EXPECT_EQ(1u, display_output_surface_->num_sent_frames()); - task_runner_->RunUntilIdle(); - EXPECT_EQ(1u, display_output_surface_->num_sent_frames()); -} - class TestBeginFrameObserver : public BeginFrameObserverBase { public: const BeginFrameAck& ack() const { return ack_; }
diff --git a/cc/surfaces/surface.cc b/cc/surfaces/surface.cc index be2332b..2ceae593 100644 --- a/cc/surfaces/surface.cc +++ b/cc/surfaces/surface.cc
@@ -82,11 +82,6 @@ UnrefFrameResourcesAndRunDrawCallback(std::move(previous_pending_frame_data)); } -void Surface::EvictFrame() { - QueueFrame(CompositorFrame(), DrawCallback(), WillDrawCallback()); - active_frame_data_.reset(); -} - void Surface::RequestCopyOfOutput( std::unique_ptr<CopyOutputRequest> copy_request) { if (!active_frame_data_ ||
diff --git a/cc/surfaces/surface.h b/cc/surfaces/surface.h index 5aefd5e..603036f 100644 --- a/cc/surfaces/surface.h +++ b/cc/surfaces/surface.h
@@ -60,7 +60,6 @@ void QueueFrame(CompositorFrame frame, const DrawCallback& draw_callback, const WillDrawCallback& will_draw_callback); - void EvictFrame(); void RequestCopyOfOutput(std::unique_ptr<CopyOutputRequest> copy_request); // Notifies the Surface that a blocking SurfaceId now has an active frame.
diff --git a/cc/surfaces/surface_factory.cc b/cc/surfaces/surface_factory.cc index 76167c9f..7d65ec2 100644 --- a/cc/surfaces/surface_factory.cc +++ b/cc/surfaces/surface_factory.cc
@@ -87,13 +87,6 @@ manager_->SurfaceModified(current_surface_->surface_id()); } -void SurfaceFactory::ClearSurface() { - if (!current_surface_) - return; - current_surface_->EvictFrame(); - manager_->SurfaceModified(current_surface_->surface_id()); -} - void SurfaceFactory::ReceiveFromChild( const TransferableResourceArray& resources) { holder_.ReceiveFromChild(resources);
diff --git a/cc/surfaces/surface_factory.h b/cc/surfaces/surface_factory.h index 0a206e6f..55782e4 100644 --- a/cc/surfaces/surface_factory.h +++ b/cc/surfaces/surface_factory.h
@@ -65,10 +65,6 @@ const WillDrawCallback& will_draw_callback); void RequestCopyOfSurface(std::unique_ptr<CopyOutputRequest> copy_request); - // Evicts the current frame on the surface. All the resources - // will be released and Surface::HasFrame will return false. - void ClearSurface(); - SurfaceFactoryClient* client() { return client_; } void ReceiveFromChild(const TransferableResourceArray& resources);
diff --git a/cc/test/layer_tree_pixel_test.cc b/cc/test/layer_tree_pixel_test.cc index 6298b78..7935b39 100644 --- a/cc/test/layer_tree_pixel_test.cc +++ b/cc/test/layer_tree_pixel_test.cc
@@ -52,14 +52,10 @@ bool synchronous_composite = !HasImplThread() && !layer_tree_host()->GetSettings().single_thread_proxy_scheduler; - // Allow resource reclaiming for partial raster tests to get back - // resources from the Display. - bool force_disable_reclaim_resources = false; auto delegating_output_surface = base::MakeUnique<TestCompositorFrameSink>( compositor_context_provider, std::move(worker_context_provider), shared_bitmap_manager(), gpu_memory_buffer_manager(), RendererSettings(), - ImplThreadTaskRunner(), synchronous_composite, - force_disable_reclaim_resources); + ImplThreadTaskRunner(), synchronous_composite); delegating_output_surface->SetEnlargePassTextureAmount( enlarge_texture_amount_); return delegating_output_surface;
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc index db7a93c..45d898a57 100644 --- a/cc/test/layer_tree_test.cc +++ b/cc/test/layer_tree_test.cc
@@ -863,14 +863,11 @@ bool synchronous_composite = !HasImplThread() && !layer_tree_host()->GetSettings().single_thread_proxy_scheduler; - // Disable reclaim resources by default to act like the Display lives - // out-of-process. - bool force_disable_reclaim_resources = true; return base::MakeUnique<TestCompositorFrameSink>( compositor_context_provider, std::move(worker_context_provider), shared_bitmap_manager(), gpu_memory_buffer_manager(), layer_tree_host()->GetSettings().renderer_settings, impl_task_runner_, - synchronous_composite, force_disable_reclaim_resources); + synchronous_composite); } std::unique_ptr<OutputSurface>
diff --git a/cc/test/test_compositor_frame_sink.cc b/cc/test/test_compositor_frame_sink.cc index 75ace29..8a856ed 100644 --- a/cc/test/test_compositor_frame_sink.cc +++ b/cc/test/test_compositor_frame_sink.cc
@@ -27,8 +27,7 @@ gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, const RendererSettings& renderer_settings, scoped_refptr<base::SingleThreadTaskRunner> task_runner, - bool synchronous_composite, - bool force_disable_reclaim_resources) + bool synchronous_composite) : CompositorFrameSink(std::move(compositor_context_provider), std::move(worker_context_provider), gpu_memory_buffer_manager, @@ -41,11 +40,6 @@ local_surface_id_allocator_(new LocalSurfaceIdAllocator()), external_begin_frame_source_(this), weak_ptr_factory_(this) { - // Since this CompositorFrameSink and the Display are tightly coupled and in - // the same process/thread, the LayerTreeHostImpl can reclaim resources from - // the Display. But we allow tests to disable this to mimic an out-of-process - // Display. - capabilities_.can_force_reclaim_resources = !force_disable_reclaim_resources; // Always use sync tokens so that code paths in resource provider that deal // with sync tokens are tested. capabilities_.delegated_sync_points_required = true; @@ -160,13 +154,6 @@ } } -void TestCompositorFrameSink::ForceReclaimResources() { - if (capabilities_.can_force_reclaim_resources && - delegated_local_surface_id_.is_valid()) { - support_->ForceReclaimResources(); - } -} - void TestCompositorFrameSink::DidReceiveCompositorFrameAck( const ReturnedResourceArray& resources) { ReclaimResources(resources);
diff --git a/cc/test/test_compositor_frame_sink.h b/cc/test/test_compositor_frame_sink.h index 3b00ae0..dad6c04 100644 --- a/cc/test/test_compositor_frame_sink.h +++ b/cc/test/test_compositor_frame_sink.h
@@ -57,8 +57,7 @@ gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, const RendererSettings& renderer_settings, scoped_refptr<base::SingleThreadTaskRunner> task_runner, - bool synchronous_composite, - bool force_disable_reclaim_resources); + bool synchronous_composite); ~TestCompositorFrameSink() override; // This client must be set before BindToClient() happens. @@ -79,7 +78,6 @@ void DetachFromClient() override; void SetLocalSurfaceId(const LocalSurfaceId& local_surface_id) override; void SubmitCompositorFrame(CompositorFrame frame) override; - void ForceReclaimResources() override; // CompositorFrameSinkSupportClient implementation. void DidReceiveCompositorFrameAck(
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 89c7ab70..5d38bf5 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -324,15 +324,6 @@ void LayerTreeHostImpl::BeginCommit() { TRACE_EVENT0("cc", "LayerTreeHostImpl::BeginCommit"); - // Ensure all textures are returned so partial texture updates can happen - // during the commit. - // TODO(ericrk): We should not need to ForceReclaimResources when using - // Impl-side-painting as it doesn't upload during commits. However, - // Display::Draw currently relies on resource being reclaimed to block drawing - // between BeginCommit / Swap. See crbug.com/489515. - if (compositor_frame_sink_) - compositor_frame_sink_->ForceReclaimResources(); - if (!CommitToActiveTree()) CreatePendingTree(); } @@ -800,8 +791,8 @@ !root_surface->layer_list().empty(); bool hud_wants_to_draw_ = active_tree_->hud_layer() && active_tree_->hud_layer()->IsAnimatingHUDContents(); - bool resources_must_be_resent = - compositor_frame_sink_->capabilities().can_force_reclaim_resources; + bool must_always_swap = + compositor_frame_sink_->capabilities().must_always_swap; // When touch handle visibility changes there is no visible damage // because touch handles are composited in the browser. However we // still want the browser to be notified that the handles changed @@ -812,8 +803,7 @@ if (root_surface_has_contributing_layers && root_surface_has_no_visible_damage && !active_tree_->property_trees()->effect_tree.HasCopyRequests() && - !resources_must_be_resent && !hud_wants_to_draw_ && - !handle_visibility_changed) { + !must_always_swap && !hud_wants_to_draw_ && !handle_visibility_changed) { TRACE_EVENT0("cc", "LayerTreeHostImpl::CalculateRenderPasses::EmptyDamageRect"); frame->has_no_damage = true;
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 74f2ab2..34d269f 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -8805,8 +8805,7 @@ auto compositor_frame_sink = base::MakeUnique<TestCompositorFrameSink>( context_provider, TestContextProvider::CreateWorker(), nullptr, nullptr, RendererSettings(), base::ThreadTaskRunnerHandle::Get().get(), - true /* synchronous_composite */, - false /* force_disable_reclaim_resources */); + true /* synchronous_composite */); compositor_frame_sink->SetClient(&test_client_); CreateHostImpl(DefaultSettings(), std::move(compositor_frame_sink)); @@ -11912,32 +11911,6 @@ EXPECT_FALSE(host_impl_->use_msaa()); } -// A mock output surface which lets us detect calls to ForceReclaimResources. -class MockReclaimResourcesCompositorFrameSink : public FakeCompositorFrameSink { - public: - MockReclaimResourcesCompositorFrameSink() - : FakeCompositorFrameSink(TestContextProvider::Create(), - TestContextProvider::CreateWorker()) {} - - MOCK_METHOD0(ForceReclaimResources, void()); -}; - -// Display::Draw (and the planned Display Scheduler) currently rely on resources -// being reclaimed to block drawing between BeginCommit / Swap. This test -// ensures that BeginCommit triggers ForceReclaimResources. See -// crbug.com/489515. -TEST_F(LayerTreeHostImplTest, BeginCommitReclaimsResources) { - auto compositor_frame_sink = - base::MakeUnique<MockReclaimResourcesCompositorFrameSink>(); - // Hold an unowned pointer to the output surface to use for mock expectations. - MockReclaimResourcesCompositorFrameSink* mock_compositor_frame_sink = - compositor_frame_sink.get(); - - CreateHostImpl(DefaultSettings(), std::move(compositor_frame_sink)); - EXPECT_CALL(*mock_compositor_frame_sink, ForceReclaimResources()).Times(1); - host_impl_->BeginCommit(); -} - TEST_F(LayerTreeHostImplTest, UpdatePageScaleFactorOnActiveTree) { // Check page scale factor update in property trees when an update is made // on the active tree.
diff --git a/cc/trees/layer_tree_host_pixeltest_tiles.cc b/cc/trees/layer_tree_host_pixeltest_tiles.cc index d6145d57..a5c02acf 100644 --- a/cc/trees/layer_tree_host_pixeltest_tiles.cc +++ b/cc/trees/layer_tree_host_pixeltest_tiles.cc
@@ -157,11 +157,17 @@ void DidCommitAndDrawFrame() override { switch (layer_tree_host()->SourceFrameNumber()) { case 1: - // We have done one frame, so the layer's content has been rastered. - // Now we change the picture behind it to record something completely - // different, but we give a smaller invalidation rect. The layer should - // only re-raster the stuff in the rect. If it doesn't do partial raster - // it would re-raster the whole thing instead. + // We have done one frame, but the resource may not be available for + // partial raster yet. Force a second frame. + picture_layer_->SetNeedsDisplayRect(gfx::Rect(50, 50, 100, 100)); + break; + case 2: + // We have done two frames, so the layer's content has been rastered + // twice and the first frame's resource is available for partial + // raster. Now we change the picture behind it to record something + // completely different, but we give a smaller invalidation rect. The + // layer should only re-raster the stuff in the rect. If it doesn't do + // partial raster it would re-raster the whole thing instead. client_.set_blue_top(false); Finish(); picture_layer_->SetNeedsDisplayRect(gfx::Rect(50, 50, 100, 100));
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index 850a28f..b31b02d 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc
@@ -3085,7 +3085,6 @@ const RendererSettings& renderer_settings, base::SingleThreadTaskRunner* task_runner, bool synchronous_composite, - bool force_disable_reclaim_resources, base::Closure invalidate_callback) : TestCompositorFrameSink(std::move(compositor_context_provider), std::move(worker_context_provider), @@ -3093,8 +3092,7 @@ gpu_memory_buffer_manager, renderer_settings, task_runner, - synchronous_composite, - force_disable_reclaim_resources), + synchronous_composite), invalidate_callback_(std::move(invalidate_callback)) {} // TestCompositorFrameSink overrides. @@ -3130,7 +3128,6 @@ shared_bitmap_manager(), gpu_memory_buffer_manager(), layer_tree_host()->GetSettings().renderer_settings, ImplThreadTaskRunner(), false /* synchronous_composite */, - false /* force_disable_reclaim_resources */, std::move(on_draw_callback)); compositor_frame_sink_ = frame_sink.get(); return std::move(frame_sink); @@ -5747,14 +5744,11 @@ bool synchronous_composite = !HasImplThread() && !layer_tree_host()->GetSettings().single_thread_proxy_scheduler; - // Relaiming resources is parameterized for this test. - bool force_disable_reclaim_resources = !reclaim_resources_; return base::MakeUnique<TestCompositorFrameSink>( compositor_context_provider, std::move(worker_context_provider), shared_bitmap_manager(), gpu_memory_buffer_manager(), layer_tree_host()->GetSettings().renderer_settings, - ImplThreadTaskRunner(), synchronous_composite, - force_disable_reclaim_resources); + ImplThreadTaskRunner(), synchronous_composite); } void BeginTest() override { @@ -5801,19 +5795,13 @@ EXPECT_TRUE(swap_promise_result_[0].dtor_called); } - // Second swap promise fails to swap if not reclaiming resources from the - // Display. + // Second swap promise fails to swap. { base::AutoLock lock(swap_promise_result_[1].lock); EXPECT_TRUE(swap_promise_result_[1].did_activate_called); - if (!reclaim_resources_) { - EXPECT_FALSE(swap_promise_result_[1].did_swap_called); - EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called); - EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[1].reason); - } else { - EXPECT_TRUE(swap_promise_result_[1].did_swap_called); - EXPECT_FALSE(swap_promise_result_[1].did_not_swap_called); - } + EXPECT_FALSE(swap_promise_result_[1].did_swap_called); + EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called); + EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[1].reason); EXPECT_TRUE(swap_promise_result_[1].dtor_called); } @@ -5828,20 +5816,12 @@ } } - bool reclaim_resources_; int commit_count_ = 0; TestSwapPromiseResult swap_promise_result_[3]; }; -TEST_F(LayerTreeHostTestSynchronousCompositeSwapPromise, NoReclaim) { - reclaim_resources_ = false; - RunTest(CompositorMode::SINGLE_THREADED); -} - -TEST_F(LayerTreeHostTestSynchronousCompositeSwapPromise, Reclaim) { - reclaim_resources_ = true; - RunTest(CompositorMode::SINGLE_THREADED); -} +// Synchronous composite is a single-threaded only feature. +SINGLE_THREAD_TEST_F(LayerTreeHostTestSynchronousCompositeSwapPromise); // Make sure page scale and top control deltas are applied to the client even // when the LayerTreeHost doesn't have a root layer.
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index f7be83ed..2ba30af 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -512,9 +512,11 @@ java_files = [ "javatests/src/org/chromium/chrome/browser/media/RouterTestUtils.java", + "javatests/src/org/chromium/chrome/browser/vr_shell/EmulatedVrController.java", "javatests/src/org/chromium/chrome/browser/vr_shell/MockVrCoreVersionCheckerImpl.java", "javatests/src/org/chromium/chrome/browser/vr_shell/MockVrDaydreamApi.java", "javatests/src/org/chromium/chrome/browser/vr_shell/VrShellTest.java", + "javatests/src/org/chromium/chrome/browser/vr_shell/VrTestBase.java", "javatests/src/org/chromium/chrome/browser/vr_shell/VrUtils.java", "javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTest.java", ] @@ -531,6 +533,7 @@ "//third_party/android_protobuf:protobuf_nano_javalib", "//third_party/android_support_test_runner:runner_java", "//third_party/android_tools:android_support_v7_appcompat_java", + "//third_party/gvr-android-sdk:controller_test_api_java", "//third_party/gvr-android-sdk:gvr_common_java", "//ui/android:ui_java", ] @@ -882,6 +885,11 @@ "//net/android:net_test_support_apk", ] proguard_enabled = !is_java_debug + + # The test APK contains code from both the APK under test and the + # test APK when proguard is enabled. That causes this APK to exceed + # the dex limit. + enable_multidex = proguard_enabled } if (enable_vr) {
diff --git a/chrome/android/java/res/layout/button_preference_button.xml b/chrome/android/java/res/layout/button_preference_button.xml index 47ad44b..76e950d 100644 --- a/chrome/android/java/res/layout/button_preference_button.xml +++ b/chrome/android/java/res/layout/button_preference_button.xml
@@ -3,7 +3,9 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<!-- Layout used by ButtonPreference for the button widget style. --> +<!-- Layout used by ButtonPreference for the button widget style. + android:focusable="false" makes it possible to trigger an event with the 'ENTER' key. + See crbug.com/674736 --> <org.chromium.ui.widget.ButtonCompat xmlns:android="http://schemas.android.com/apk/res/android" xmlns:chrome="http://schemas.android.com/apk/res-auto" @@ -11,5 +13,6 @@ android:layout_height="wrap_content" android:layout_width="wrap_content" android:minHeight="40dp" + android:focusable="false" android:textColor="@android:color/white" chrome:buttonColor="@color/pref_accent_color" />
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/TabularContextMenuUi.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/TabularContextMenuUi.java index 5440368..64096dc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/TabularContextMenuUi.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/TabularContextMenuUi.java
@@ -91,6 +91,47 @@ } /** + * Creates a ViewPageAdapter based off the given list of views. + * @param activity Used to inflate the new ViewPager + * @param params Used to get the header text. + * @param itemGroups The list of views to put into the ViewPager. The string is the title of the + * tab + * @return Returns a complete tabular context menu view. + */ + @VisibleForTesting + View createPagerView(Activity activity, ContextMenuParams params, + List<Pair<Integer, List<ContextMenuItem>>> itemGroups) { + View view = LayoutInflater.from(activity).inflate(R.layout.tabular_context_menu, null); + + List<Pair<String, ViewGroup>> viewGroups = new ArrayList<>(); + int maxCount = 0; + for (int i = 0; i < itemGroups.size(); i++) { + Pair<Integer, List<ContextMenuItem>> itemGroup = itemGroups.get(i); + maxCount = Math.max(maxCount, itemGroup.second.size()); + } + for (int i = 0; i < itemGroups.size(); i++) { + Pair<Integer, List<ContextMenuItem>> itemGroup = itemGroups.get(i); + // TODO(tedchoc): Pass the ContextMenuGroup identifier to determine if it's an image. + boolean isImageTab = itemGroup.first == R.string.contextmenu_image_title; + viewGroups.add(new Pair<>(activity.getString(itemGroup.first), + createContextMenuPageUi( + activity, params, itemGroup.second, isImageTab, maxCount))); + } + TabularContextMenuViewPager pager = + (TabularContextMenuViewPager) view.findViewById(R.id.custom_pager); + pager.setAdapter(new TabularContextMenuPagerAdapter(viewGroups)); + + TabLayout tabLayout = (TabLayout) view.findViewById(R.id.tab_layout); + if (itemGroups.size() <= 1) { + tabLayout.setVisibility(View.GONE); + } else { + tabLayout.setupWithViewPager((ViewPager) view.findViewById(R.id.custom_pager)); + } + + return view; + } + + /** * Creates the view of a context menu. Based off the Context Type, it'll adjust the list of * items and display only the ones that'll be on that specific group. * @param activity Used to get the resources of an item. @@ -109,10 +150,13 @@ R.layout.tabular_context_menu_page, null); ListView listView = (ListView) baseLayout.findViewById(R.id.selectable_items); + displayHeaderIfVisibleItems(params, baseLayout); if (isImage) { + // #displayHeaderIfVisibleItems() sets these two views to GONE if the header text is + // empty but they should still be visible because we have an image to display. + baseLayout.findViewById(R.id.context_header_layout).setVisibility(View.VISIBLE); + baseLayout.findViewById(R.id.context_divider).setVisibility(View.VISIBLE); displayImageHeader(baseLayout, params, activity.getResources()); - } else { - displayHeaderIfVisibleItems(params, baseLayout); } // Set the list adapter and get the height to display it appropriately in a dialog. @@ -155,12 +199,6 @@ private void displayImageHeader( ViewGroup baseLayout, ContextMenuParams params, Resources resources) { - displayHeaderIfVisibleItems(params, baseLayout); - // #displayHeaderIfVisibleItems() sets these two views to GONE if the header text is - // empty but they should still be visible because we have an image to display. - baseLayout.findViewById(R.id.context_header_layout).setVisibility(View.VISIBLE); - baseLayout.findViewById(R.id.context_divider).setVisibility(View.VISIBLE); - mHeaderImageView = (ImageView) baseLayout.findViewById(R.id.context_header_image); TextView headerTextView = (TextView) baseLayout.findViewById(R.id.context_header_text); // We'd prefer the header text is the title text instead of the link text for images. @@ -210,46 +248,6 @@ } /** - * Creates a ViewPageAdapter based off the given list of views. - * @param activity Used to inflate the new ViewPager - * @param params Used to get the header text. - * @param itemGroups The list of views to put into the ViewPager. The string is the title of the - * tab - * @return Returns a complete tabular context menu view. - */ - @VisibleForTesting - View createPagerView(Activity activity, ContextMenuParams params, - List<Pair<Integer, List<ContextMenuItem>>> itemGroups) { - View view = LayoutInflater.from(activity).inflate(R.layout.tabular_context_menu, null); - - List<Pair<String, ViewGroup>> viewGroups = new ArrayList<>(); - int maxCount = 0; - for (int i = 0; i < itemGroups.size(); i++) { - Pair<Integer, List<ContextMenuItem>> itemGroup = itemGroups.get(i); - maxCount = Math.max(maxCount, itemGroup.second.size()); - } - for (int i = 0; i < itemGroups.size(); i++) { - Pair<Integer, List<ContextMenuItem>> itemGroup = itemGroups.get(i); - // TODO(tedchoc): Pass the ContextMenuGroup identifier to determine if it's an image. - boolean isImageTab = itemGroup.first == R.string.contextmenu_image_title; - viewGroups.add(new Pair<>(activity.getString(itemGroup.first), - createContextMenuPageUi( - activity, params, itemGroup.second, isImageTab, maxCount))); - } - TabularContextMenuViewPager pager = - (TabularContextMenuViewPager) view.findViewById(R.id.custom_pager); - pager.setAdapter(new TabularContextMenuPagerAdapter(viewGroups)); - - TabLayout tabLayout = (TabLayout) view.findViewById(R.id.tab_layout); - if (itemGroups.size() <= 1) { - tabLayout.setVisibility(View.GONE); - } - tabLayout.setupWithViewPager((ViewPager) view.findViewById(R.id.custom_pager)); - - return view; - } - - /** * When an thumbnail is retrieved for the header of an image, this will set the header to * that particular bitmap. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java index 9fac8503..740ebb1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java
@@ -1123,9 +1123,9 @@ @Override protected void onPostExecute(Intent intent) { - if (intent == null - || !ExternalNavigationDelegateImpl.resolveIntent(intent, true) - || !DownloadUtils.fireOpenIntentForDownload(context, intent)) { + if (intent == null || !ExternalNavigationDelegateImpl.resolveIntent(intent, true) + || !DownloadUtils.fireOpenIntentForDownload(context, intent) + || !hasDownloadManagerService()) { openDownloadsPage(context); } else { DownloadManagerService service =
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/ButtonPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/ButtonPreference.java index 93f08a5..67fadc1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/ButtonPreference.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/ButtonPreference.java
@@ -27,7 +27,7 @@ super(context, attrs); setLayoutResource(R.layout.button_preference_layout); setWidgetLayoutResource(R.layout.button_preference_button); - setSelectable(false); + setSelectable(true); } @Override @@ -43,5 +43,14 @@ } } }); + + View viewFrame = view.findViewById(android.R.id.widget_frame); + viewFrame.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + // This is intentionally left blank to prevent triggering an event after tapping + // any part of the view that is not the button. + } + }); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/BindingManagerIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/BindingManagerIntegrationTest.java index 0441146..241589f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/BindingManagerIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/BindingManagerIntegrationTest.java
@@ -119,7 +119,7 @@ } @Override - public void determinedVisibility(int pid) { + public void onDeterminedVisibility(int pid) { synchronized (mVisibilityCallsMap) { mVisibilityCallsMap.put(pid, mVisibilityCallsMap.get(pid) + "DETERMINED;"); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java index 324d7fd..476fc94 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
@@ -41,6 +41,7 @@ import android.view.ViewGroup; import android.widget.EditText; import android.widget.ImageButton; +import android.widget.TextView; import org.chromium.base.ActivityState; import org.chromium.base.ApplicationStatus; @@ -138,6 +139,20 @@ + " }" + " </script>" + "</body></html>"; + private static final String ONLOAD_TITLE_CHANGE = "<!DOCTYPE html><html><body>" + + " <script>" + + " window.onload = function () {" + + " document.title = \"nytimes.com\";" + + " }" + + " </script>" + + "</body></html>"; + private static final String DELAYED_TITLE_CHANGE = "<!DOCTYPE html><html><body>" + + " <script>" + + " window.onload = function () {" + + " setTimeout(function (){ document.title = \"nytimes.com\"}, 200);" + + " }" + + " </script>" + + "</body></html>"; private static int sIdToIncrement = 1; @@ -1058,6 +1073,84 @@ } /** + * Tests that TITLE_ONLY state works as expected with a title getting set onload. + */ + @SmallTest + public void testToolbarTitleOnlyStateWithProperTitle() throws InterruptedException { + final String url = mWebServer.setResponse("/test.html", ONLOAD_TITLE_CHANGE, null); + hideDomainAndEnsureTitleIsSet( + url, CustomTabsConnection.SpeculationParams.NO_SPECULATION, "nytimes.com"); + } + + /** + * Tests that TITLE_ONLY state works as expected with a title getting set during prerendering. + + */ + @SmallTest + public void testToolbarTitleOnlyStateWithProperTitlePrerendered() throws InterruptedException { + final String url = mWebServer.setResponse("/test.html", ONLOAD_TITLE_CHANGE, null); + hideDomainAndEnsureTitleIsSet( + url, CustomTabsConnection.SpeculationParams.PRERENDER, "nytimes.com"); + } + + /** + * Tests that TITLE_ONLY state works as expected with a title getting set delayed after load. + + */ + @SmallTest + public void testToolbarTitleOnlyStateWithDelayedTitle() throws InterruptedException { + final String url = mWebServer.setResponse("/test.html", DELAYED_TITLE_CHANGE, null); + hideDomainAndEnsureTitleIsSet( + url, CustomTabsConnection.SpeculationParams.NO_SPECULATION, "nytimes.com"); + } + + private void hideDomainAndEnsureTitleIsSet( + final String url, int speculation, final String expectedTitle) { + final CustomTabsConnection connection = warmUpAndWait(); + Context context = getInstrumentation().getTargetContext(); + Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(context, url); + intent.putExtra( + CustomTabsIntent.EXTRA_TITLE_VISIBILITY_STATE, CustomTabsIntent.SHOW_PAGE_TITLE); + final CustomTabsSessionToken token = + CustomTabsSessionToken.getSessionTokenFromIntent(intent); + assertTrue(connection.newSession(token)); + connection.mClientManager.setHideDomainForSession(token, true); + + if (speculation != CustomTabsConnection.SpeculationParams.NO_SPECULATION) { + connection.setSpeculationModeForSession(token, speculation); + assertTrue(connection.mayLaunchUrl(token, Uri.parse(url), null, null)); + try { + ensureCompletedSpeculationForUrl(connection, url, speculation); + } catch (Exception e1) { + fail(); + } + } + + try { + startCustomTabActivityWithIntent(intent); + } catch (InterruptedException e) { + fail(); + } + CriteriaHelper.pollUiThread(new Criteria() { + @Override + public boolean isSatisfied() { + final Tab currentTab = getActivity().getActivityTab(); + return url.equals(currentTab.getUrl()); + } + }); + CriteriaHelper.pollUiThread(new Criteria() { + @Override + public boolean isSatisfied() { + CustomTabToolbar toolbar = + (CustomTabToolbar) getActivity().findViewById(R.id.toolbar); + TextView titleBar = (TextView) toolbar.findViewById(R.id.title_bar); + return titleBar != null && titleBar.isShown() + && (titleBar.getText()).toString().equals(expectedTitle); + } + }); + } + + /** * Tests that basic postMessage functionality works through sending a single postMessage * request. */
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/EmulatedVrController.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/EmulatedVrController.java new file mode 100644 index 0000000..304169a --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/EmulatedVrController.java
@@ -0,0 +1,40 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.vr_shell; + +import android.content.Context; + +import com.google.vr.testframework.controller.ControllerTestApi; + +/** + * Wrapper for the ControllerTestApi class to handle more complex actions such + * as clicking and dragging. + * + * Requires that VrCore's settings file is modified to use the test API: + * - UseAutomatedController: true + * - PairedControllerDriver: "DRIVER_AUTOMATED" + * - PairedControllerAddress: "FOO" + */ +public class EmulatedVrController { + private final ControllerTestApi mApi; + + public EmulatedVrController(Context context) { + mApi = new ControllerTestApi(context); + } + + public ControllerTestApi getApi() { + return mApi; + } + + /** + * Presses and quickly releases the Daydream controller's touchpad button. + * Or, if the button is already pressed, releases and quickly presses again. + */ + public void pressReleaseTouchpadButton() { + mApi.buttonEvent.sendClickButtonEvent(); + } + + // TODO(bsheedy): Add support for more complex actions, e.g. click/drag/release +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellTest.java index 7452083b..db02139 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellTest.java
@@ -22,7 +22,6 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.compositor.CompositorViewHolder; import org.chromium.chrome.browser.tabmodel.TabModelSelector; -import org.chromium.chrome.test.ChromeTabbedActivityTestBase; import org.chromium.chrome.test.util.RenderUtils.ViewRenderer; import org.chromium.content.browser.ContentViewCore; import org.chromium.content.browser.test.util.Criteria; @@ -34,10 +33,12 @@ import java.util.concurrent.atomic.AtomicReference; /** - * Instrumentation tests for VR Shell (Chrome VR) + * End-to-end tests for VR browsing, aka "VR Shell". This may require + * interacting with WebVR in addition to the VR browser, so inherit from + * VrTestBase for the WebVR test framework. */ @CommandLineFlags.Add("enable-features=VrShell") -public class VrShellTest extends ChromeTabbedActivityTestBase { +public class VrShellTest extends VrTestBase { private static final String GOLDEN_DIR = "chrome/test/data/android/render_tests";
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrTestBase.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrTestBase.java new file mode 100644 index 0000000..d0bc080 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrTestBase.java
@@ -0,0 +1,212 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.vr_shell; + +import static org.chromium.chrome.browser.vr_shell.VrUtils.POLL_CHECK_INTERVAL_LONG_MS; +import static org.chromium.chrome.browser.vr_shell.VrUtils.POLL_CHECK_INTERVAL_SHORT_MS; +import static org.chromium.chrome.browser.vr_shell.VrUtils.POLL_TIMEOUT_LONG_MS; +import static org.chromium.chrome.browser.vr_shell.VrUtils.POLL_TIMEOUT_SHORT_MS; + +import org.chromium.base.Log; +import org.chromium.base.test.util.UrlUtils; +import org.chromium.chrome.test.ChromeTabbedActivityTestBase; +import org.chromium.content.browser.test.util.ClickUtils; +import org.chromium.content.browser.test.util.Criteria; +import org.chromium.content.browser.test.util.CriteriaHelper; +import org.chromium.content.browser.test.util.JavaScriptUtils; +import org.chromium.content_public.browser.WebContents; + +import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +/** + * This is a workaround for testing aspects of WebVR that aren't testable with + * WebVR's mocked layout tests, such as E2E tests. + * + * The general test flow is: + * - Load the HTML file containing the test, which: + * - Loads the WebVR boilerplate code and some test functions + * - Sets up common elements like the canvas and synchronization variable + * - Sets up any steps that need to be triggered by the Java code + * - Check if any VRDisplay objects were found and fail the test if it doesn't + * match what we expect for that test + * - Repeat: + * - Run any necessary Java-side code, e.g. trigger a user action + * - Trigger the next JavaScript test step and wait for it to finish + * + * The JavaScript code will automatically process test results once all + * testharness.js tests are done, just like in layout tests. Once the results + * are processed, the JavaScript code will automatically signal the Java code, + * which can then grab the results and pass/fail the instrumentation test. + */ +public class VrTestBase extends ChromeTabbedActivityTestBase { + private static final String TAG = "VrTestBase"; + protected static final String TEST_DIR = "chrome/test/data/android/webvr_instrumentation"; + protected static final int PAGE_LOAD_TIMEOUT_S = 10; + + protected WebContents mWebContents; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mWebContents = getActivity().getActivityTab().getWebContents(); + } + + @Override + public void startMainActivity() throws InterruptedException { + startMainActivityOnBlankPage(); + } + + /** + * Gets the file:// URL to the test file + * @param testName The name of the test whose file will be retrieved + * @return The file:// URL to the specified test file + */ + protected String getHtmlTestFile(String testName) { + return "file://" + UrlUtils.getIsolatedTestFilePath(TEST_DIR) + "/html/" + testName + + ".html"; + } + + /** + * Blocks until the promise returned by nagivator.getVRDisplays() resolves, + * then checks whether a VRDisplay was actually found. + * @param webContents The WebContents to run the JavaScript through + * @return Whether a VRDisplay was found + */ + protected boolean vrDisplayFound(WebContents webContents) { + pollJavaScriptBoolean("vrDisplayPromiseDone", POLL_TIMEOUT_SHORT_MS, webContents); + return !runJavaScriptOrFail("vrDisplay", POLL_TIMEOUT_SHORT_MS, webContents).equals("null"); + } + + /** + * Use to tap in the middle of the screen, triggering the canvas' onclick + * to fulfil WebVR's gesture requirement for presenting. + */ + protected void enterVrTap() { + ClickUtils.mouseSingleClickView( + getInstrumentation(), getActivity().getWindow().getDecorView().getRootView()); + } + + /** + * Taps in the middle of the screen then waits for the JavaScript step to finish. + * @param webContents The WebContents for the tab the JavaScript step is in + */ + protected void enterVrTapAndWait(WebContents webContents) { + enterVrTap(); + waitOnJavaScriptStep(webContents); + } + + /** + * Use to simulate a Daydream View NFC scan without blocking afterwards + */ + protected void simNfcScan() { + VrUtils.simNfc(getActivity()); + } + + /** + * Simulate an NFC scan and wait for the JavaScript code in the given + * WebContents to signal that it is done with the step. + * @param webContents The WebContents for the JavaScript that will be polled + */ + protected void simNfcScanAndWait(WebContents webContents) { + simNfcScan(); + waitOnJavaScriptStep(webContents); + } + + /** + * Helper function to run the given JavaScript, return the return value, + * and fail if a timeout/interrupt occurs so we don't have to catch or + * declare exceptions all the time. + * @param js The JavaScript to run + * @param timeout The timeout in milliseconds before a failure + * @param webContents The WebContents object to run the JavaScript in + * @return The return value of the JavaScript + */ + protected String runJavaScriptOrFail(String js, int timeout, WebContents webContents) { + try { + return JavaScriptUtils.executeJavaScriptAndWaitForResult( + webContents, js, timeout, TimeUnit.MILLISECONDS); + } catch (InterruptedException | TimeoutException e) { + fail("Fatal interruption or timeout running JavaScript: " + js); + } + return "Not reached"; + } + + /** + * Ends the test harness test and checks whether there it passed + * @param webContents The WebContents for the tab to check results in + * @return "Passed" if test passed, String with failure reason otherwise + */ + protected String checkResults(WebContents webContents) { + if (runJavaScriptOrFail("testPassed", POLL_TIMEOUT_SHORT_MS, webContents).equals("true")) { + return "Passed"; + } + return runJavaScriptOrFail("resultString", POLL_TIMEOUT_SHORT_MS, webContents); + } + + /** + * Helper function to end the test harness test and assert that it passed, + * setting the failure reason as the description if it didn't. + * @param webContents The WebContents for the tab to check test results in + */ + protected void endTest(WebContents webContents) { + assertEquals("Passed", checkResults(webContents)); + } + + /** + * Polls the provided JavaScript boolean until the timeout is reached or + * the boolean is true. + * @param boolName The name of the JavaScript boolean or expression to poll + * @param timeoutMs The polling timeout in milliseconds + * @param webContents The WebContents to run the JavaScript through + * @return True if the boolean evaluated to true, false if timed out + */ + protected boolean pollJavaScriptBoolean( + final String boolName, int timeoutMs, final WebContents webContents) { + try { + CriteriaHelper.pollInstrumentationThread(Criteria.equals(true, new Callable<Boolean>() { + @Override + public Boolean call() { + String result = "false"; + try { + result = JavaScriptUtils.executeJavaScriptAndWaitForResult(webContents, + boolName, POLL_CHECK_INTERVAL_SHORT_MS, TimeUnit.MILLISECONDS); + } catch (InterruptedException | TimeoutException e) { + // Expected to happen regularly, do nothing + } + return Boolean.parseBoolean(result); + } + }), timeoutMs, POLL_CHECK_INTERVAL_LONG_MS); + } catch (AssertionError e) { + Log.d(TAG, "pollJavaScriptBoolean() timed out"); + return false; + } + return true; + } + + /** + * Waits for a JavaScript step to finish, asserting that the step finished + * instead of timing out. + * @param webContents The WebContents for the tab the JavaScript step is in + */ + protected void waitOnJavaScriptStep(WebContents webContents) { + assertTrue("Polling JavaScript boolean javascriptDone succeeded", + pollJavaScriptBoolean("javascriptDone", POLL_TIMEOUT_LONG_MS, webContents)); + // Reset the synchronization boolean + runJavaScriptOrFail("javascriptDone = false", POLL_TIMEOUT_SHORT_MS, webContents); + } + + /** + * Executes a JavaScript step function using the given WebContents. + * @param stepFunction The JavaScript step function to call + * @param webContents The WebContents for the tab the JavaScript is in + */ + protected void executeStepAndWait(String stepFunction, WebContents webContents) { + // Run the step and block + JavaScriptUtils.executeJavaScript(webContents, stepFunction); + waitOnJavaScriptStep(webContents); + } +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTest.java index 7ef17e1..248d64f1 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTest.java
@@ -4,9 +4,6 @@ package org.chromium.chrome.browser.vr_shell; -import static org.chromium.chrome.browser.vr_shell.VrUtils.POLL_CHECK_INTERVAL_LONG_MS; -import static org.chromium.chrome.browser.vr_shell.VrUtils.POLL_CHECK_INTERVAL_SHORT_MS; -import static org.chromium.chrome.browser.vr_shell.VrUtils.POLL_TIMEOUT_LONG_MS; import static org.chromium.chrome.browser.vr_shell.VrUtils.POLL_TIMEOUT_SHORT_MS; import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_VIEWER_DAYDREAM; import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_WEBVR_SUPPORTED; @@ -17,213 +14,22 @@ import android.support.test.filters.SmallTest; import android.widget.TextView; -import org.chromium.base.Log; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Restriction; -import org.chromium.base.test.util.UrlUtils; import org.chromium.chrome.R; -import org.chromium.chrome.test.ChromeTabbedActivityTestBase; -import org.chromium.content.browser.test.util.ClickUtils; -import org.chromium.content.browser.test.util.Criteria; -import org.chromium.content.browser.test.util.CriteriaHelper; -import org.chromium.content.browser.test.util.JavaScriptUtils; -import org.chromium.content_public.browser.WebContents; -import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; /** - * This is a workaround for testing aspects of WebVR that aren't testable with - * WebVR's mocked layout tests, such as E2E tests. - * - * The general test flow is: - * - Load the HTML file containing the test, which: - * - Loads the WebVR boilerplate code and some test functions - * - Sets up common elements like the canvas and synchronization variable - * - Sets up any steps that need to be triggered by the Java code - * - Check if any VRDisplay objects were found and fail the test if it doesn't - * match what we expect for that test - * - Repeat: - * - Run any necessary Java-side code, e.g. trigger a user action - * - Trigger the next JavaScript test step and wait for it to finish - * - * The JavaScript code will automatically process test results once all - * testharness.js tests are done, just like in layout tests. Once the results - * are processed, the JavaScript code will automatically signal the Java code, - * which can then grab the results and pass/fail the instrumentation test. + * End-to-end tests for WebVR using the WebVR test framework from + * VrTestBase. */ @CommandLineFlags.Add("enable-webvr") @Restriction(RESTRICTION_TYPE_WEBVR_SUPPORTED) -public class WebVrTest extends ChromeTabbedActivityTestBase { +public class WebVrTest extends VrTestBase { private static final String TAG = "WebVrTest"; - private static final String TEST_DIR = "chrome/test/data/android/webvr_instrumentation"; - private static final int PAGE_LOAD_TIMEOUT_S = 10; - - private WebContents mWebContents; - - @Override - protected void setUp() throws Exception { - super.setUp(); - mWebContents = getActivity().getActivityTab().getWebContents(); - } - - @Override - public void startMainActivity() throws InterruptedException { - startMainActivityOnBlankPage(); - } - - /** - * Gets the file:// URL to the test file - * @param testName The name of the test whose file will be retrieved - * @return The file:// URL to the specified test file - */ - private String getHtmlTestFile(String testName) { - return "file://" + UrlUtils.getIsolatedTestFilePath(TEST_DIR) + "/html/" + testName - + ".html"; - } - - /** - * Blocks until the promise returned by nagivator.getVRDisplays() resolves, - * then checks whether a VRDisplay was actually found. - * @param webContents The WebContents to run the JavaScript through - * @return Whether a VRDisplay was found - */ - private boolean vrDisplayFound(WebContents webContents) { - pollJavaScriptBoolean("vrDisplayPromiseDone", POLL_TIMEOUT_SHORT_MS, webContents); - return !runJavaScriptOrFail("vrDisplay", POLL_TIMEOUT_SHORT_MS, webContents).equals("null"); - } - - /** - * Use to tap in the middle of the screen, triggering the canvas' onclick - * to fulfil WebVR's gesture requirement for presenting. - */ - private void enterVrTap() { - ClickUtils.mouseSingleClickView( - getInstrumentation(), getActivity().getWindow().getDecorView().getRootView()); - } - - /** - * Taps in the middle of the screen then waits for the JavaScript step to finish. - * @param webContents The WebContents for the tab the JavaScript step is in - */ - private void enterVrTapAndWait(WebContents webContents) { - enterVrTap(); - waitOnJavaScriptStep(webContents); - } - - /** - * Use to simulate a Daydream View NFC scan without blocking afterwards - */ - private void simNfcScan() { - VrUtils.simNfc(getActivity()); - } - - /** - * Simulate an NFC scan and wait for the JavaScript code in the given - * WebContents to signal that it is done with the step. - * @param webContents The WebContents for the JavaScript that will be polled - */ - private void simNfcScanAndWait(WebContents webContents) { - simNfcScan(); - waitOnJavaScriptStep(webContents); - } - - /** - * Helper function to run the given JavaScript, return the return value, - * and fail if a timeout/interrupt occurs so we don't have to catch or - * declare exceptions all the time. - * @param js The JavaScript to run - * @param timeout The timeout in milliseconds before a failure - * @param webContents The WebContents object to run the JavaScript in - * @return The return value of the JavaScript - */ - private String runJavaScriptOrFail(String js, int timeout, WebContents webContents) { - try { - return JavaScriptUtils.executeJavaScriptAndWaitForResult( - webContents, js, timeout, TimeUnit.MILLISECONDS); - } catch (InterruptedException | TimeoutException e) { - fail("Fatal interruption or timeout running JavaScript: " + js); - } - return "Not reached"; - } - - /** - * Ends the test harness test and checks whether there it passed - * @param webContents The WebContents for the tab to check results in - * @return "Passed" if test passed, String with failure reason otherwise - */ - private String checkResults(WebContents webContents) { - if (runJavaScriptOrFail("testPassed", POLL_TIMEOUT_SHORT_MS, webContents).equals("true")) { - return "Passed"; - } - return runJavaScriptOrFail("resultString", POLL_TIMEOUT_SHORT_MS, webContents); - } - - /** - * Helper function to end the test harness test and assert that it passed, - * setting the failure reason as the description if it didn't. - * @param webContents The WebContents for the tab to check test results in - */ - private void endTest(WebContents webContents) { - assertEquals("Passed", checkResults(webContents)); - } - - /** - * Polls the provided JavaScript boolean until the timeout is reached or - * the boolean is true. - * @param boolName The name of the JavaScript boolean or expression to poll - * @param timeoutMs The polling timeout in milliseconds - * @param webContents The WebContents to run the JavaScript through - * @return True if the boolean evaluated to true, false if timed out - */ - private boolean pollJavaScriptBoolean( - final String boolName, int timeoutMs, final WebContents webContents) { - try { - CriteriaHelper.pollInstrumentationThread(Criteria.equals(true, new Callable<Boolean>() { - @Override - public Boolean call() { - String result = "false"; - try { - result = JavaScriptUtils.executeJavaScriptAndWaitForResult(webContents, - boolName, POLL_CHECK_INTERVAL_SHORT_MS, TimeUnit.MILLISECONDS); - } catch (InterruptedException | TimeoutException e) { - // Expected to happen regularly, do nothing - } - return Boolean.parseBoolean(result); - } - }), timeoutMs, POLL_CHECK_INTERVAL_LONG_MS); - } catch (AssertionError e) { - Log.d(TAG, "pollJavaScriptBoolean() timed out"); - return false; - } - return true; - } - - /** - * Waits for a JavaScript step to finish, asserting that the step finished - * instead of timing out. - * @param webContents The WebContents for the tab the JavaScript step is in - */ - private void waitOnJavaScriptStep(WebContents webContents) { - assertTrue("Polling JavaScript boolean javascriptDone succeeded", - pollJavaScriptBoolean("javascriptDone", POLL_TIMEOUT_LONG_MS, webContents)); - // Reset the synchronization boolean - runJavaScriptOrFail("javascriptDone = false", POLL_TIMEOUT_SHORT_MS, webContents); - } - - /** - * Executes a JavaScript step function using the given WebContents. - * @param stepFunction The JavaScript step function to call - * @param webContents The WebContents for the tab the JavaScript is in - */ - private void executeStepAndWait(String stepFunction, WebContents webContents) { - // Run the step and block - JavaScriptUtils.executeJavaScript(webContents, stepFunction); - waitOnJavaScriptStep(webContents); - } /** * Tests that a successful requestPresent call actually enters VR @@ -284,6 +90,26 @@ } /** + * Tests that Daydream controller clicks are registered as screen taps when + * the viewer is a Daydream View. + */ + @LargeTest + @Restriction(RESTRICTION_TYPE_VIEWER_DAYDREAM) + public void testControllerClicksRegisteredAsTapsOnDaydream() throws InterruptedException { + EmulatedVrController controller = new EmulatedVrController(getActivity()); + String testName = "test_screen_taps_registered"; + loadUrl(getHtmlTestFile(testName), PAGE_LOAD_TIMEOUT_S); + assertTrue("VRDisplay found", vrDisplayFound(mWebContents)); + executeStepAndWait("stepVerifyNoInitialTaps()", mWebContents); + // Tap and wait to enter VR + enterVrTapAndWait(mWebContents); + // Send a controller click and wait for JavaScript to receive it + controller.pressReleaseTouchpadButton(); + waitOnJavaScriptStep(mWebContents); + endTest(mWebContents); + } + + /** * Tests that screen touches are still registered when the viewer is * Cardboard. */ @@ -293,7 +119,7 @@ */ @DisabledTest(message = "crbug.com/713781") public void testScreenTapsRegisteredOnCardboard() throws InterruptedException { - String testName = "test_screen_taps_registered_on_cardboard"; + String testName = "test_screen_taps_registered"; loadUrl(getHtmlTestFile(testName), PAGE_LOAD_TIMEOUT_S); assertTrue("VRDisplay found", vrDisplayFound(mWebContents)); executeStepAndWait("stepVerifyNoInitialTaps()", mWebContents);
diff --git a/chrome/android/shared_preference_files/test/vr_ddview_skipdon_setupcomplete.json b/chrome/android/shared_preference_files/test/vr_ddview_skipdon_setupcomplete.json index a34bfb3..6b7d0f2e 100644 --- a/chrome/android/shared_preference_files/test/vr_ddview_skipdon_setupcomplete.json +++ b/chrome/android/shared_preference_files/test/vr_ddview_skipdon_setupcomplete.json
@@ -5,7 +5,10 @@ "set": { "VrSkipDon": true, "DaydreamSetupComplete": true, - "VrDeviceParams": "CgxHb29nbGUsIEluYy4SDURheWRyZWFtIFZpZXcdCfkgPSUB3oI9KhAAAFxCAABcQgAAXEIAAFxCNd9PDT06CLgexT7Zzhc_WABgAJqRYBoIARIKDQAAAAAV9P3UPBIKDQAAAAAV9P3UvA" + "VrDeviceParams": "CgxHb29nbGUsIEluYy4SDURheWRyZWFtIFZpZXcdCfkgPSUB3oI9KhAAAFxCAABcQgAAXEIAAFxCNd9PDT06CLgexT7Zzhc_WABgAJqRYBoIARIKDQAAAAAV9P3UPBIKDQAAAAAV9P3UvA", + "UseAutomatedController": true, + "PairedControllerDriver": "DRIVER_AUTOMATED", + "PairedControllerAddress": "FOO" } } ]
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 84b5bee..f929816 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -2984,6 +2984,7 @@ "android/tab_state.h", "android/tab_web_contents_delegate_android.cc", "android/tab_web_contents_delegate_android.h", + "android/thumbnail/scoped_ptr_expiring_cache.h", "android/thumbnail/thumbnail.cc", "android/thumbnail/thumbnail.h", "android/thumbnail/thumbnail_cache.cc",
diff --git a/chrome/browser/android/offline_pages/offline_page_model_factory.cc b/chrome/browser/android/offline_pages/offline_page_model_factory.cc index 089b558..75f965b 100644 --- a/chrome/browser/android/offline_pages/offline_page_model_factory.cc +++ b/chrome/browser/android/offline_pages/offline_page_model_factory.cc
@@ -9,14 +9,13 @@ #include "base/files/file_path.h" #include "base/memory/singleton.h" #include "base/sequenced_task_runner.h" -#include "base/threading/sequenced_worker_pool.h" +#include "base/task_scheduler/post_task.h" #include "chrome/browser/profiles/incognito_helpers.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_constants.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/offline_pages/core/offline_page_metadata_store_sql.h" #include "components/offline_pages/core/offline_page_model_impl.h" -#include "content/public/browser/browser_thread.h" namespace offline_pages { @@ -42,8 +41,7 @@ content::BrowserContext* context) const { Profile* profile = Profile::FromBrowserContext(context); scoped_refptr<base::SequencedTaskRunner> background_task_runner = - content::BrowserThread::GetBlockingPool()->GetSequencedTaskRunner( - content::BrowserThread::GetBlockingPool()->GetSequenceToken()); + base::CreateSequencedTaskRunnerWithTraits(base::TaskTraits().MayBlock()); base::FilePath store_path = profile->GetPath().Append(chrome::kOfflinePageMetadataDirname);
diff --git a/chrome/browser/android/vr_shell/BUILD.gn b/chrome/browser/android/vr_shell/BUILD.gn index dc166f9..fc8cb2e 100644 --- a/chrome/browser/android/vr_shell/BUILD.gn +++ b/chrome/browser/android/vr_shell/BUILD.gn
@@ -20,6 +20,8 @@ "animation.h", "easing.cc", "easing.h", + "elbow_model.cc", + "elbow_model.h", "fps_meter.cc", "fps_meter.h", "gltf_asset.cc",
diff --git a/chrome/browser/android/vr_shell/elbow_model.cc b/chrome/browser/android/vr_shell/elbow_model.cc new file mode 100644 index 0000000..f71ece0 --- /dev/null +++ b/chrome/browser/android/vr_shell/elbow_model.cc
@@ -0,0 +1,142 @@ +// 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. + +// Adapted from: +// https://github.com/googlevr/gvr-unity-sdk/blob/master/Samples/DaydreamLabsControllerPlayground/Assets/GoogleVR/Scripts/Controller/GvrArmModel.cs + +#include "chrome/browser/android/vr_shell/elbow_model.h" + +#include <cmath> + +#include "device/vr/vr_math.h" + +namespace vr_shell { + +namespace { + +constexpr vr::Quatf kNoRotation = {0.0f, 0.0f, 0.0f, 1.0f}; +constexpr gfx::Point3F kDefaultShoulderRight = {0.19f, -0.19f, 0.03f}; +constexpr float kFadeDistanceFromFace = 0.34f; +constexpr gfx::Point3F kDefaultRelativeElbow = {0.195f, -0.5f, 0.075f}; +constexpr gfx::Point3F kDefaultRelativeWrist = {0.0f, 0.0f, -0.25f}; +constexpr gfx::Vector3dF kForward = {0.0f, 0.0f, -1.0f}; +constexpr gfx::Vector3dF kUp = {0.0f, 1.0f, 0.0f}; +constexpr gfx::Vector3dF kDefaultArmExtensionOffset = {-0.13f, 0.14f, -0.08f}; +constexpr float kMinExtensionAngle = 7.0f; +constexpr float kMaxExtenstionAngle = 60.0f; +constexpr float kExtensionWeight = 0.4f; +constexpr float kDeltaAlpha = 3.0f; +constexpr float kDefaultElbowRotationRatio = 0.4f; + +} // namespace + +ElbowModel::ElbowModel(gvr::ControllerHandedness handedness) + : handedness_(handedness), + alpha_value_(1.0f), + torso_direction_{0.0f, 0.0f, 0.0f} {} + +ElbowModel::~ElbowModel() = default; + +void ElbowModel::UpdateHandedness() { + handed_multiplier_ = { + handedness_ == GVR_CONTROLLER_RIGHT_HANDED ? 1.0f : -1.0f, 1.0f, 1.0f}; + shoulder_rotation_ = kNoRotation; + shoulder_position_ = + vr::ScalePoint(kDefaultShoulderRight, handed_multiplier_); +} + +void ElbowModel::Update(const UpdateData& update) { + UpdateHandedness(); + UpdateTorsoDirection(update); + ApplyArmModel(update); + UpdateTransparency(update); +} + +void ElbowModel::UpdateTorsoDirection(const UpdateData& update) { + auto head_direction = update.head_direction; + head_direction.set_y(0); + vr::NormalizeVector(&head_direction); + + // Determine the gaze direction horizontally. + float angular_velocity = update.gyro.Length(); + float gaze_filter_strength = + vr::Clampf((angular_velocity - 0.2f) / 45.0f, 0.0f, 0.1f); + torso_direction_ = + vr::QuatSlerp(torso_direction_, head_direction, gaze_filter_strength); + + // Rotate the fixed joints. + auto gaze_rotation = vr::GetVectorRotation(kForward, torso_direction_); + shoulder_rotation_ = gaze_rotation; + vr::Mat4f gaze_rotation_mat; + vr::QuatToMatrix(gaze_rotation, &gaze_rotation_mat); + shoulder_position_ = vr::ToPoint(vr::MatrixVectorRotate( + gaze_rotation_mat, vr::ToVector(shoulder_position_))); +} + +void ElbowModel::ApplyArmModel(const UpdateData& update) { + // Controller's orientation relative to the user. + auto controller_orientation = update.orientation; + controller_orientation = vr::QuatProduct(vr::InvertQuat(shoulder_rotation_), + controller_orientation); + + // Relative positions of the joints. + elbow_position_ = vr::ScalePoint(kDefaultRelativeElbow, handed_multiplier_); + wrist_position_ = vr::ScalePoint(kDefaultRelativeWrist, handed_multiplier_); + auto arm_extension_offset = + vr::ScaleVector(kDefaultArmExtensionOffset, handed_multiplier_); + + // Extract just the x rotation angle. + vr::Mat4f controller_orientation_mat; + QuatToMatrix(controller_orientation, &controller_orientation_mat); + auto controller_forward = + vr::MatrixVectorRotate(controller_orientation_mat, kForward); + float x_angle = + 90.0f - gfx::AngleBetweenVectorsInDegrees(controller_forward, kUp); + + // Remove the z rotation from the controller + auto x_y_rotation = vr::GetVectorRotation(kForward, controller_forward); + + // Offset the elbow by the extension. + float normalized_angle = (x_angle - kMinExtensionAngle) / + (kMaxExtenstionAngle - kMinExtensionAngle); + float extension_ratio = vr::Clampf(normalized_angle, 0.0f, 1.0f); + elbow_position_ = elbow_position_ + + gfx::ScaleVector3d(arm_extension_offset, extension_ratio); + + // Calculate the lerp interpolation factor. + float total_angle = vr::QuatAngleDegrees(x_y_rotation, kNoRotation); + float lerp_suppresion = 1.0f - pow(total_angle / 180.0f, 6); + float lerp_value = lerp_suppresion * (kDefaultElbowRotationRatio + + (1.0f - kDefaultElbowRotationRatio) * + extension_ratio * kExtensionWeight); + + // Apply the absolute rotations to the joints. + auto lerp_rotation = vr::QuatLerp(kNoRotation, x_y_rotation, lerp_value); + elbow_rotation_ = vr::QuatProduct( + vr::QuatProduct(shoulder_rotation_, vr::InvertQuat(lerp_rotation)), + controller_orientation); + wrist_rotation_ = vr::QuatProduct(shoulder_rotation_, controller_orientation); + + // Determine the relative positions. + vr::Mat4f shoulder_rotation_mat; + QuatToMatrix(shoulder_rotation_, &shoulder_rotation_mat); + elbow_position_ = vr::ToPoint(vr::MatrixVectorRotate( + shoulder_rotation_mat, vr::ToVector(elbow_position_))); + vr::Mat4f elbow_rotation_mat; + QuatToMatrix(elbow_rotation_, &elbow_rotation_mat); + wrist_position_ = + elbow_position_ + + vr::MatrixVectorRotate(elbow_rotation_mat, vr::ToVector(wrist_position_)); +} + +void ElbowModel::UpdateTransparency(const UpdateData& update) { + float distance_to_face = vr::ToVector(wrist_position_).Length(); + float alpha_change = kDeltaAlpha * update.delta_time_seconds; + alpha_value_ = vr::Clampf(distance_to_face < kFadeDistanceFromFace + ? alpha_value_ - alpha_change + : alpha_value_ + alpha_change, + 0.0f, 1.0f); +} + +} // namespace vr_shell
diff --git a/chrome/browser/android/vr_shell/elbow_model.h b/chrome/browser/android/vr_shell/elbow_model.h new file mode 100644 index 0000000..afb990ba4 --- /dev/null +++ b/chrome/browser/android/vr_shell/elbow_model.h
@@ -0,0 +1,57 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Adapted from: +// https://github.com/googlevr/gvr-unity-sdk/blob/master/Samples/DaydreamLabsControllerPlayground/Assets/GoogleVR/Scripts/Controller/GvrArmModel.cs + +#ifndef CHROME_BROWSER_ANDROID_VR_SHELL_ELBOW_MODEL_H_ +#define CHROME_BROWSER_ANDROID_VR_SHELL_ELBOW_MODEL_H_ + +#include "device/vr/vr_types.h" +#include "third_party/gvr-android-sdk/src/libraries/headers/vr/gvr/capi/include/gvr_types.h" + +namespace vr_shell { + +class ElbowModel { + public: + struct UpdateData { + bool connected; + vr::Quatf orientation; + gfx::Vector3dF gyro; + gfx::Vector3dF head_direction; + float delta_time_seconds; + }; + + explicit ElbowModel(gvr::ControllerHandedness handedness); + ~ElbowModel(); + + const gfx::Point3F& GetControllerPosition() const { return wrist_position_; } + const vr::Quatf& GetControllerRotation() const { return wrist_rotation_; } + float GetAlphaValue() const { return alpha_value_; } + + void Update(const UpdateData& update); + + private: + void UpdateHandedness(); + void UpdateTorsoDirection(const UpdateData& update); + void ApplyArmModel(const UpdateData& update); + void UpdateTransparency(const UpdateData& update); + + gvr::ControllerHandedness handedness_; + + gfx::Point3F wrist_position_; + vr::Quatf wrist_rotation_; + float alpha_value_; + + gfx::Point3F elbow_position_; + vr::Quatf elbow_rotation_; + gfx::Point3F shoulder_position_; + vr::Quatf shoulder_rotation_; + gfx::Vector3dF torso_direction_; + gfx::Vector3dF handed_multiplier_; +}; + +} // namespace vr_shell + +#endif // CHROME_BROWSER_ANDROID_VR_SHELL_ELBOW_MODEL_H_
diff --git a/chrome/browser/android/vr_shell/vr_controller.cc b/chrome/browser/android/vr_shell/vr_controller.cc index 177b3b6..89584100 100644 --- a/chrome/browser/android/vr_shell/vr_controller.cc +++ b/chrome/browser/android/vr_shell/vr_controller.cc
@@ -9,7 +9,9 @@ #include <utility> #include "base/logging.h" +#include "base/memory/ptr_util.h" #include "base/time/time.h" +#include "chrome/browser/android/vr_shell/elbow_model.h" #include "device/vr/vr_math.h" #include "third_party/gvr-android-sdk/src/libraries/headers/vr/gvr/capi/include/gvr.h" #include "third_party/gvr-android-sdk/src/libraries/headers/vr/gvr/capi/include/gvr_controller.h" @@ -41,11 +43,18 @@ constexpr int kMaxNumOfExtrapolations = 2; -static constexpr gfx::Point3F kControllerPosition = {0.2f, -0.5f, -0.15f}; +// Distance from the center of the controller to start rendering the laser. +constexpr float kLaserStartDisplacement = 0.045; void ClampTouchpadPosition(gfx::Vector2dF* position) { - position->set_x(std::min(std::max(0.0f, position->x()), 1.0f)); - position->set_y(std::min(std::max(0.0f, position->y()), 1.0f)); + position->set_x(vr::Clampf(position->x(), 0.0f, 1.0f)); + position->set_y(vr::Clampf(position->y(), 0.0f, 1.0f)); +} + +float DeltaTimeSeconds(int64_t last_timestamp_nanos) { + return (gvr::GvrApi::GetTimePointNow().monotonic_system_time_nanos - + last_timestamp_nanos) / + kNanoSecondsPerSecond; } } // namespace @@ -53,7 +62,10 @@ VrController::VrController(gvr_context* vr_context) { DVLOG(1) << __FUNCTION__ << "=" << this; Initialize(vr_context); + elbow_model_ = base::MakeUnique<ElbowModel>(handedness_); Reset(); + last_timestamp_nanos_ = + gvr::GvrApi::GetTimePointNow().monotonic_system_time_nanos; } VrController::~VrController() { @@ -114,18 +126,24 @@ } void VrController::GetTransform(vr::Mat4f* out) const { - // TODO(acondor): Position and orientation needs to be obtained - // from an elbow model. - // Placing the controller in a fixed position for now. - vr::SetIdentityM(out); - // Changing rotation point. - vr::TranslateM(*out, gfx::Vector3dF(0, 0, 0.05), out); - vr::Mat4f quat_to_matrix; - vr::QuatToMatrix(Orientation(), &quat_to_matrix); - vr::MatrixMul(quat_to_matrix, *out, out); - gfx::Vector3dF translation(kControllerPosition.x(), kControllerPosition.y(), - kControllerPosition.z() - 0.05); - vr::TranslateM(*out, translation, out); + QuatToMatrix(elbow_model_->GetControllerRotation(), out); + auto position = elbow_model_->GetControllerPosition(); + vr::TranslateM(*out, vr::ToVector(position), out); +} + +float VrController::GetOpacity() const { + return elbow_model_->GetAlphaValue(); +} + +gfx::Point3F VrController::GetPointerStart() const { + auto controller_position = elbow_model_->GetControllerPosition(); + gfx::Vector3dF pointer_direction{0.0f, -sin(kErgoAngleOffset), + -cos(kErgoAngleOffset)}; + vr::Mat4f rotation_mat; + vr::QuatToMatrix(Orientation(), &rotation_mat); + pointer_direction = vr::MatrixVectorRotate(rotation_mat, pointer_direction); + return controller_position + + gfx::ScaleVector3d(pointer_direction, kLaserStartDisplacement); } VrControllerModel::State VrController::GetModelState() const { @@ -162,7 +180,7 @@ return controller_state_->GetConnectionState() == gvr::kControllerConnected; } -void VrController::UpdateState() { +void VrController::UpdateState(const gfx::Vector3dF& head_direction) { const int32_t old_status = controller_state_->GetApiStatus(); const int32_t old_connection_state = controller_state_->GetConnectionState(); // Read current controller state. @@ -174,6 +192,12 @@ << gvr_controller_connection_state_to_string( controller_state_->GetConnectionState()); } + + const gvr::Vec3f& gvr_gyro = controller_state_->GetGyro(); + elbow_model_->Update({IsConnected(), Orientation(), + gfx::Vector3dF(gvr_gyro.x, gvr_gyro.y, gvr_gyro.z), + head_direction, + DeltaTimeSeconds(last_timestamp_nanos_)}); } void VrController::UpdateTouchInfo() { @@ -185,10 +209,7 @@ extrapolated_touch_++; touch_position_changed_ = true; // Fill the touch_info - float duration = - (gvr::GvrApi::GetTimePointNow().monotonic_system_time_nanos - - last_timestamp_nanos_) / - kNanoSecondsPerSecond; + float duration = DeltaTimeSeconds(last_timestamp_nanos_); touch_info_->touch_point.position.set_x(cur_touch_point_->position.x() + overall_velocity_.x() * duration); touch_info_->touch_point.position.set_y(cur_touch_point_->position.y() +
diff --git a/chrome/browser/android/vr_shell/vr_controller.h b/chrome/browser/android/vr_shell/vr_controller.h index 9cc0b3d..d3afda8 100644 --- a/chrome/browser/android/vr_shell/vr_controller.h +++ b/chrome/browser/android/vr_shell/vr_controller.h
@@ -25,6 +25,11 @@ namespace vr_shell { +class ElbowModel; + +// Angle (radians) the beam down from the controller axis, for wrist comfort. +constexpr float kErgoAngleOffset = 0.26f; + class VrController { public: // Controller API entry point. @@ -43,7 +48,7 @@ device::GvrGamepadData GetGamepadData(); // Must be called when the GL renderer gets OnDrawFrame(). - void UpdateState(); + void UpdateState(const gfx::Vector3dF& head_direction); std::vector<std::unique_ptr<WebGestureEvent>> DetectGestures(); @@ -54,8 +59,9 @@ float TouchPosY(); vr::Quatf Orientation() const; - void GetTransform(vr::Mat4f* out) const; + float GetOpacity() const; + gfx::Point3F GetPointerStart() const; VrControllerModel::State GetModelState() const; @@ -170,6 +176,8 @@ // Number of consecutively extrapolated touch points int extrapolated_touch_ = 0; + std::unique_ptr<ElbowModel> elbow_model_; + DISALLOW_COPY_AND_ASSIGN(VrController); };
diff --git a/chrome/browser/android/vr_shell/vr_shell_gl.cc b/chrome/browser/android/vr_shell/vr_shell_gl.cc index 27e62da0..6eaa0dd9 100644 --- a/chrome/browser/android/vr_shell/vr_shell_gl.cc +++ b/chrome/browser/android/vr_shell/vr_shell_gl.cc
@@ -47,15 +47,8 @@ static constexpr float kLaserWidth = 0.01f; -// Angle (radians) the beam down from the controller axis, for wrist comfort. -static constexpr float kErgoAngleOffset = 0.26f; - static constexpr gfx::Point3F kOrigin = {0.0f, 0.0f, 0.0f}; -// In lieu of an elbow model, we assume a position for the user's hand. -// TODO(mthiesse): Handedness options. -static constexpr gfx::Point3F kHandPosition = {0.2f, -0.5f, -0.2f}; - // Fraction of the distance to the object the cursor is drawn at to avoid // rounding errors drawing the cursor behind the object. static constexpr float kReticleOffset = 0.99f; @@ -514,15 +507,16 @@ FROM_HERE, base::Bind(&VrShell::GvrDelegateReady, weak_vr_shell_)); } -void VrShellGl::UpdateController() { - controller_->UpdateState(); +void VrShellGl::UpdateController(const gfx::Vector3dF& head_direction) { + controller_->UpdateState(head_direction); + pointer_start_ = controller_->GetPointerStart(); device::GvrGamepadData pad = controller_->GetGamepadData(); main_thread_task_runner_->PostTask( FROM_HERE, base::Bind(&VrShell::UpdateGamepadData, weak_vr_shell_, pad)); } -void VrShellGl::HandleControllerInput(const gfx::Vector3dF& forward_vector) { +void VrShellGl::HandleControllerInput(const gfx::Vector3dF& head_direction) { if (ShouldDrawWebVr()) { // Process screen touch events for Cardboard button compatibility. // Also send tap events for controller "touchpad click" events. @@ -546,7 +540,7 @@ // No controller detected, set up a gaze cursor that tracks the // forward direction. ergo_neutral_pose = {0.0f, 0.0f, -1.0f}; - controller_quat_ = GetRotationFromZAxis(forward_vector); + controller_quat_ = GetRotationFromZAxis(head_direction); } else { ergo_neutral_pose = {0.0f, -sin(kErgoAngleOffset), -cos(kErgoAngleOffset)}; controller_quat_ = controller_->Orientation(); @@ -579,7 +573,7 @@ // simplicity. float distance = scene_->GetBackgroundDistance(); target_point_ = - vr::GetRayPoint(kHandPosition, controller_direction, distance); + vr::GetRayPoint(pointer_start_, controller_direction, distance); gfx::Vector3dF eye_to_target = target_point_ - kOrigin; vr::NormalizeVector(&eye_to_target); @@ -866,8 +860,9 @@ // TODO(crbug.com/704690): Acquire controller state in a way that's timely // for both the gamepad API and UI input handling. TRACE_EVENT0("gpu", "VrShellGl::UpdateController"); - UpdateController(); - HandleControllerInput(vr::GetForwardVector(head_pose)); + auto head_direction = vr::GetForwardVector(head_pose); + UpdateController(head_direction); + HandleControllerInput(head_direction); } DrawWorldElements(head_pose); @@ -983,8 +978,8 @@ DrawElements(render_matrix, elementsInDrawOrder); if (draw_cursor) { - DrawCursor(render_matrix); DrawController(render_matrix); + DrawCursor(render_matrix); } } } @@ -1100,7 +1095,7 @@ // Find the length of the beam (from hand to target). const float laser_length = - std::sqrt(kHandPosition.SquaredDistanceTo(target_point)); + std::sqrt(pointer_start_.SquaredDistanceTo(target_point)); // Build a beam, originating from the origin. vr::SetIdentityM(&mat); @@ -1114,11 +1109,12 @@ vr::QuatToMatrix(quat, &rotation_mat); vr::MatrixMul(rotation_mat, mat, &mat); - const gfx::Vector3dF beam_direction = target_point_ - kHandPosition; + const gfx::Vector3dF beam_direction = target_point_ - pointer_start_; vr::Mat4f beam_direction_mat; vr::QuatToMatrix(GetRotationFromZAxis(beam_direction), &beam_direction_mat); + float opacity = controller_->GetOpacity(); // Render multiple faces to make the laser appear cylindrical. const int faces = 4; for (int i = 0; i < faces; i++) { @@ -1132,22 +1128,23 @@ vr::MatrixMul(beam_direction_mat, face_transform, &face_transform); // Move the beam origin to the hand. - vr::TranslateM(face_transform, kHandPosition - kOrigin, &face_transform); + vr::TranslateM(face_transform, pointer_start_ - kOrigin, &face_transform); vr::MatrixMul(render_matrix, face_transform, &transform); - vr_shell_renderer_->GetLaserRenderer()->Draw(transform); + vr_shell_renderer_->GetLaserRenderer()->Draw(opacity, transform); } } void VrShellGl::DrawController(const vr::Mat4f& view_proj_matrix) { if (!vr_shell_renderer_->GetControllerRenderer()->IsSetUp()) return; + auto state = controller_->GetModelState(); + auto opacity = controller_->GetOpacity(); vr::Mat4f controller_transform; controller_->GetTransform(&controller_transform); vr::Mat4f transform; vr::MatrixMul(view_proj_matrix, controller_transform, &transform); - auto state = controller_->GetModelState(); - vr_shell_renderer_->GetControllerRenderer()->Draw(state, transform); + vr_shell_renderer_->GetControllerRenderer()->Draw(state, opacity, transform); } bool VrShellGl::ShouldDrawWebVr() {
diff --git a/chrome/browser/android/vr_shell/vr_shell_gl.h b/chrome/browser/android/vr_shell/vr_shell_gl.h index 8aa1406..f01c3b3b 100644 --- a/chrome/browser/android/vr_shell/vr_shell_gl.h +++ b/chrome/browser/android/vr_shell/vr_shell_gl.h
@@ -130,8 +130,8 @@ void DrawWebVr(); bool WebVrPoseByteIsValid(int pose_index_byte); - void UpdateController(); - void HandleControllerInput(const gfx::Vector3dF& forward_vector); + void UpdateController(const gfx::Vector3dF& head_direction); + void HandleControllerInput(const gfx::Vector3dF& head_direction); void HandleControllerAppButtonActivity( const gfx::Vector3dF& controller_direction); void SendEventsToTarget(InputTarget input_target, int pixel_x, int pixel_y); @@ -232,6 +232,8 @@ std::unique_ptr<FPSMeter> fps_meter_; + gfx::Point3F pointer_start_; + base::WeakPtrFactory<VrShellGl> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(VrShellGl);
diff --git a/chrome/browser/android/vr_shell/vr_shell_renderer.cc b/chrome/browser/android/vr_shell/vr_shell_renderer.cc index 61a5f0d..b037a0b0 100644 --- a/chrome/browser/android/vr_shell/vr_shell_renderer.cc +++ b/chrome/browser/android/vr_shell/vr_shell_renderer.cc
@@ -208,6 +208,7 @@ uniform lowp vec4 color; uniform mediump float fade_point; uniform mediump float fade_end; + uniform mediump float u_Opacity; void main() { mediump vec2 uv = v_TexCoordinate; @@ -218,7 +219,8 @@ mediump float total_fade = front_fade_factor * back_fade_factor; lowp vec4 texture_color = texture2D(texture_unit, uv); lowp vec4 final_color = color * texture_color; - gl_FragColor = vec4(final_color.xyz, final_color.w * total_fade); + gl_FragColor = vec4(final_color.xyz, + final_color.w * total_fade * u_Opacity); } /* clang-format on */); case vr_shell::ShaderID::GRADIENT_QUAD_FRAGMENT_SHADER: @@ -244,9 +246,11 @@ precision mediump float; uniform sampler2D u_texture; varying vec2 v_TexCoordinate; + uniform mediump float u_Opacity; void main() { - gl_FragColor = texture2D(u_texture, v_TexCoordinate); + lowp vec4 texture_color = texture2D(u_texture, v_TexCoordinate); + gl_FragColor = vec4(texture_color.xyz, texture_color.w * u_Opacity); } /* clang-format on */); default: @@ -544,6 +548,7 @@ color_handle_ = glGetUniformLocation(program_handle_, "color"); fade_point_handle_ = glGetUniformLocation(program_handle_, "fade_point"); fade_end_handle_ = glGetUniformLocation(program_handle_, "fade_end"); + opacity_handle_ = glGetUniformLocation(program_handle_, "u_Opacity"); glGenTextures(1, &texture_data_handle_); glBindTexture(GL_TEXTURE_2D, texture_data_handle_); @@ -557,7 +562,7 @@ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } -void LaserRenderer::Draw(const vr::Mat4f& view_proj_matrix) { +void LaserRenderer::Draw(float opacity, const vr::Mat4f& view_proj_matrix) { PrepareToDraw(model_view_proj_matrix_handle_, view_proj_matrix); // Link texture data with texture unit. @@ -569,6 +574,7 @@ kLaserColor[3]); glUniform1f(fade_point_handle_, kFadePoint); glUniform1f(fade_end_handle_, kFadeEnd); + glUniform1f(opacity_handle_, opacity); glDrawArrays(GL_TRIANGLES, 0, kVerticesNumber); @@ -584,6 +590,7 @@ model_view_proj_matrix_handle_ = glGetUniformLocation(program_handle_, "u_ModelViewProjMatrix"); tex_uniform_handle_ = glGetUniformLocation(program_handle_, "u_Texture"); + opacity_handle_ = glGetUniformLocation(program_handle_, "u_Opacity"); } ControllerRenderer::~ControllerRenderer() = default; @@ -632,9 +639,12 @@ } void ControllerRenderer::Draw(VrControllerModel::State state, + float opacity, const vr::Mat4f& view_proj_matrix) { glUseProgram(program_handle_); + glUniform1f(opacity_handle_, opacity); + glUniformMatrix4fv(model_view_proj_matrix_handle_, 1, false, MatrixToGLArray(view_proj_matrix).data());
diff --git a/chrome/browser/android/vr_shell/vr_shell_renderer.h b/chrome/browser/android/vr_shell/vr_shell_renderer.h index 0b1c5aa..7a046ab 100644 --- a/chrome/browser/android/vr_shell/vr_shell_renderer.h +++ b/chrome/browser/android/vr_shell/vr_shell_renderer.h
@@ -178,7 +178,7 @@ LaserRenderer(); ~LaserRenderer() override; - void Draw(const vr::Mat4f& view_proj_matrix); + void Draw(float opacity, const vr::Mat4f& view_proj_matrix); private: GLuint model_view_proj_matrix_handle_; @@ -187,6 +187,7 @@ GLuint color_handle_; GLuint fade_point_handle_; GLuint fade_end_handle_; + GLuint opacity_handle_; DISALLOW_COPY_AND_ASSIGN(LaserRenderer); }; @@ -197,12 +198,15 @@ ~ControllerRenderer() override; void SetUp(std::unique_ptr<VrControllerModel> model); - void Draw(VrControllerModel::State state, const vr::Mat4f& view_proj_matrix); + void Draw(VrControllerModel::State state, + float opacity, + const vr::Mat4f& view_proj_matrix); bool IsSetUp() const { return setup_; } private: GLuint model_view_proj_matrix_handle_; GLuint tex_uniform_handle_; + GLuint opacity_handle_; GLuint indices_buffer_ = 0; GLuint vertex_buffer_ = 0; GLint position_components_ = 0;
diff --git a/chrome/browser/app_controller_mac_browsertest.mm b/chrome/browser/app_controller_mac_browsertest.mm index c0b4161b..1d46c37 100644 --- a/chrome/browser/app_controller_mac_browsertest.mm +++ b/chrome/browser/app_controller_mac_browsertest.mm
@@ -16,6 +16,7 @@ #include "base/run_loop.h" #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" #include "chrome/app/chrome_command_ids.h" #import "chrome/browser/app_controller_mac.h" #include "chrome/browser/apps/app_browsertest_util.h" @@ -257,6 +258,7 @@ base::scoped_nsobject<AppController> ac([[AppController alloc] init]); // Lock the active profile. + base::ThreadRestrictions::ScopedAllowIO allow_io; Profile* profile = [ac lastProfile]; ProfileAttributesEntry* entry; ASSERT_TRUE(g_browser_process->profile_manager()-> @@ -292,6 +294,7 @@ base::scoped_nsobject<AppController> ac([[AppController alloc] init]); + base::ThreadRestrictions::ScopedAllowIO allow_io; Profile* profile = [ac lastProfile]; EXPECT_EQ(ProfileManager::GetGuestProfilePath(), profile->GetPath()); EXPECT_TRUE(profile->IsGuestSession()); @@ -326,6 +329,7 @@ // Prohibiting guest mode forces the user manager flow for About Chrome. local_state->SetBoolean(prefs::kBrowserGuestModeEnabled, false); + base::ThreadRestrictions::ScopedAllowIO allow_io; Profile* guest_profile = [ac lastProfile]; EXPECT_EQ(ProfileManager::GetGuestProfilePath(), guest_profile->GetPath()); EXPECT_TRUE(guest_profile->IsGuestSession()); @@ -538,6 +542,7 @@ BookmarkModelFactory::GetForBrowserContext(profile1)); // Create profile 2. + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath path2 = profile_manager->GenerateNextProfileDirectoryPath(); Profile* profile2 = Profile::CreateProfile(path2, NULL, Profile::CREATE_MODE_SYNCHRONOUS);
diff --git a/chrome/browser/apps/app_browsertest.cc b/chrome/browser/apps/app_browsertest.cc index 2fdf6f8..e258bdd 100644 --- a/chrome/browser/apps/app_browsertest.cc +++ b/chrome/browser/apps/app_browsertest.cc
@@ -15,6 +15,7 @@ #include "base/macros.h" #include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/apps/app_browsertest_util.h" @@ -601,6 +602,7 @@ // a handler accepts "". IN_PROC_BROWSER_TEST_F(PlatformAppWithFileBrowserTest, LaunchWithFileEmptyExtension) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); base::FilePath test_file; @@ -615,6 +617,7 @@ // a handler accepts *. IN_PROC_BROWSER_TEST_F(PlatformAppWithFileBrowserTest, LaunchWithFileEmptyExtensionAcceptAny) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); base::FilePath test_file; @@ -723,6 +726,7 @@ // Tests that the file is created if the file does not exist and the app has the // fileSystem.write permission. IN_PROC_BROWSER_TEST_F(PlatformAppWithFileBrowserTest, LaunchNewFile) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); ASSERT_TRUE(RunPlatformAppTestWithFile(
diff --git a/chrome/browser/apps/app_shim/app_shim_host_manager_browsertest_mac.mm b/chrome/browser/apps/app_shim/app_shim_host_manager_browsertest_mac.mm index 33f94c5..919877c 100644 --- a/chrome/browser/apps/app_shim/app_shim_host_manager_browsertest_mac.mm +++ b/chrome/browser/apps/app_shim/app_shim_host_manager_browsertest_mac.mm
@@ -10,6 +10,7 @@ #include "base/logging.h" #include "base/macros.h" #include "base/path_service.h" +#include "base/threading/thread_restrictions.h" #include "chrome/browser/apps/app_shim/app_shim_handler_mac.h" #include "chrome/browser/apps/app_shim/test/app_shim_host_manager_test_api_mac.h" #include "chrome/browser/browser_process.h" @@ -65,6 +66,7 @@ user_data_dir.Append(app_mode::kAppShimSocketSymlinkName); base::FilePath socket_path; + base::ThreadRestrictions::ScopedAllowIO allow_io; CHECK(base::ReadSymbolicLink(symlink_path, &socket_path)); app_mode::VerifySocketPermissions(socket_path); @@ -76,7 +78,10 @@ this, io_thread_.task_runner().get()); } -TestShimClient::~TestShimClient() {} +TestShimClient::~TestShimClient() { + base::ThreadRestrictions::ScopedAllowIO allow_io; + io_thread_.Stop(); +} bool TestShimClient::OnMessageReceived(const IPC::Message& message) { return true; @@ -276,6 +281,7 @@ directory_in_tmp_ = test_api.directory_in_tmp(); // Check that socket files have been created. + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_TRUE(base::PathExists(directory_in_tmp_)); EXPECT_TRUE(base::PathExists(symlink_path_));
diff --git a/chrome/browser/apps/app_shim/app_shim_interactive_uitest_mac.mm b/chrome/browser/apps/app_shim/app_shim_interactive_uitest_mac.mm index ea990bd..238e0e1 100644 --- a/chrome/browser/apps/app_shim/app_shim_interactive_uitest_mac.mm +++ b/chrome/browser/apps/app_shim/app_shim_interactive_uitest_mac.mm
@@ -18,6 +18,7 @@ #include "base/strings/sys_string_conversions.h" #include "base/test/scoped_feature_list.h" #include "base/test/test_timeouts.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/apps/app_browsertest_util.h" #include "chrome/browser/apps/app_shim/app_shim_handler_mac.h" @@ -261,6 +262,7 @@ // (always) in tests. If it wasn't the case, the following test would fail // (but flakily since the creation happens on the FILE thread). shim_path_ = GetAppShimPath(profile(), app); + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_FALSE(base::PathExists(shim_path_)); // To create a shim in a test, instead call UpdateAllShortcuts, which has been
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc index bf978ee..32c2fe9 100644 --- a/chrome/browser/apps/guest_view/web_view_browsertest.cc +++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -19,6 +19,7 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "chrome/app/chrome_command_ids.h" @@ -2558,6 +2559,7 @@ "web_view/download"); ASSERT_TRUE(guest_web_contents); + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temporary_download_dir; ASSERT_TRUE(temporary_download_dir.CreateUniqueTempDir()); DownloadPrefs::FromBrowserContext(guest_web_contents->GetBrowserContext()) @@ -2715,6 +2717,7 @@ content::WebContents* web_contents = GetFirstAppWindowWebContents(); ASSERT_TRUE(web_contents); + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temporary_download_dir; ASSERT_TRUE(temporary_download_dir.CreateUniqueTempDir()); DownloadPrefs::FromBrowserContext(web_contents->GetBrowserContext()) @@ -2800,6 +2803,7 @@ content::WebContents* web_contents = GetFirstAppWindowWebContents(); ASSERT_TRUE(web_contents); + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temporary_download_dir; ASSERT_TRUE(temporary_download_dir.CreateUniqueTempDir()); DownloadPrefs::FromBrowserContext(web_contents->GetBrowserContext()) @@ -2858,6 +2862,7 @@ DownloadHistoryWaiter history_waiter(browser_context); history_waiter.WaitForHistoryLoad(); + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temporary_download_dir; ASSERT_TRUE(temporary_download_dir.Set( DownloadPrefs::FromBrowserContext(browser_context)->DownloadPath()));
diff --git a/chrome/browser/browsing_data/browsing_data_local_storage_helper_browsertest.cc b/chrome/browser/browsing_data/browsing_data_local_storage_helper_browsertest.cc index 0851507..8524ba33 100644 --- a/chrome/browser/browsing_data/browsing_data_local_storage_helper_browsertest.cc +++ b/chrome/browser/browsing_data/browsing_data_local_storage_helper_browsertest.cc
@@ -19,6 +19,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/thread_test_helper.h" #include "base/threading/sequenced_worker_pool.h" +#include "base/threading/thread_restrictions.h" #include "chrome/browser/browsing_data/browsing_data_helper_browsertest.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" @@ -54,6 +55,7 @@ class BrowsingDataLocalStorageHelperTest : public InProcessBrowserTest { protected: void CreateLocalStorageFilesForTest() { + base::ThreadRestrictions::ScopedAllowIO allow_io; // Note: This helper depends on details of how the dom_storage library // stores data in the host file system. base::FilePath storage_path = GetLocalStoragePathForTestingProfile(); @@ -128,6 +130,7 @@ content::RunAllBlockingPoolTasksUntilIdle(); // Ensure the file has been deleted. + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FileEnumerator file_enumerator( GetLocalStoragePathForTestingProfile(), false,
diff --git a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc index 70250bc..5700047 100644 --- a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc +++ b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc
@@ -10,6 +10,7 @@ #include "base/files/file_path.h" #include "base/path_service.h" #include "base/run_loop.h" +#include "base/threading/thread_restrictions.h" #include "chrome/browser/browsing_data/browsing_data_helper.h" #include "chrome/browser/browsing_data/cache_counter.h" @@ -77,6 +78,7 @@ } void DownloadAnItem() { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir downloads_directory; ASSERT_TRUE(downloads_directory.CreateUniqueTempDir()); browser()->profile()->GetPrefs()->SetFilePath(
diff --git a/chrome/browser/chrome_service_worker_browsertest.cc b/chrome/browser/chrome_service_worker_browsertest.cc index bfeee854..1d22706 100644 --- a/chrome/browser/chrome_service_worker_browsertest.cc +++ b/chrome/browser/chrome_service_worker_browsertest.cc
@@ -12,6 +12,7 @@ #include "base/run_loop.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" @@ -47,6 +48,7 @@ void WriteFile(const base::FilePath::StringType& filename, base::StringPiece contents) { + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_EQ(base::checked_cast<int>(contents.size()), base::WriteFile(service_worker_dir_.GetPath().Append(filename), contents.data(), contents.size()));
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 06ee059..a641111 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -364,6 +364,7 @@ "camera_presence_notifier.h", "certificate_provider/certificate_info.cc", "certificate_provider/certificate_info.h", + "certificate_provider/certificate_provider.h", "certificate_provider/certificate_provider_service.cc", "certificate_provider/certificate_provider_service.h", "certificate_provider/certificate_provider_service_factory.cc", @@ -811,6 +812,8 @@ "login/saml/saml_offline_signin_limiter_factory.h", "login/screen_manager.cc", "login/screen_manager.h", + "login/screens/app_launch_splash_screen_view.h", + "login/screens/arc_kiosk_splash_screen_view.h", "login/screens/arc_terms_of_service_screen.cc", "login/screens/arc_terms_of_service_screen.h", "login/screens/arc_terms_of_service_screen_view.h", @@ -877,6 +880,7 @@ "login/screens/update_view.h", "login/screens/user_image_screen.cc", "login/screens/user_image_screen.h", + "login/screens/user_image_view.h", "login/screens/user_selection_screen.cc", "login/screens/user_selection_screen.h", "login/screens/wrong_hwid_screen.cc", @@ -1077,6 +1081,7 @@ "platform_keys/platform_keys_service.h", "platform_keys/platform_keys_service_factory.cc", "platform_keys/platform_keys_service_factory.h", + "policy/active_directory_join_delegate.h", "policy/active_directory_policy_manager.cc", "policy/active_directory_policy_manager.h", "policy/affiliated_cloud_policy_invalidator.cc",
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc index 0e9d7764..06ecc1d9 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -6,6 +6,7 @@ #include "base/macros.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" #include "chrome/browser/chromeos/drive/file_system_util.h" #include "chrome/browser/chromeos/file_manager/file_manager_browsertest_base.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" @@ -631,6 +632,7 @@ // Adds a new user for testing to the current session. void AddUser(const TestAccountInfo& info, bool log_in) { + base::ThreadRestrictions::ScopedAllowIO allow_io; const AccountId account_id(AccountId::FromUserEmail(info.email)); if (log_in) { session_manager::SessionManager::Get()->CreateSession(account_id,
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc index e1769d3f..e5ffef3 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
@@ -14,6 +14,7 @@ #include "base/path_service.h" #include "base/run_loop.h" #include "base/strings/string_piece.h" +#include "base/threading/thread_restrictions.h" #include "base/time/time.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/drive/file_system_util.h" @@ -624,6 +625,7 @@ void FileManagerBrowserTestBase::OnMessage(const std::string& name, const base::DictionaryValue& value, std::string* output) { + base::ThreadRestrictions::ScopedAllowIO allow_io; if (name == "getTestName") { // Pass the test case name. *output = GetTestCaseNameParam();
diff --git a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_browsertest.cc b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_browsertest.cc index d5d975c..26c0c7c7 100644 --- a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_browsertest.cc +++ b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_browsertest.cc
@@ -16,6 +16,7 @@ #include "base/message_loop/message_loop.h" #include "base/path_service.h" #include "base/strings/string_number_conversions.h" +#include "base/threading/thread_restrictions.h" #include "base/time/time.h" #include "base/values.h" #include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_test_utils.h" @@ -102,6 +103,7 @@ const char* sub_dir, const wallpaper::WallpaperFilesId& wallpaper_files_id, const std::string& id) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath wallpaper_path = WallpaperManager::Get()->GetCustomWallpaperPath(sub_dir, wallpaper_files_id, id); @@ -113,6 +115,7 @@ // Logs in |account_id|. void LogIn(const AccountId& account_id, const std::string& user_id_hash) { + base::ThreadRestrictions::ScopedAllowIO allow_io; SessionManager::Get()->CreateSession(account_id, user_id_hash); SessionManager::Get()->SessionStarted(); // Flush to ensure the created session and ACTIVE state reaches ash. @@ -152,6 +155,7 @@ // Only needs to be called (once) by tests that want to test loading of // default wallpapers. void CreateCmdlineWallpapers() { + base::ThreadRestrictions::ScopedAllowIO allow_io; wallpaper_dir_.reset(new base::ScopedTempDir); ASSERT_TRUE(wallpaper_dir_->CreateUniqueTempDir()); wallpaper_manager_test_utils::CreateCmdlineWallpapers(
diff --git a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_test_utils.cc b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_test_utils.cc index 83d0e09..028da45f 100644 --- a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_test_utils.cc +++ b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_test_utils.cc
@@ -13,6 +13,7 @@ #include "base/logging.h" #include "base/macros.h" #include "base/run_loop.h" +#include "base/threading/thread_restrictions.h" #include "base/time/time.h" #include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h" #include "chromeos/chromeos_switches.h" @@ -111,6 +112,7 @@ int width, int height, SkColor color) { + base::ThreadRestrictions::ScopedAllowIO allow_io; std::vector<unsigned char> output; if (!CreateJPEGImage(width, height, color, &output)) return false;
diff --git a/chrome/browser/component_updater/sw_reporter_installer_win.cc b/chrome/browser/component_updater/sw_reporter_installer_win.cc index 385bf12..ea42ade 100644 --- a/chrome/browser/component_updater/sw_reporter_installer_win.cc +++ b/chrome/browser/component_updater/sw_reporter_installer_win.cc
@@ -498,13 +498,4 @@ registry->RegisterStringPref(prefs::kSwReporterPromptSeed, ""); } -void RegisterUserInitiatedSwReporterScan(base::Closure callback) { - // Fetch the latest version of the Cleanup component and run it, - // bypassing the usual scheduling logic. Once the scan is done, report - // whether the scan was successful and the names of the Unwanted Software that - // can be removed by the Cleanup tool. - // TODO(proberge): Implement me. - callback.Run(); -} - } // namespace component_updater
diff --git a/chrome/browser/component_updater/sw_reporter_installer_win.h b/chrome/browser/component_updater/sw_reporter_installer_win.h index 79064eb..dc3f19c 100644 --- a/chrome/browser/component_updater/sw_reporter_installer_win.h +++ b/chrome/browser/component_updater/sw_reporter_installer_win.h
@@ -93,10 +93,6 @@ void RegisterProfilePrefsForSwReporter( user_prefs::PrefRegistrySyncable* registry); -// Called by chrome://cleanup/ to manually trigger a reporter run. -// TODO(proberge): Replace the Closure with a typed callback. -void RegisterUserInitiatedSwReporterScan(base::Closure callback); - } // namespace component_updater #endif // CHROME_BROWSER_COMPONENT_UPDATER_SW_REPORTER_INSTALLER_WIN_H_
diff --git a/chrome/browser/devtools/devtools_sanity_browsertest.cc b/chrome/browser/devtools/devtools_sanity_browsertest.cc index 700ebf86..1bca197 100644 --- a/chrome/browser/devtools/devtools_sanity_browsertest.cc +++ b/chrome/browser/devtools/devtools_sanity_browsertest.cc
@@ -23,6 +23,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/task_scheduler/post_task.h" #include "base/test/test_timeouts.h" +#include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "chrome/browser/chrome_notification_types.h" @@ -597,6 +598,7 @@ const Extension* GetExtensionByPath( const extensions::ExtensionSet& extensions, const base::FilePath& path) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath extension_path = base::MakeAbsoluteFilePath(path); EXPECT_TRUE(!extension_path.empty()); for (const scoped_refptr<const Extension>& extension : extensions) {
diff --git a/chrome/browser/downgrade/user_data_downgrade_browsertest.cc b/chrome/browser/downgrade/user_data_downgrade_browsertest.cc index a395463..dbab5a47 100644 --- a/chrome/browser/downgrade/user_data_downgrade_browsertest.cc +++ b/chrome/browser/downgrade/user_data_downgrade_browsertest.cc
@@ -9,6 +9,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/test_reg_util_win.h" #include "base/threading/sequenced_worker_pool.h" +#include "base/threading/thread_restrictions.h" #include "base/version.h" #include "base/win/registry.h" #include "chrome/common/chrome_constants.h" @@ -115,6 +116,7 @@ // Verify the user data directory has been renamed and created again after // downgrade. IN_PROC_BROWSER_TEST_F(UserDataDowngradeBrowserCopyAndCleanTest, Test) { + base::ThreadRestrictions::ScopedAllowIO allow_io; content::BrowserThread::GetBlockingPool()->FlushForTesting(); EXPECT_EQ(chrome::kChromeVersion, GetLastVersion(user_data_dir_).GetString()); ASSERT_FALSE(base::PathExists(other_file_)); @@ -122,12 +124,14 @@ // Verify the user data directory will not be reset without downgrade. IN_PROC_BROWSER_TEST_F(UserDataDowngradeBrowserNoResetTest, Test) { + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_EQ(chrome::kChromeVersion, GetLastVersion(user_data_dir_).GetString()); ASSERT_TRUE(base::PathExists(other_file_)); } // Verify the "Last Version" file won't be created for non-msi install. IN_PROC_BROWSER_TEST_F(UserDataDowngradeBrowserNoMSITest, Test) { + base::ThreadRestrictions::ScopedAllowIO allow_io; ASSERT_FALSE(base::PathExists(last_version_file_path_)); ASSERT_TRUE(base::PathExists(other_file_)); }
diff --git a/chrome/browser/download/download_browsertest.cc b/chrome/browser/download/download_browsertest.cc index a6dab6d9..d5168de2 100644 --- a/chrome/browser/download/download_browsertest.cc +++ b/chrome/browser/download/download_browsertest.cc
@@ -31,6 +31,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/sys_info.h" #include "base/test/test_file_util.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/browser_process.h" @@ -503,6 +504,7 @@ if (!browser) return false; + base::ThreadRestrictions::ScopedAllowIO allow_io; if (!downloads_directory_.CreateUniqueTempDir()) return false; @@ -631,6 +633,7 @@ bool CheckDownloadFullPaths(Browser* browser, const base::FilePath& downloaded_file, const base::FilePath& origin_file) { + base::ThreadRestrictions::ScopedAllowIO allow_io; bool origin_file_exists = base::PathExists(origin_file); EXPECT_TRUE(origin_file_exists) << origin_file.value(); if (!origin_file_exists) @@ -697,6 +700,7 @@ SizeTestType type, const std::string& partial_indication, const std::string& total_indication) { + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_TRUE(type == SIZE_TEST_TYPE_UNKNOWN || type == SIZE_TEST_TYPE_KNOWN); if (type != SIZE_TEST_TYPE_KNOWN && type != SIZE_TEST_TYPE_UNKNOWN) return false; @@ -792,6 +796,7 @@ const int64_t file_size) { std::string file_contents; + base::ThreadRestrictions::ScopedAllowIO allow_io; bool read = base::ReadFileToString(path, &file_contents); EXPECT_TRUE(read) << "Failed reading file: " << path.value() << std::endl; if (!read) @@ -927,6 +932,7 @@ if (item->GetState() == content::DownloadItem::COMPLETE) { // Clean up the file, in case it ended up in the My Documents folder. + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath destination_folder = GetDownloadDirectory(browser()); base::FilePath my_downloaded_file = item->GetTargetFilePath(); EXPECT_TRUE(base::PathExists(my_downloaded_file)); @@ -1200,6 +1206,7 @@ EXPECT_EQ(1, browser()->tab_strip_model()->count()); base::FilePath file(FILE_PATH_LITERAL("download-test1.lib")); base::FilePath downloaded_file(DestinationFile(browser(), file)); + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_TRUE(content::IsFileQuarantined(downloaded_file, url, GURL())); CheckDownload(browser(), file, file); } @@ -1281,6 +1288,7 @@ ui_test_utils::NavigateToURL(browser(), url); // Check that we did not download the web page. + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_FALSE(base::PathExists(file_path)); // Check state. @@ -1380,6 +1388,7 @@ // Check that we did not download the file. base::FilePath file(FILE_PATH_LITERAL("download-test1.lib")); base::FilePath file_path(DestinationFile(browser(), file)); + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_FALSE(base::PathExists(file_path)); // Check state. @@ -1478,6 +1487,7 @@ // later. base::FilePath origin(OriginFile(base::FilePath(FILE_PATH_LITERAL( "downloads/a_zip_file.zip")))); + base::ThreadRestrictions::ScopedAllowIO allow_io; ASSERT_TRUE(base::PathExists(origin)); int64_t origin_file_size = 0; EXPECT_TRUE(base::GetFileSize(origin, &origin_file_size)); @@ -1982,6 +1992,7 @@ // Confirm the downloaded data exists. base::FilePath downloaded_file = GetDownloadDirectory(browser()); downloaded_file = downloaded_file.Append(FILE_PATH_LITERAL("a_red_dot.png")); + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_TRUE(base::PathExists(downloaded_file)); } @@ -2204,6 +2215,7 @@ browser()->tab_strip_model()->GetActiveWebContents(); ASSERT_TRUE(web_contents); + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath file(FILE_PATH_LITERAL("download-test1.lib")); base::ScopedTempDir other_directory; ASSERT_TRUE(other_directory.CreateUniqueTempDir()); @@ -2240,6 +2252,7 @@ browser()->tab_strip_model()->GetActiveWebContents(); ASSERT_TRUE(web_contents); + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath file(FILE_PATH_LITERAL("download-test1.lib")); base::ScopedTempDir other_directory; ASSERT_TRUE(other_directory.CreateUniqueTempDir()); @@ -2931,6 +2944,7 @@ content::DownloadManager* manager = DownloadManagerForBrowser(browser()); base::FilePath origin_file(OriginFile(base::FilePath(FILE_PATH_LITERAL( "downloads/a_zip_file.zip")))); + base::ThreadRestrictions::ScopedAllowIO allow_io; ASSERT_TRUE(base::PathExists(origin_file)); std::string origin_contents; ASSERT_TRUE(base::ReadFileToString(origin_file, &origin_contents)); @@ -2948,6 +2962,7 @@ (index == 0 ? std::string(".zip") : base::StringPrintf(" (%d).zip", index)), target_path.BaseName().AsUTF8Unsafe()); + base::ThreadRestrictions::ScopedAllowIO allow_io; ASSERT_TRUE(base::PathExists(target_path)); ASSERT_TRUE(VerifyFile(target_path, origin_contents, origin_contents.size())); @@ -2987,6 +3002,7 @@ }; std::vector<DownloadItem*> download_items; + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath origin_directory = GetDownloadDirectory(browser()).Append(FILE_PATH_LITERAL("origin")); ASSERT_TRUE(base::CreateDirectory(origin_directory)); @@ -3084,23 +3100,27 @@ base::FilePath file_path( GetDownloadDirectory(browser()).AppendASCII("source").AppendASCII( "DownloadTest_BigZip.zip")); - ASSERT_TRUE(CreateDirectory(file_path.DirName())); - base::File file(file_path, base::File::FLAG_CREATE | base::File::FLAG_WRITE); - ASSERT_TRUE(file.IsValid()); int64_t size = 1 << 25; - EXPECT_EQ(1, file.Write(size, "a", 1)); - file.Close(); + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + ASSERT_TRUE(CreateDirectory(file_path.DirName())); + base::File file(file_path, + base::File::FLAG_CREATE | base::File::FLAG_WRITE); + ASSERT_TRUE(file.IsValid()); + EXPECT_EQ(1, file.Write(size, "a", 1)); + file.Close(); #if defined(OS_POSIX) - // Make it readable by chronos on chromeos - base::SetPosixFilePermissions(file_path, 0755); + // Make it readable by chronos on chromeos + base::SetPosixFilePermissions(file_path, 0755); #endif - // Ensure that we have enough disk space. - int64_t free_space = - base::SysInfo::AmountOfFreeDiskSpace(GetDownloadDirectory(browser())); - ASSERT_LE(size, free_space) << "Not enough disk space to download. Got " - << free_space; + // Ensure that we have enough disk space. + int64_t free_space = + base::SysInfo::AmountOfFreeDiskSpace(GetDownloadDirectory(browser())); + ASSERT_LE(size, free_space) + << "Not enough disk space to download. Got " << free_space; + } GURL file_url(net::FilePathToFileURL(file_path)); std::unique_ptr<content::DownloadTestObserver> progress_waiter( CreateInProgressWaiter(browser(), 1)); @@ -3124,6 +3144,7 @@ ASSERT_EQ(100, download_items[0]->PercentComplete()); // Check that the file downloaded correctly. + base::ThreadRestrictions::ScopedAllowIO allow_io; ASSERT_TRUE(base::PathExists(download_items[0]->GetTargetFilePath())); int64_t downloaded_size = 0; ASSERT_TRUE(base::GetFileSize( @@ -3534,6 +3555,7 @@ GetDownloads(browser(), &updated_downloads); ASSERT_EQ(std::size_t(1), updated_downloads.size()); ASSERT_FALSE(updated_downloads[0]->IsDangerous()); + base::ThreadRestrictions::ScopedAllowIO allow_io; ASSERT_TRUE(PathExists(updated_downloads[0]->GetTargetFilePath())); updated_downloads[0]->Cancel(true); }
diff --git a/chrome/browser/download/save_page_browsertest.cc b/chrome/browser/download/save_page_browsertest.cc index 3c771b36..9ed8b3a 100644 --- a/chrome/browser/download/save_page_browsertest.cc +++ b/chrome/browser/download/save_page_browsertest.cc
@@ -21,6 +21,7 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/test/test_file_util.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/download/chrome_download_manager_delegate.h" @@ -439,6 +440,7 @@ &full_file_name); ASSERT_FALSE(HasFailure()); + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_TRUE(base::PathExists(full_file_name)); EXPECT_FALSE(base::PathExists(dir)); EXPECT_TRUE(base::ContentsEqual(GetTestDirFile("a.htm"), full_file_name)); @@ -526,6 +528,7 @@ GetCurrentTab(browser())->Close(); EXPECT_EQ(DownloadItem::CANCELLED, items[0]->GetState()); + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_FALSE(base::PathExists(full_file_name)); EXPECT_FALSE(base::PathExists(dir)); } @@ -543,6 +546,7 @@ &dir, &full_file_name); ASSERT_FALSE(HasFailure()); + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_TRUE(base::PathExists(full_file_name)); EXPECT_FALSE(base::PathExists(dir)); EXPECT_TRUE(base::ContentsEqual(GetTestDirFile("a.htm"), full_file_name)); @@ -556,6 +560,7 @@ &full_file_name); ASSERT_FALSE(HasFailure()); + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_TRUE(base::PathExists(full_file_name)); EXPECT_TRUE(base::PathExists(dir)); @@ -631,6 +636,7 @@ ASSERT_TRUE(VerifySavePackageExpectations(browser(), url)); persisted.WaitForPersisted(); + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_TRUE(base::PathExists(full_file_name)); EXPECT_TRUE(base::PathExists(dir)); @@ -659,6 +665,7 @@ downloads[0]->Remove(); removed.WaitForRemoved(); + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_TRUE(base::PathExists(full_file_name)); EXPECT_FALSE(base::PathExists(dir)); EXPECT_TRUE(base::ContentsEqual(GetTestDirFile("a.htm"), full_file_name)); @@ -676,6 +683,7 @@ download_dir.AppendASCII(std::string("test.exe") + kAppendedExtension); base::FilePath dir = download_dir.AppendASCII("test.exe_files"); + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_FALSE(base::PathExists(full_file_name)); GURL url = URLRequestMockHTTPJob::GetMockUrl("save_page/c.htm"); ui_test_utils::NavigateToURL(browser(), url); @@ -732,6 +740,7 @@ ASSERT_TRUE(VerifySavePackageExpectations(browser(), url)); persisted.WaitForPersisted(); + base::ThreadRestrictions::ScopedAllowIO allow_io; ASSERT_TRUE(base::PathExists(full_file_name)); int64_t actual_file_size = -1; EXPECT_TRUE(base::GetFileSize(full_file_name, &actual_file_size)); @@ -757,6 +766,7 @@ base::FilePath download_dir = DownloadPrefs::FromDownloadManager( GetDownloadManager())->DownloadPath(); base::FilePath filename = download_dir.AppendASCII("dataurl.txt"); + base::ThreadRestrictions::ScopedAllowIO allow_io; ASSERT_TRUE(base::PathExists(filename)); std::string contents; EXPECT_TRUE(base::ReadFileToString(filename, &contents)); @@ -776,6 +786,7 @@ "dubious-subresources", 2, &dir, &full_file_name); ASSERT_FALSE(HasFailure()); + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_TRUE(base::PathExists(full_file_name)); EXPECT_TRUE(base::PathExists(dir.AppendASCII("not-a-crx.crx.download"))); } @@ -810,6 +821,7 @@ "iframe-src-is-a-download", 3, &dir, &full_file_name); ASSERT_FALSE(HasFailure()); + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_TRUE(base::PathExists(full_file_name)); EXPECT_TRUE(base::PathExists(dir.AppendASCII("thisdayinhistory.html"))); EXPECT_TRUE(base::PathExists(dir.AppendASCII("no-such-file.html"))); @@ -821,6 +833,7 @@ GURL url = NavigateToMockURL("unauthorized-access"); // Create a test file (that the web page should not have access to). + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temp_dir2; ASSERT_TRUE(temp_dir2.CreateUniqueTempDir()); base::FilePath file_path = @@ -888,6 +901,7 @@ "frames-xsite-complete-html", 5, &dir, &full_file_name); ASSERT_FALSE(HasFailure()); + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_TRUE(base::DirectoryExists(dir)); base::FilePath expected_files[] = { full_file_name, @@ -948,7 +962,10 @@ ASSERT_FALSE(HasFailure()); std::string mhtml; - ASSERT_TRUE(base::ReadFileToString(full_file_name, &mhtml)); + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + ASSERT_TRUE(base::ReadFileToString(full_file_name, &mhtml)); + } // Verify content of main frame, subframes and some savable resources. EXPECT_THAT( @@ -1014,6 +1031,7 @@ SaveCurrentTab(url, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML, "frames-xsite-complete-html", 5, &dir, &full_file_name); ASSERT_FALSE(HasFailure()); + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_TRUE(base::DirectoryExists(dir)); EXPECT_TRUE(base::PathExists(full_file_name)); }
diff --git a/chrome/browser/extensions/api/cast_streaming/cast_streaming_apitest.cc b/chrome/browser/extensions/api/cast_streaming/cast_streaming_apitest.cc index df4109d..22e2284 100644 --- a/chrome/browser/extensions/api/cast_streaming/cast_streaming_apitest.cc +++ b/chrome/browser/extensions/api/cast_streaming/cast_streaming_apitest.cc
@@ -16,6 +16,7 @@ #include "base/run_loop.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" +#include "base/threading/thread_restrictions.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/common/chrome_switches.h" #include "content/public/common/content_switches.h" @@ -388,6 +389,7 @@ receiver->Stop(); delete receiver; + base::ThreadRestrictions::ScopedAllowIO allow_io; cast_environment->Shutdown(); }
diff --git a/chrome/browser/extensions/api/commands/command_service_browsertest.cc b/chrome/browser/extensions/api/commands/command_service_browsertest.cc index 636cffe..cfd932f 100644 --- a/chrome/browser/extensions/api/commands/command_service_browsertest.cc +++ b/chrome/browser/extensions/api/commands/command_service_browsertest.cc
@@ -5,6 +5,7 @@ #include <utility> #include "base/memory/ptr_util.h" +#include "base/threading/thread_restrictions.h" #include "base/values.h" #include "build/build_config.h" #include "chrome/browser/extensions/api/commands/command_service.h" @@ -45,6 +46,7 @@ typedef ExtensionApiTest CommandServiceTest; IN_PROC_BROWSER_TEST_F(CommandServiceTest, RemoveShortcutSurvivesUpdate) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir scoped_temp_dir; EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir()); base::FilePath pem_path = test_data_dir_.
diff --git a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc index 13f90fe..1a4cb535 100644 --- a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc +++ b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
@@ -19,6 +19,7 @@ #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/strings/stringprintf.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/download/download_file_icon_extractor.h" #include "chrome/browser/download/download_service.h" @@ -695,6 +696,7 @@ const storage::FileSystemURL& path, const char* data, int length) { + base::ThreadRestrictions::ScopedAllowIO allow_io; // Create a temp file. base::FilePath temp_file; if (!base::CreateTemporaryFile(&temp_file) || @@ -1050,9 +1052,12 @@ base::FilePath real_path = all_downloads[0]->GetTargetFilePath(); base::FilePath fake_path = all_downloads[1]->GetTargetFilePath(); - EXPECT_EQ(0, base::WriteFile(real_path, "", 0)); - ASSERT_TRUE(base::PathExists(real_path)); - ASSERT_FALSE(base::PathExists(fake_path)); + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + EXPECT_EQ(0, base::WriteFile(real_path, "", 0)); + ASSERT_TRUE(base::PathExists(real_path)); + ASSERT_FALSE(base::PathExists(fake_path)); + } for (DownloadManager::DownloadVector::iterator iter = all_downloads.begin(); iter != all_downloads.end(); @@ -2582,6 +2587,7 @@ " \"previous\": \"in_progress\"," " \"current\": \"complete\"}}]", result_id))); + base::ThreadRestrictions::ScopedAllowIO allow_io; std::string disk_data; EXPECT_TRUE(base::ReadFileToString(item->GetTargetFilePath(), &disk_data)); EXPECT_STREQ(kPayloadData, disk_data.c_str());
diff --git a/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc b/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc index 2d57dda..5250c1e 100644 --- a/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc +++ b/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc
@@ -8,6 +8,7 @@ #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/macros.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" #include "chrome/browser/extensions/browser_action_test_util.h" @@ -71,6 +72,7 @@ std::unique_ptr<base::ScopedTempDir> CreateAndSetDownloadsDirectory( PrefService* pref_service) { + base::ThreadRestrictions::ScopedAllowIO allow_io; std::unique_ptr<base::ScopedTempDir> dir(new base::ScopedTempDir); if (!dir->CreateUniqueTempDir()) @@ -1012,6 +1014,7 @@ // Override the default downloads directory, so that the test can cleanup // after itself. This section is based on CreateAndSetDownloadsDirectory // method defined in a few other source files with tests. + base::ThreadRestrictions::ScopedAllowIO allow_io; std::unique_ptr<base::ScopedTempDir> downloads_directory = CreateAndSetDownloadsDirectory(browser()->profile()->GetPrefs()); ASSERT_TRUE(downloads_directory);
diff --git a/chrome/browser/extensions/api/file_system/file_system_apitest.cc b/chrome/browser/extensions/api/file_system/file_system_apitest.cc index 3a3b841..19dd525 100644 --- a/chrome/browser/extensions/api/file_system/file_system_apitest.cc +++ b/chrome/browser/extensions/api/file_system/file_system_apitest.cc
@@ -7,6 +7,7 @@ #include "base/macros.h" #include "base/path_service.h" #include "base/scoped_observer.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/apps/app_browsertest_util.h" #include "chrome/browser/extensions/api/file_system/file_system_api.h" @@ -85,6 +86,7 @@ protected: base::FilePath TempFilePath(const std::string& destination_name, bool copy_gold) { + base::ThreadRestrictions::ScopedAllowIO allow_io; if (!temp_dir_.CreateUniqueTempDir()) { ADD_FAILURE() << "CreateUniqueTempDir failed"; return base::FilePath(); @@ -104,6 +106,7 @@ std::vector<base::FilePath> TempFilePaths( const std::vector<std::string>& destination_names, bool copy_gold) { + base::ThreadRestrictions::ScopedAllowIO allow_io; if (!temp_dir_.CreateUniqueTempDir()) { ADD_FAILURE() << "CreateUniqueTempDir failed"; return std::vector<base::FilePath>(); @@ -126,6 +129,7 @@ } void CheckStoredDirectoryMatches(const base::FilePath& filename) { + base::ThreadRestrictions::ScopedAllowIO allow_io; const Extension* extension = GetSingleLoadedExtension(); ASSERT_TRUE(extension); std::string extension_id = extension->id(); @@ -154,8 +158,11 @@ #if defined(OS_WIN) || defined(OS_POSIX) IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiGetDisplayPathPrettify) { - ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded(base::DIR_HOME, - test_root_folder_, false, false)); + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded( + base::DIR_HOME, test_root_folder_, false, false)); + } base::FilePath test_file = test_root_folder_.AppendASCII("gold.txt"); FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest( @@ -168,13 +175,17 @@ #if defined(OS_MACOSX) IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiGetDisplayPathPrettifyMac) { - // On Mac, "test.localized" will be localized into just "test". - base::FilePath test_path = TempFilePath("test.localized", false); - ASSERT_TRUE(base::CreateDirectory(test_path)); + base::FilePath test_file; + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + // On Mac, "test.localized" will be localized into just "test". + base::FilePath test_path = TempFilePath("test.localized", false); + ASSERT_TRUE(base::CreateDirectory(test_path)); - base::FilePath test_file = test_path.AppendASCII("gold.txt"); - base::FilePath source = test_root_folder_.AppendASCII("gold.txt"); - EXPECT_TRUE(base::CopyFile(source, test_file)); + test_file = test_path.AppendASCII("gold.txt"); + base::FilePath source = test_root_folder_.AppendASCII("gold.txt"); + EXPECT_TRUE(base::CopyFile(source, test_file)); + } FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest( &test_file); @@ -214,8 +225,11 @@ FileSystemApiOpenExistingFilePreviousPathDoesNotExistTest) { base::FilePath test_file = TempFilePath("open_existing.txt", true); ASSERT_FALSE(test_file.empty()); - ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded( - chrome::DIR_USER_DOCUMENTS, test_file.DirName(), false, false)); + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded( + chrome::DIR_USER_DOCUMENTS, test_file.DirName(), false, false)); + } FileSystemChooseEntryFunction:: SkipPickerAndSelectSuggestedPathForTest(); { @@ -235,8 +249,11 @@ FileSystemApiOpenExistingFileDefaultPathTest) { base::FilePath test_file = TempFilePath("open_existing.txt", true); ASSERT_FALSE(test_file.empty()); - ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded( - chrome::DIR_USER_DOCUMENTS, test_file.DirName(), false, false)); + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded( + chrome::DIR_USER_DOCUMENTS, test_file.DirName(), false, false)); + } FileSystemChooseEntryFunction:: SkipPickerAndSelectSuggestedPathForTest(); ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/open_existing")) @@ -247,8 +264,11 @@ IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiOpenMultipleSuggested) { base::FilePath test_file = TempFilePath("open_existing.txt", true); ASSERT_FALSE(test_file.empty()); - ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded( - chrome::DIR_USER_DOCUMENTS, test_file.DirName(), false, false)); + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded( + chrome::DIR_USER_DOCUMENTS, test_file.DirName(), false, false)); + } FileSystemChooseEntryFunction::SkipPickerAndSelectSuggestedPathForTest(); ASSERT_TRUE(RunPlatformAppTest( "api_test/file_system/open_multiple_with_suggested_name")) @@ -326,8 +346,11 @@ base::FilePath test_file = TempFilePath("open_existing.txt", true); ASSERT_FALSE(test_file.empty()); base::FilePath test_directory = test_file.DirName(); - ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded( - kGraylistedPath, test_directory, false, false)); + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded( + kGraylistedPath, test_directory, false, false)); + } FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest( &test_directory); ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/open_directory")) @@ -341,8 +364,11 @@ base::FilePath test_file = TempFilePath("open_existing.txt", true); ASSERT_FALSE(test_file.empty()); base::FilePath test_directory = test_file.DirName(); - ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded( - kGraylistedPath, test_directory, false, false)); + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded( + kGraylistedPath, test_directory, false, false)); + } FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest( &test_directory); ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/open_directory_cancel")) @@ -357,8 +383,11 @@ ASSERT_FALSE(test_file.empty()); base::FilePath test_directory = test_file.DirName(); base::FilePath parent_directory = test_directory.DirName(); - ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded( - kGraylistedPath, test_directory, false, false)); + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded( + kGraylistedPath, test_directory, false, false)); + } FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest( &parent_directory); ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/open_directory_cancel")) @@ -376,8 +405,11 @@ ASSERT_FALSE(test_file.empty()); base::FilePath test_directory = test_file.DirName(); base::FilePath parent_directory = test_directory.DirName(); - ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded( - kGraylistedPath, parent_directory, false, false)); + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded( + kGraylistedPath, parent_directory, false, false)); + } FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest( &test_directory); ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/open_directory"))
diff --git a/chrome/browser/extensions/api/i18n/i18n_apitest.cc b/chrome/browser/extensions/api/i18n/i18n_apitest.cc index db534d2..0a1735a 100644 --- a/chrome/browser/extensions/api/i18n/i18n_apitest.cc +++ b/chrome/browser/extensions/api/i18n/i18n_apitest.cc
@@ -6,6 +6,7 @@ #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/ui/browser.h" #include "chrome/test/base/ui_test_utils.h" @@ -21,6 +22,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, I18NUpdate) { ASSERT_TRUE(embedded_test_server()->Start()); // Create an Extension whose messages.json file will be updated. + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir extension_dir; ASSERT_TRUE(extension_dir.CreateUniqueTempDir()); base::CopyFile(
diff --git a/chrome/browser/extensions/api/image_writer_private/image_writer_utility_client_browsertest.cc b/chrome/browser/extensions/api/image_writer_private/image_writer_utility_client_browsertest.cc index dd5006a..962a0b2 100644 --- a/chrome/browser/extensions/api/image_writer_private/image_writer_utility_client_browsertest.cc +++ b/chrome/browser/extensions/api/image_writer_private/image_writer_utility_client_browsertest.cc
@@ -12,6 +12,7 @@ #include "base/macros.h" #include "base/run_loop.h" #include "base/task_scheduler/post_task.h" +#include "base/threading/thread_restrictions.h" #include "chrome/common/extensions/removable_storage_writer.mojom.h" #include "chrome/test/base/in_process_browser_test.h" #include "content/public/browser/browser_thread.h" @@ -21,12 +22,14 @@ class ImageWriterUtilityClientTest : public InProcessBrowserTest { public: ImageWriterUtilityClientTest() { + base::ThreadRestrictions::ScopedAllowIO allow_io; test_device_ = base::FilePath().AppendASCII( extensions::mojom::RemovableStorageWriter::kTestDevice); EXPECT_TRUE(temp_dir_.CreateUniqueTempDir()); } void FillImageFileWithPattern(char pattern) { + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &image_)); base::RunLoop run_loop;
diff --git a/chrome/browser/extensions/api/media_galleries/media_galleries_apitest.cc b/chrome/browser/extensions/api/media_galleries/media_galleries_apitest.cc index 2c322b5..c47f6d8 100644 --- a/chrome/browser/extensions/api/media_galleries/media_galleries_apitest.cc +++ b/chrome/browser/extensions/api/media_galleries/media_galleries_apitest.cc
@@ -14,6 +14,7 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/test/test_timeouts.h" +#include "base/threading/thread_restrictions.h" #include "base/values.h" #include "build/build_config.h" #include "chrome/browser/apps/app_browsertest_util.h" @@ -112,6 +113,7 @@ test_data_dir_.AppendASCII(kTestDir + extension_name); from_dir = from_dir.NormalizePathSeparators(); + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temp_dir; if (!temp_dir.CreateUniqueTempDir()) return false; @@ -172,6 +174,7 @@ // with no default media galleries, such as CHROMEOS. This fake gallery is // pre-populated with a test.jpg and test.txt. void MakeSingleFakeGallery(MediaGalleryPrefId* pref_id) { + base::ThreadRestrictions::ScopedAllowIO allow_io; ASSERT_FALSE(fake_gallery_temp_dir_.IsValid()); ASSERT_TRUE(fake_gallery_temp_dir_.CreateUniqueTempDir()); @@ -203,6 +206,7 @@ } void AddFileToSingleFakeGallery(const base::FilePath& source_path) { + base::ThreadRestrictions::ScopedAllowIO allow_io; ASSERT_TRUE(fake_gallery_temp_dir_.IsValid()); ASSERT_TRUE(base::CopyFile( @@ -212,6 +216,7 @@ #if defined(OS_WIN) || defined(OS_MACOSX) void PopulatePicasaTestData(const base::FilePath& picasa_app_data_root) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath picasa_database_path = picasa::MakePicasaDatabasePath(picasa_app_data_root); base::FilePath picasa_temp_dir_path = @@ -431,6 +436,7 @@ IN_PROC_BROWSER_TEST_F(MediaGalleriesPlatformAppBrowserTest, MAYBE_PicasaCustomLocation) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir custom_picasa_app_data_root; ASSERT_TRUE(custom_picasa_app_data_root.CreateUniqueTempDir()); ensure_media_directories_exists()->SetCustomPicasaAppDataPath(
diff --git a/chrome/browser/extensions/api/media_galleries/media_galleries_watch_apitest.cc b/chrome/browser/extensions/api/media_galleries/media_galleries_watch_apitest.cc index 5c0a500..e8e43de0 100644 --- a/chrome/browser/extensions/api/media_galleries/media_galleries_watch_apitest.cc +++ b/chrome/browser/extensions/api/media_galleries/media_galleries_watch_apitest.cc
@@ -10,6 +10,7 @@ #include "base/macros.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/extensions/extension_apitest.h" @@ -109,6 +110,7 @@ } bool AddNewFileInTestGallery() { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath gallery_file = test_gallery_.GetPath().Append(FILE_PATH_LITERAL("test1.txt")); std::string content("new content");
diff --git a/chrome/browser/extensions/api/messaging/native_messaging_test_util.cc b/chrome/browser/extensions/api/messaging/native_messaging_test_util.cc index ebd91a7..3c28d3e 100644 --- a/chrome/browser/extensions/api/messaging/native_messaging_test_util.cc +++ b/chrome/browser/extensions/api/messaging/native_messaging_test_util.cc
@@ -12,6 +12,7 @@ #include "base/path_service.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" #include "base/values.h" #include "build/build_config.h" #include "chrome/common/chrome_paths.h" @@ -68,6 +69,7 @@ ScopedTestNativeMessagingHost::ScopedTestNativeMessagingHost() {} void ScopedTestNativeMessagingHost::RegisterTestHost(bool user_level) { + base::ThreadRestrictions::ScopedAllowIO allow_io; ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); ScopedTestNativeMessagingHost test_host; @@ -99,6 +101,9 @@ test_user_data_dir.AppendASCII("missing_nm_binary.exe"), user_level)); } -ScopedTestNativeMessagingHost::~ScopedTestNativeMessagingHost() {} +ScopedTestNativeMessagingHost::~ScopedTestNativeMessagingHost() { + base::ThreadRestrictions::ScopedAllowIO allow_io; + ignore_result(temp_dir_.Delete()); +} } // namespace extensions
diff --git a/chrome/browser/extensions/api/page_capture/page_capture_apitest.cc b/chrome/browser/extensions/api/page_capture/page_capture_apitest.cc index 3cdf16b..035b462 100644 --- a/chrome/browser/extensions/api/page_capture/page_capture_apitest.cc +++ b/chrome/browser/extensions/api/page_capture/page_capture_apitest.cc
@@ -4,6 +4,7 @@ #include "base/base_switches.h" #include "base/command_line.h" +#include "base/threading/thread_restrictions.h" #include "chrome/browser/extensions/api/page_capture/page_capture_api.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/common/chrome_switches.h" @@ -54,6 +55,7 @@ content::RunAllPendingInMessageLoop(content::BrowserThread::IO); // Make sure the temporary file is destroyed once the javascript side reads // the contents. + base::ThreadRestrictions::ScopedAllowIO allow_io; ASSERT_FALSE(base::PathExists(delegate.temp_file_)); } @@ -73,6 +75,7 @@ ASSERT_FALSE(delegate.temp_file_.empty()); content::RunAllPendingInMessageLoop(content::BrowserThread::FILE); content::RunAllPendingInMessageLoop(content::BrowserThread::IO); + base::ThreadRestrictions::ScopedAllowIO allow_io; ASSERT_FALSE(base::PathExists(delegate.temp_file_)); }
diff --git a/chrome/browser/extensions/api/streams_private/streams_private_apitest.cc b/chrome/browser/extensions/api/streams_private/streams_private_apitest.cc index 1339ae4..9495771 100644 --- a/chrome/browser/extensions/api/streams_private/streams_private_apitest.cc +++ b/chrome/browser/extensions/api/streams_private/streams_private_apitest.cc
@@ -6,6 +6,7 @@ #include "base/command_line.h" #include "base/run_loop.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/download/download_prefs.h" #include "chrome/browser/extensions/extension_apitest.h" @@ -150,6 +151,7 @@ } void InitializeDownloadSettings() { + base::ThreadRestrictions::ScopedAllowIO allow_io; ASSERT_TRUE(browser()); ASSERT_TRUE(downloads_dir_.CreateUniqueTempDir());
diff --git a/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc b/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc index 7ca55aa..9f82d5df 100644 --- a/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc +++ b/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc
@@ -13,6 +13,7 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/browser_process.h" @@ -406,6 +407,7 @@ } IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, Download) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir download_directory; ASSERT_TRUE(download_directory.CreateUniqueTempDir()); DownloadPrefs* download_prefs =
diff --git a/chrome/browser/extensions/api/webrtc_logging_private/webrtc_event_log_apitest.cc b/chrome/browser/extensions/api/webrtc_logging_private/webrtc_event_log_apitest.cc index 1726664..4c040ef0 100644 --- a/chrome/browser/extensions/api/webrtc_logging_private/webrtc_event_log_apitest.cc +++ b/chrome/browser/extensions/api/webrtc_logging_private/webrtc_event_log_apitest.cc
@@ -12,6 +12,7 @@ #include "base/run_loop.h" #include "base/strings/string_number_conversions.h" #include "base/threading/platform_thread.h" +#include "base/threading/thread_restrictions.h" #include "base/time/time.h" #include "build/build_config.h" #include "chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api.h" @@ -65,6 +66,7 @@ : found_(false), path_(path) {} bool Start() { + base::ThreadRestrictions::ScopedAllowIO allow_io; if (base::PathExists(path_)) { found_ = true; return true; @@ -233,6 +235,7 @@ ASSERT_TRUE(waiter->Start()) << "ERROR watching for " << full_file_name.value(); ASSERT_TRUE(waiter->WaitForFile()); + base::ThreadRestrictions::ScopedAllowIO allow_io; ASSERT_TRUE(base::PathExists(full_file_name)); EXPECT_TRUE(base::GetFileSize(full_file_name, &file_size)); EXPECT_GT(file_size, 0); @@ -243,6 +246,7 @@ IN_PROC_BROWSER_TEST_F(WebrtcEventLogApiTest, TestStartTimedWebRtcEventLogging) { + base::ThreadRestrictions::ScopedAllowIO allow_io; ASSERT_TRUE(embedded_test_server()->Start()); content::WebContents* left_tab =
diff --git a/chrome/browser/extensions/api/webstore_private/webstore_private_apitest.cc b/chrome/browser/extensions/api/webstore_private/webstore_private_apitest.cc index 4dd5d71..f2ee8aab 100644 --- a/chrome/browser/extensions/api/webstore_private/webstore_private_apitest.cc +++ b/chrome/browser/extensions/api/webstore_private/webstore_private_apitest.cc
@@ -8,6 +8,7 @@ #include "base/files/file_util.h" #include "base/macros.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/extensions/api/webstore_private/webstore_private_api.h" @@ -218,6 +219,7 @@ // Test having the default download directory missing. IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, MissingDownloadDir) { // Set a non-existent directory as the download path. + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temp_dir; EXPECT_TRUE(temp_dir.CreateUniqueTempDir()); base::FilePath missing_directory = temp_dir.Take();
diff --git a/chrome/browser/extensions/app_background_page_apitest.cc b/chrome/browser/extensions/app_background_page_apitest.cc index ad16e39..b6a70ee 100644 --- a/chrome/browser/extensions/app_background_page_apitest.cc +++ b/chrome/browser/extensions/app_background_page_apitest.cc
@@ -7,6 +7,7 @@ #include "base/single_thread_task_runner.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "chrome/browser/background/background_contents_service.h" @@ -54,6 +55,7 @@ bool CreateApp(const std::string& app_manifest, base::FilePath* app_dir) { + base::ThreadRestrictions::ScopedAllowIO allow_io; if (!app_dir_.CreateUniqueTempDir()) { LOG(ERROR) << "Unable to create a temporary directory."; return false; @@ -129,6 +131,7 @@ protected: void LaunchTestingApp() { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath app_dir; PathService::Get(chrome::DIR_GEN_TEST_DATA, &app_dir); app_dir = app_dir.AppendASCII(
diff --git a/chrome/browser/extensions/app_process_apitest.cc b/chrome/browser/extensions/app_process_apitest.cc index 6abc403f..a08f254 100644 --- a/chrome/browser/extensions/app_process_apitest.cc +++ b/chrome/browser/extensions/app_process_apitest.cc
@@ -304,11 +304,13 @@ // Load an app as a bookmark app. std::string error; - scoped_refptr<const Extension> extension(extensions::file_util::LoadExtension( - test_data_dir_.AppendASCII("app_process"), - extensions::Manifest::UNPACKED, - Extension::FROM_BOOKMARK, - &error)); + scoped_refptr<const Extension> extension; + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + extension = extensions::file_util::LoadExtension( + test_data_dir_.AppendASCII("app_process"), + extensions::Manifest::UNPACKED, Extension::FROM_BOOKMARK, &error); + } service->OnExtensionInstalled(extension.get(), syncer::StringOrdinal::CreateInitialOrdinal(), extensions::kInstallFlagInstallImmediately);
diff --git a/chrome/browser/extensions/content_verifier_browsertest.cc b/chrome/browser/extensions/content_verifier_browsertest.cc index f44c9d2d..63c6b04 100644 --- a/chrome/browser/extensions/content_verifier_browsertest.cc +++ b/chrome/browser/extensions/content_verifier_browsertest.cc
@@ -13,6 +13,7 @@ #include "base/run_loop.h" #include "base/scoped_observer.h" #include "base/strings/string_split.h" +#include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/extensions/browsertest_util.h" #include "chrome/browser/extensions/chrome_content_verifier_delegate.h" @@ -542,7 +543,10 @@ // being what was signed by the webstore. base::FilePath scriptfile = extension->path().AppendASCII(script_relpath); std::string extra = "some_extra_function_call();"; - ASSERT_TRUE(base::AppendToFile(scriptfile, extra.data(), extra.size())); + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + ASSERT_TRUE(base::AppendToFile(scriptfile, extra.data(), extra.size())); + } DisableExtension(id); job_observer.ExpectJobResult(id, script_relfilepath, JobObserver::Result::FAILURE);
diff --git a/chrome/browser/extensions/crx_installer_browsertest.cc b/chrome/browser/extensions/crx_installer_browsertest.cc index af7b9e43..9e32e0d 100644 --- a/chrome/browser/extensions/crx_installer_browsertest.cc +++ b/chrome/browser/extensions/crx_installer_browsertest.cc
@@ -14,6 +14,7 @@ #include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/download/download_crx_util.h" #include "chrome/browser/extensions/browser_action_test_util.h" @@ -214,6 +215,7 @@ bool strict_manifest_checks) { std::unique_ptr<WebstoreInstaller::Approval> result; + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath ext_path = test_data_dir_.AppendASCII(manifest_dir); std::string error; std::unique_ptr<base::DictionaryValue> parsed_manifest( @@ -338,6 +340,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, BlockedFileTypes) { const Extension* extension = InstallExtension(test_data_dir_.AppendASCII("blocked_file_types.crx"), 1); + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_TRUE(base::PathExists(extension->path().AppendASCII("test.html"))); EXPECT_TRUE(base::PathExists(extension->path().AppendASCII("test.nexe"))); EXPECT_FALSE(base::PathExists(extension->path().AppendASCII("test1.EXE"))); @@ -349,6 +352,7 @@ test_data_dir_.AppendASCII("theme_with_extension.crx"), 1); ASSERT_TRUE(extension); const base::FilePath& path = extension->path(); + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_TRUE( base::PathExists(path.AppendASCII("images/theme_frame_camo.PNG"))); EXPECT_TRUE( @@ -599,6 +603,7 @@ crx_path, 1, extensions::Manifest::EXTERNAL_PREF); base::FilePath extension_path = extension->path(); EXPECT_TRUE(cache_dir.GetPath().IsParent(extension_path)); + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_TRUE(base::PathExists(extension_path)); std::string extension_id = extension->id();
diff --git a/chrome/browser/extensions/extension_browsertest.cc b/chrome/browser/extensions/extension_browsertest.cc index 1aa8bd6..b425a443 100644 --- a/chrome/browser/extensions/extension_browsertest.cc +++ b/chrome/browser/extensions/extension_browsertest.cc
@@ -18,6 +18,7 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/task_scheduler/post_task.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/extensions/browsertest_util.h" #include "chrome/browser/extensions/chrome_test_extension_loader.h" @@ -149,6 +150,7 @@ const Extension* ExtensionBrowserTest::GetExtensionByPath( const extensions::ExtensionSet& extensions, const base::FilePath& path) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath extension_path = base::MakeAbsoluteFilePath(path); EXPECT_TRUE(!extension_path.empty()); for (const scoped_refptr<const Extension>& extension : extensions) { @@ -252,6 +254,7 @@ profile())->extension_service(); ExtensionRegistry* registry = ExtensionRegistry::Get(profile()); + base::ThreadRestrictions::ScopedAllowIO allow_io; std::string manifest; if (!base::ReadFileToString(path.Append(manifest_relative_path), &manifest)) { return NULL; @@ -292,6 +295,7 @@ base::FilePath ExtensionBrowserTest::PackExtension( const base::FilePath& dir_path) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath crx_path = temp_dir_.GetPath().AppendASCII("temp.crx"); if (!base::DeleteFile(crx_path, false)) { ADD_FAILURE() << "Failed to delete crx: " << crx_path.value(); @@ -320,6 +324,7 @@ const base::FilePath& crx_path, const base::FilePath& pem_path, const base::FilePath& pem_out_path) { + base::ThreadRestrictions::ScopedAllowIO allow_io; if (!base::PathExists(dir_path)) { ADD_FAILURE() << "Extension dir not found: " << dir_path.value(); return base::FilePath();
diff --git a/chrome/browser/extensions/extension_keybinding_apitest.cc b/chrome/browser/extensions/extension_keybinding_apitest.cc index be19bc2a..b477aad 100644 --- a/chrome/browser/extensions/extension_keybinding_apitest.cc +++ b/chrome/browser/extensions/extension_keybinding_apitest.cc
@@ -4,6 +4,7 @@ #include "base/command_line.h" #include "base/macros.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/extensions/active_tab_permission_granter.h" @@ -558,6 +559,7 @@ } IN_PROC_BROWSER_TEST_F(CommandsApiTest, ShortcutAddedOnUpdate) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir scoped_temp_dir; EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir()); base::FilePath pem_path = test_data_dir_. @@ -603,6 +605,7 @@ } IN_PROC_BROWSER_TEST_F(CommandsApiTest, ShortcutChangedOnUpdate) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir scoped_temp_dir; EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir()); base::FilePath pem_path = test_data_dir_. @@ -651,6 +654,7 @@ } IN_PROC_BROWSER_TEST_F(CommandsApiTest, ShortcutRemovedOnUpdate) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir scoped_temp_dir; EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir()); base::FilePath pem_path = test_data_dir_. @@ -697,6 +701,7 @@ IN_PROC_BROWSER_TEST_F(CommandsApiTest, ShortcutAddedOnUpdateAfterBeingAssignedByUser) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir scoped_temp_dir; EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir()); base::FilePath pem_path = test_data_dir_. @@ -747,6 +752,7 @@ IN_PROC_BROWSER_TEST_F(CommandsApiTest, ShortcutChangedOnUpdateAfterBeingReassignedByUser) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir scoped_temp_dir; EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir()); base::FilePath pem_path = test_data_dir_. @@ -801,6 +807,7 @@ // Test that Media keys do not overwrite previous settings. IN_PROC_BROWSER_TEST_F(CommandsApiTest, MediaKeyShortcutChangedOnUpdateAfterBeingReassignedByUser) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir scoped_temp_dir; EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir()); base::FilePath pem_path = test_data_dir_. @@ -854,6 +861,7 @@ IN_PROC_BROWSER_TEST_F(CommandsApiTest, ShortcutRemovedOnUpdateAfterBeingReassignedByUser) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir scoped_temp_dir; EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir()); base::FilePath pem_path = test_data_dir_.
diff --git a/chrome/browser/extensions/extension_resource_request_policy_apitest.cc b/chrome/browser/extensions/extension_resource_request_policy_apitest.cc index ad316d54..9049e91 100644 --- a/chrome/browser/extensions/extension_resource_request_policy_apitest.cc +++ b/chrome/browser/extensions/extension_resource_request_policy_apitest.cc
@@ -77,9 +77,13 @@ // A data URL. Data URLs should always be able to load chrome-extension:// // resources. std::string file_source; - ASSERT_TRUE(base::ReadFileToString( - test_data_dir_.AppendASCII("extension_resource_request_policy") - .AppendASCII("index.html"), &file_source)); + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + ASSERT_TRUE(base::ReadFileToString( + test_data_dir_.AppendASCII("extension_resource_request_policy") + .AppendASCII("index.html"), + &file_source)); + } ui_test_utils::NavigateToURL(browser(), GURL(std::string("data:text/html;charset=utf-8,") + file_source)); ASSERT_TRUE(content::ExecuteScriptAndExtractString(
diff --git a/chrome/browser/extensions/extension_webui_apitest.cc b/chrome/browser/extensions/extension_webui_apitest.cc index de1a34c7..1fd6e8c 100644 --- a/chrome/browser/extensions/extension_webui_apitest.cc +++ b/chrome/browser/extensions/extension_webui_apitest.cc
@@ -6,6 +6,7 @@ #include "base/files/file_util.h" #include "base/memory/ptr_util.h" #include "base/path_service.h" +#include "base/threading/thread_restrictions.h" #include "base/values.h" #include "build/build_config.h" #include "chrome/browser/extensions/extension_apitest.h" @@ -35,18 +36,21 @@ const GURL& page_url, const GURL& frame_url, bool expected_result) { - // Tests are located in chrome/test/data/extensions/webui/$(name). - base::FilePath path; - PathService::Get(chrome::DIR_TEST_DATA, &path); - path = - path.AppendASCII("extensions").AppendASCII("webui").AppendASCII(name); - - // Read the test. - if (!base::PathExists(path)) - return testing::AssertionFailure() << "Couldn't find " << path.value(); std::string script; - base::ReadFileToString(path, &script); - script = "(function(){'use strict';" + script + "}());"; + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + // Tests are located in chrome/test/data/extensions/webui/$(name). + base::FilePath path; + PathService::Get(chrome::DIR_TEST_DATA, &path); + path = + path.AppendASCII("extensions").AppendASCII("webui").AppendASCII(name); + + // Read the test. + if (!base::PathExists(path)) + return testing::AssertionFailure() << "Couldn't find " << path.value(); + base::ReadFileToString(path, &script); + script = "(function(){'use strict';" + script + "}());"; + } // Run the test. bool actual_result = false;
diff --git a/chrome/browser/extensions/lazy_background_page_apitest.cc b/chrome/browser/extensions/lazy_background_page_apitest.cc index 5b0696b9..ead2b67 100644 --- a/chrome/browser/extensions/lazy_background_page_apitest.cc +++ b/chrome/browser/extensions/lazy_background_page_apitest.cc
@@ -10,6 +10,7 @@ #include "base/path_service.h" #include "base/scoped_observer.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/bookmarks/bookmark_model_factory.h" #include "chrome/browser/extensions/browser_action_test_util.h" @@ -318,6 +319,7 @@ IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, NaClInBackgroundPage) { { base::FilePath extdir; + base::ThreadRestrictions::ScopedAllowIO allow_io; ASSERT_TRUE(PathService::Get(chrome::DIR_GEN_TEST_DATA, &extdir)); extdir = extdir.AppendASCII("ppapi/tests/extensions/load_unload/newlib"); LazyBackgroundObserver page_complete; @@ -354,6 +356,7 @@ // page, and the Lazy Background Page stays alive. { base::FilePath extdir; + base::ThreadRestrictions::ScopedAllowIO allow_io; ASSERT_TRUE(PathService::Get(chrome::DIR_GEN_TEST_DATA, &extdir)); extdir = extdir.AppendASCII("ppapi/tests/extensions/popup/newlib"); ResultCatcher catcher;
diff --git a/chrome/browser/extensions/service_worker_apitest.cc b/chrome/browser/extensions/service_worker_apitest.cc index 80336cee..9d2dd5de 100644 --- a/chrome/browser/extensions/service_worker_apitest.cc +++ b/chrome/browser/extensions/service_worker_apitest.cc
@@ -8,6 +8,7 @@ #include "base/macros.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/gcm/fake_gcm_profile_service.h" @@ -283,6 +284,7 @@ } IN_PROC_BROWSER_TEST_F(ServiceWorkerTest, UpdateRefreshesServiceWorker) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir scoped_temp_dir; ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir()); base::FilePath pem_path = test_data_dir_.AppendASCII("service_worker") @@ -323,6 +325,7 @@ } IN_PROC_BROWSER_TEST_F(ServiceWorkerTest, UpdateWithoutSkipWaiting) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir scoped_temp_dir; ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir()); base::FilePath pem_path = test_data_dir_.AppendASCII("service_worker")
diff --git a/chrome/browser/extensions/startup_helper_browsertest.cc b/chrome/browser/extensions/startup_helper_browsertest.cc index f69701b..36fcc36 100644 --- a/chrome/browser/extensions/startup_helper_browsertest.cc +++ b/chrome/browser/extensions/startup_helper_browsertest.cc
@@ -7,6 +7,7 @@ #include "base/command_line.h" #include "base/files/file_path.h" #include "base/path_service.h" +#include "base/threading/thread_restrictions.h" #include "chrome/browser/extensions/startup_helper.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" @@ -49,6 +50,7 @@ std::string error; extensions::StartupHelper helper; + base::ThreadRestrictions::ScopedAllowIO allow_io; bool result = helper.ValidateCrx(command_line, &error); if (i->second) { EXPECT_TRUE(result) << path.LossyDisplayName()
diff --git a/chrome/browser/extensions/test_extension_dir.cc b/chrome/browser/extensions/test_extension_dir.cc index a279182..daf2c76 100644 --- a/chrome/browser/extensions/test_extension_dir.cc +++ b/chrome/browser/extensions/test_extension_dir.cc
@@ -9,17 +9,22 @@ #include "base/numerics/safe_conversions.h" #include "base/strings/string_util.h" #include "base/test/values_test_util.h" +#include "base/threading/thread_restrictions.h" #include "chrome/browser/extensions/extension_creator.h" #include "testing/gtest/include/gtest/gtest.h" namespace extensions { TestExtensionDir::TestExtensionDir() { + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_TRUE(dir_.CreateUniqueTempDir()); EXPECT_TRUE(crx_dir_.CreateUniqueTempDir()); } TestExtensionDir::~TestExtensionDir() { + base::ThreadRestrictions::ScopedAllowIO allow_io; + ignore_result(dir_.Delete()); + ignore_result(crx_dir_.Delete()); } void TestExtensionDir::WriteManifest(base::StringPiece manifest) { @@ -35,6 +40,7 @@ void TestExtensionDir::WriteFile(const base::FilePath::StringType& filename, base::StringPiece contents) { + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_EQ(base::checked_cast<int>(contents.size()), base::WriteFile(dir_.GetPath().Append(filename), contents.data(), contents.size())); @@ -43,6 +49,7 @@ // This function packs the extension into a .crx, and returns the path to that // .crx. Multiple calls to Pack() will produce extensions with the same ID. base::FilePath TestExtensionDir::Pack() { + base::ThreadRestrictions::ScopedAllowIO allow_io; ExtensionCreator creator; base::FilePath crx_path = crx_dir_.GetPath().Append(FILE_PATH_LITERAL("ext.crx")); @@ -67,6 +74,7 @@ } base::FilePath TestExtensionDir::UnpackedPath() { + base::ThreadRestrictions::ScopedAllowIO allow_io; // We make this absolute because it's possible that dir_ contains a symlink as // part of it's path. When UnpackedInstaller::GetAbsolutePath() runs as part // of loading the extension, the extension's path is converted to an absolute
diff --git a/chrome/browser/history/redirect_browsertest.cc b/chrome/browser/history/redirect_browsertest.cc index 781bee29..ba0e687 100644 --- a/chrome/browser/history/redirect_browsertest.cc +++ b/chrome/browser/history/redirect_browsertest.cc
@@ -21,6 +21,7 @@ #include "base/task/cancelable_task_tracker.h" #include "base/test/test_timeouts.h" #include "base/threading/platform_thread.h" +#include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/profiles/profile.h" @@ -133,6 +134,7 @@ final_url.spec().c_str()); // Write the contents to a temporary file. + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temp_directory; ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); base::FilePath temp_file;
diff --git a/chrome/browser/importer/edge_importer_browsertest_win.cc b/chrome/browser/importer/edge_importer_browsertest_win.cc index 1f7bcac..65b7d90 100644 --- a/chrome/browser/importer/edge_importer_browsertest_win.cc +++ b/chrome/browser/importer/edge_importer_browsertest_win.cc
@@ -203,8 +203,11 @@ data_path = data_path.AppendASCII("edge_profile"); base::FilePath temp_path = temp_dir_.GetPath(); - ASSERT_TRUE(base::CopyDirectory(data_path, temp_path, true)); - ASSERT_TRUE(DecompressDatabase(temp_path.AppendASCII("edge_profile"))); + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + ASSERT_TRUE(base::CopyDirectory(data_path, temp_path, true)); + ASSERT_TRUE(DecompressDatabase(temp_path.AppendASCII("edge_profile"))); + } base::string16 key_path(importer::GetEdgeSettingsKey()); base::win::RegKey key; @@ -243,8 +246,11 @@ ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_path)); data_path = data_path.AppendASCII("edge_profile"); - ASSERT_TRUE(base::CopyDirectory(data_path, temp_dir_.GetPath(), true)); - ASSERT_TRUE(importer::IsEdgeFavoritesLegacyMode()); + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + ASSERT_TRUE(base::CopyDirectory(data_path, temp_dir_.GetPath(), true)); + ASSERT_TRUE(importer::IsEdgeFavoritesLegacyMode()); + } // Starts to import the above settings. // Deletes itself. @@ -256,10 +262,13 @@ importer::SourceProfile source_profile; source_profile.importer_type = importer::TYPE_EDGE; base::FilePath source_path = temp_dir_.GetPath().AppendASCII("edge_profile"); - ASSERT_NE(-1, - base::WriteFile( + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + ASSERT_NE( + -1, base::WriteFile( source_path.AppendASCII("Favorites\\Google.url:favicon:$DATA"), kDummyFaviconImageData, sizeof(kDummyFaviconImageData))); + } source_profile.source_path = source_path; host->StartImportSettings(source_profile, browser()->profile(),
diff --git a/chrome/browser/importer/ie_importer_browsertest_win.cc b/chrome/browser/importer/ie_importer_browsertest_win.cc index e306a43..ed6974f7 100644 --- a/chrome/browser/importer/ie_importer_browsertest_win.cc +++ b/chrome/browser/importer/ie_importer_browsertest_win.cc
@@ -27,6 +27,7 @@ #include "base/strings/string16.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" #include "base/win/registry.h" #include "base/win/scoped_comptr.h" #include "base/win/scoped_propvariant.h" @@ -435,6 +436,7 @@ }; IN_PROC_BROWSER_TEST_F(IEImporterBrowserTest, IEImporter) { + base::ThreadRestrictions::ScopedAllowIO allow_io; // Sets up a favorites folder. base::FilePath path = temp_dir_.GetPath().AppendASCII("Favorites"); CreateDirectory(path.value().c_str(), NULL);
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc index 3afae54..4e730e6c 100644 --- a/chrome/browser/io_thread.cc +++ b/chrome/browser/io_thread.cc
@@ -26,7 +26,7 @@ #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" -#include "base/threading/sequenced_worker_pool.h" +#include "base/task_scheduler/post_task.h" #include "base/threading/thread.h" #include "base/time/time.h" #include "base/trace_event/trace_event.h" @@ -1080,9 +1080,12 @@ job_factory->SetProtocolHandler( url::kFileScheme, base::MakeUnique<net::FileProtocolHandler>( - content::BrowserThread::GetBlockingPool() - ->GetTaskRunnerWithShutdownBehavior( - base::SequencedWorkerPool::SKIP_ON_SHUTDOWN))); + base::CreateTaskRunnerWithTraits( + base::TaskTraits() + .MayBlock() + .WithPriority(base::TaskPriority::USER_VISIBLE) + .WithShutdownBehavior( + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN)))); #if !BUILDFLAG(DISABLE_FTP_SUPPORT) job_factory->SetProtocolHandler( url::kFtpScheme,
diff --git a/chrome/browser/lifetime/browser_close_manager_browsertest.cc b/chrome/browser/lifetime/browser_close_manager_browsertest.cc index f711acc05..c25223d 100644 --- a/chrome/browser/lifetime/browser_close_manager_browsertest.cc +++ b/chrome/browser/lifetime/browser_close_manager_browsertest.cc
@@ -10,6 +10,7 @@ #include "base/command_line.h" #include "base/files/scoped_temp_dir.h" #include "base/macros.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/background/background_mode_manager.h" #include "chrome/browser/browser_process.h" @@ -1163,12 +1164,16 @@ IN_PROC_BROWSER_TEST_P(BrowserCloseManagerWithDownloadsBrowserTest, TestWithDownloadsFromDifferentProfiles) { ProfileManager* profile_manager = g_browser_process->profile_manager(); - base::FilePath path = - profile_manager->user_data_dir().AppendASCII("test_profile"); - if (!base::PathExists(path)) - ASSERT_TRUE(base::CreateDirectory(path)); - Profile* other_profile = - Profile::CreateProfile(path, NULL, Profile::CREATE_MODE_SYNCHRONOUS); + Profile* other_profile = nullptr; + { + base::FilePath path = + profile_manager->user_data_dir().AppendASCII("test_profile"); + base::ThreadRestrictions::ScopedAllowIO allow_io; + if (!base::PathExists(path)) + ASSERT_TRUE(base::CreateDirectory(path)); + other_profile = + Profile::CreateProfile(path, NULL, Profile::CREATE_MODE_SYNCHRONOUS); + } profile_manager->RegisterTestingProfile(other_profile, true, false); Browser* other_profile_browser = CreateBrowser(other_profile);
diff --git a/chrome/browser/media_galleries/fileapi/iapps_finder_impl_win_browsertest.cc b/chrome/browser/media_galleries/fileapi/iapps_finder_impl_win_browsertest.cc index f2ca11d1..6d04416 100644 --- a/chrome/browser/media_galleries/fileapi/iapps_finder_impl_win_browsertest.cc +++ b/chrome/browser/media_galleries/fileapi/iapps_finder_impl_win_browsertest.cc
@@ -17,6 +17,7 @@ #include "base/run_loop.h" #include "base/strings/stringprintf.h" #include "base/test/scoped_path_override.h" +#include "base/threading/thread_restrictions.h" #include "chrome/common/chrome_paths.h" #include "chrome/test/base/in_process_browser_test.h" @@ -33,6 +34,7 @@ } void TouchFile(const base::FilePath& file) { + base::ThreadRestrictions::ScopedAllowIO allow_io; ASSERT_EQ(1, base::WriteFile(file, " ", 1)); } @@ -57,6 +59,7 @@ const base::FilePath& music_dir() { return music_dir_.GetPath(); } void WritePrefFile(const std::string& data) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath pref_dir = app_data_dir().AppendASCII("Apple Computer").AppendASCII("iTunes"); ASSERT_TRUE(base::CreateDirectory(pref_dir)); @@ -66,12 +69,14 @@ } void TouchDefault() { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath default_dir = music_dir().AppendASCII("iTunes"); ASSERT_TRUE(base::CreateDirectory(default_dir)); TouchFile(default_dir.AppendASCII("iTunes Music Library.xml")); } void TestFindITunesLibrary() { + base::ThreadRestrictions::ScopedAllowIO allow_io; test_finder_callback_called_ = false; result_.clear(); base::RunLoop loop;
diff --git a/chrome/browser/media_galleries/media_galleries_test_util.cc b/chrome/browser/media_galleries/media_galleries_test_util.cc index 437e897..a7da77f 100644 --- a/chrome/browser/media_galleries/media_galleries_test_util.cc +++ b/chrome/browser/media_galleries/media_galleries_test_util.cc
@@ -13,6 +13,7 @@ #include "base/files/file_util.h" #include "base/path_service.h" #include "base/strings/string_number_conversions.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/media_galleries/fileapi/picasa_finder.h" @@ -96,6 +97,8 @@ iapps::SetMacPreferencesForTesting(NULL); picasa::SetMacPreferencesForTesting(NULL); #endif // OS_MACOSX + base::ThreadRestrictions::ScopedAllowIO allow_io; + ignore_result(fake_dir_.Delete()); } void EnsureMediaDirectoriesExists::ChangeMediaPathOverrides() { @@ -131,6 +134,7 @@ } base::FilePath EnsureMediaDirectoriesExists::GetFakeAppDataPath() const { + base::ThreadRestrictions::ScopedAllowIO allow_io; DCHECK(fake_dir_.IsValid()); return fake_dir_.GetPath().AppendASCII("appdata"); }
diff --git a/chrome/browser/nacl_host/test/nacl_gdb_browsertest.cc b/chrome/browser/nacl_host/test/nacl_gdb_browsertest.cc index 199e51667..1153f7c 100644 --- a/chrome/browser/nacl_host/test/nacl_gdb_browsertest.cc +++ b/chrome/browser/nacl_host/test/nacl_gdb_browsertest.cc
@@ -8,6 +8,7 @@ #include "base/environment.h" #include "base/files/file_util.h" #include "base/path_service.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/common/chrome_switches.h" #include "chrome/test/ppapi/ppapi_test.h" @@ -56,6 +57,7 @@ return; } #endif + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_TRUE(base::CreateTemporaryFile(&mock_nacl_gdb_file)); env->SetVar("MOCK_NACL_GDB", mock_nacl_gdb_file.AsUTF8Unsafe()); RunTestViaHTTP(test_name);
diff --git a/chrome/browser/net/errorpage_browsertest.cc b/chrome/browser/net/errorpage_browsertest.cc index ec51d3b..dfd12f39 100644 --- a/chrome/browser/net/errorpage_browsertest.cc +++ b/chrome/browser/net/errorpage_browsertest.cc
@@ -17,11 +17,12 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/synchronization/lock.h" +#include "base/task_scheduler/post_task.h" #include "base/threading/sequenced_worker_pool.h" +#include "base/threading/thread_restrictions.h" #include "base/values.h" #include "build/build_config.h" #include "chrome/browser/browsing_data/browsing_data_helper.h" - #include "chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h" #include "chrome/browser/net/net_error_diagnostics_dialog.h" #include "chrome/browser/net/url_request_mock_util.h" @@ -247,11 +248,14 @@ base::FilePath root_http; PathService::Get(chrome::DIR_TEST_DATA, &root_http); return new net::URLRequestMockHTTPJob( - request, - network_delegate, + request, network_delegate, root_http.AppendASCII("mock-link-doctor.json"), - BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior( - base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)); + base::CreateTaskRunnerWithTraits( + base::TaskTraits() + .MayBlock() + .WithPriority(base::TaskPriority::BACKGROUND) + .WithShutdownBehavior( + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN))); } void WaitForRequests(int requests_to_wait_for) { @@ -541,6 +545,7 @@ // button to launch a network diagnostics tool. IN_PROC_BROWSER_TEST_F(ErrorPageTest, FileNotFound) { // Create an empty temp directory, to be sure there's no file in it. + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); GURL non_existent_file_url =
diff --git a/chrome/browser/net/file_downloader.cc b/chrome/browser/net/file_downloader.cc index ffbb4f9..f8f3f792 100644 --- a/chrome/browser/net/file_downloader.cc +++ b/chrome/browser/net/file_downloader.cc
@@ -8,7 +8,7 @@ #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/logging.h" -#include "base/threading/sequenced_worker_pool.h" +#include "base/task_scheduler/post_task.h" #include "content/public/browser/browser_thread.h" #include "net/base/load_flags.h" #include "net/http/http_status_code.h" @@ -43,9 +43,12 @@ fetcher_->Start(); } else { base::PostTaskAndReplyWithResult( - BrowserThread::GetBlockingPool() - ->GetTaskRunnerWithShutdownBehavior( - base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN) + base::CreateTaskRunnerWithTraits( + base::TaskTraits() + .MayBlock() + .WithPriority(base::TaskPriority::BACKGROUND) + .WithShutdownBehavior( + base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)) .get(), FROM_HERE, base::Bind(&base::PathExists, local_path_), base::Bind(&FileDownloader::OnFileExistsCheckDone, @@ -82,9 +85,12 @@ } base::PostTaskAndReplyWithResult( - BrowserThread::GetBlockingPool() - ->GetTaskRunnerWithShutdownBehavior( - base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN) + base::CreateTaskRunnerWithTraits( + base::TaskTraits() + .MayBlock() + .WithPriority(base::TaskPriority::BACKGROUND) + .WithShutdownBehavior( + base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)) .get(), FROM_HERE, base::Bind(&base::Move, response_path, local_path_), base::Bind(&FileDownloader::OnFileMoveDone,
diff --git a/chrome/browser/net/file_downloader_unittest.cc b/chrome/browser/net/file_downloader_unittest.cc index c34763a..79fa18a4 100644 --- a/chrome/browser/net/file_downloader_unittest.cc +++ b/chrome/browser/net/file_downloader_unittest.cc
@@ -7,11 +7,9 @@ #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "base/threading/sequenced_worker_pool.h" +#include "base/test/scoped_task_environment.h" #include "base/threading/thread_task_runner_handle.h" -#include "content/public/browser/browser_thread.h" +#include "content/public/test/test_utils.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/test_url_fetcher_factory.h" #include "net/url_request/url_request_test_util.h" @@ -68,20 +66,14 @@ TRAFFIC_ANNOTATION_FOR_TESTS); EXPECT_CALL(*this, OnDownloadFinished(expected_result)); // Wait for the FileExists check to happen if necessary. - if (!overwrite) - content::BrowserThread::GetBlockingPool()->FlushForTesting(); - // Wait for the actual download to happen. - base::RunLoop().RunUntilIdle(); - // Wait for the FileMove to happen. - content::BrowserThread::GetBlockingPool()->FlushForTesting(); - base::RunLoop().RunUntilIdle(); + content::RunAllBlockingPoolTasksUntilIdle(); } private: base::ScopedTempDir dir_; base::FilePath path_; - base::MessageLoop message_loop_; + base::test::ScopedTaskEnvironment scoped_task_environment_; scoped_refptr<net::TestURLRequestContextGetter> request_context_; net::FakeURLFetcherFactory url_fetcher_factory_; };
diff --git a/chrome/browser/notifications/message_center_settings_controller.cc b/chrome/browser/notifications/message_center_settings_controller.cc index ec12eae..d337df99 100644 --- a/chrome/browser/notifications/message_center_settings_controller.cc +++ b/chrome/browser/notifications/message_center_settings_controller.cc
@@ -11,6 +11,7 @@ #include "base/command_line.h" #include "base/i18n/string_compare.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" @@ -335,6 +336,7 @@ #if defined(OS_CHROMEOS) void MessageCenterSettingsController::CreateNotifierGroupForGuestLogin() { + base::ThreadRestrictions::ScopedAllowIO allow_io; // Already created. if (!notifier_groups_.empty()) return;
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc index 8d69c71..f7fc55f 100644 --- a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc +++ b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
@@ -5,6 +5,7 @@ #include "base/files/scoped_temp_dir.h" #include "base/macros.h" #include "base/test/histogram_tester.h" +#include "base/threading/thread_restrictions.h" #include "base/time/time.h" #include "chrome/browser/page_load_metrics/metrics_web_contents_observer.h" #include "chrome/browser/page_load_metrics/observers/aborts_page_load_metrics_observer.h" @@ -319,6 +320,7 @@ IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, IgnoreDownloads) { ASSERT_TRUE(embedded_test_server()->Start()); + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir downloads_directory; ASSERT_TRUE(downloads_directory.CreateUniqueTempDir()); browser()->profile()->GetPrefs()->SetFilePath(
diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc index ac6d9bf..2034ad38 100644 --- a/chrome/browser/password_manager/password_manager_browsertest.cc +++ b/chrome/browser/password_manager/password_manager_browsertest.cc
@@ -17,6 +17,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/histogram_tester.h" #include "base/test/scoped_feature_list.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/password_manager/chrome_password_manager_client.h" @@ -95,6 +96,7 @@ }; GURL GetFileURL(const char* filename) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath path; PathService::Get(chrome::DIR_TEST_DATA, &path); path = path.AppendASCII("password").AppendASCII(filename);
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc index 2a72ae44..0885bdca 100644 --- a/chrome/browser/pdf/pdf_extension_test.cc +++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -16,6 +16,7 @@ #include "base/path_service.h" #include "base/strings/pattern.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/extensions/component_loader.h" @@ -141,19 +142,23 @@ // loaded before continuing. WebContents* guest_contents = LoadPdfGetGuestContents(url); ASSERT_TRUE(guest_contents); - - base::FilePath test_data_dir; - PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir); - test_data_dir = test_data_dir.Append(FILE_PATH_LITERAL("pdf")); - base::FilePath test_util_path = test_data_dir.AppendASCII("test_util.js"); std::string test_util_js; - ASSERT_TRUE(base::ReadFileToString(test_util_path, &test_util_js)); - base::FilePath test_file_path = test_data_dir.AppendASCII(filename); - std::string test_js; - ASSERT_TRUE(base::ReadFileToString(test_file_path, &test_js)); + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + base::FilePath test_data_dir; + PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir); + test_data_dir = test_data_dir.Append(FILE_PATH_LITERAL("pdf")); + base::FilePath test_util_path = test_data_dir.AppendASCII("test_util.js"); + ASSERT_TRUE(base::ReadFileToString(test_util_path, &test_util_js)); - test_util_js.append(test_js); + base::FilePath test_file_path = test_data_dir.AppendASCII(filename); + std::string test_js; + ASSERT_TRUE(base::ReadFileToString(test_file_path, &test_js)); + + test_util_js.append(test_js); + } + ASSERT_TRUE(content::ExecuteScript(guest_contents, test_util_js)); if (!catcher.GetNextResult()) @@ -188,6 +193,7 @@ // the test if base::Hash(filename) mod kNumberLoadTestParts == k in order // to shard the files evenly across values of k in [0, kNumberLoadTestParts). void LoadAllPdfsTest(const std::string& dir_name, int k) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath test_data_dir; ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir)); base::FileEnumerator file_enumerator(test_data_dir.AppendASCII(dir_name), @@ -472,12 +478,16 @@ // This test ensures that PDF can be loaded from local file IN_PROC_BROWSER_TEST_F(PDFExtensionTest, EnsurePDFFromLocalFileLoads) { - base::FilePath test_data_dir; - ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir)); - test_data_dir = test_data_dir.Append(FILE_PATH_LITERAL("pdf")); - base::FilePath test_data_file = test_data_dir.AppendASCII("test.pdf"); - ASSERT_TRUE(PathExists(test_data_file)); - GURL test_pdf_url("file://" + test_data_file.MaybeAsASCII()); + GURL test_pdf_url; + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + base::FilePath test_data_dir; + ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir)); + test_data_dir = test_data_dir.Append(FILE_PATH_LITERAL("pdf")); + base::FilePath test_data_file = test_data_dir.AppendASCII("test.pdf"); + ASSERT_TRUE(PathExists(test_data_file)); + test_pdf_url = GURL("file://" + test_data_file.MaybeAsASCII()); + } WebContents* guest_contents = LoadPdfGetGuestContents(test_pdf_url); ASSERT_TRUE(guest_contents); }
diff --git a/chrome/browser/plugins/plugin_power_saver_browsertest.cc b/chrome/browser/plugins/plugin_power_saver_browsertest.cc index c0b1a0c..b8ad00c 100644 --- a/chrome/browser/plugins/plugin_power_saver_browsertest.cc +++ b/chrome/browser/plugins/plugin_power_saver_browsertest.cc
@@ -11,6 +11,7 @@ #include "base/strings/string_piece.h" #include "base/strings/stringprintf.h" #include "base/test/scoped_feature_list.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/ui/browser.h" @@ -220,6 +221,7 @@ const base::Closure& done_cb, const SkBitmap& bitmap, content::ReadbackResponse response) { + base::ThreadRestrictions::ScopedAllowIO allow_io; DCHECK(snapshot_matches); ASSERT_EQ(content::READBACK_SUCCESS, response);
diff --git a/chrome/browser/policy/cloud/cloud_policy_browsertest.cc b/chrome/browser/policy/cloud/cloud_policy_browsertest.cc index 04705a3..65247d7b 100644 --- a/chrome/browser/policy/cloud/cloud_policy_browsertest.cc +++ b/chrome/browser/policy/cloud/cloud_policy_browsertest.cc
@@ -14,6 +14,7 @@ #include "base/path_service.h" #include "base/run_loop.h" #include "base/strings/stringprintf.h" +#include "base/threading/thread_restrictions.h" #include "base/time/time.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" @@ -282,6 +283,7 @@ } void SetServerPolicy(const std::string& policy) { + base::ThreadRestrictions::ScopedAllowIO allow_io; int result = base::WriteFile(policy_file_path(), policy.data(), policy.size()); ASSERT_EQ(base::checked_cast<int>(policy.size()), result);
diff --git a/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc b/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc index 327b14b..70b55ab 100644 --- a/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc +++ b/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc
@@ -11,6 +11,7 @@ #include "base/memory/ref_counted.h" #include "base/path_service.h" #include "base/run_loop.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/extensions/extension_browsertest.h" @@ -316,6 +317,7 @@ base::Base64UrlEncode( kTestExtension, base::Base64UrlEncodePolicy::INCLUDE_PADDING, &cache_subkey); + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath cache_path = browser()->profile()->GetPath() .Append(FILE_PATH_LITERAL("Policy")) .Append(FILE_PATH_LITERAL("Components"))
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc index a6c6d0fe..134d49d0 100644 --- a/chrome/browser/policy/policy_browsertest.cc +++ b/chrome/browser/policy/policy_browsertest.cc
@@ -34,6 +34,7 @@ #include "base/test/scoped_feature_list.h" #include "base/test/test_file_util.h" #include "base/threading/sequenced_worker_pool.h" +#include "base/threading/thread_restrictions.h" #include "base/time/time.h" #include "base/values.h" #include "build/build_config.h" @@ -876,6 +877,7 @@ EXPECT_EQ(french_title, title); // Make sure this is really French and differs from the English title. + base::ThreadRestrictions::ScopedAllowIO allow_io; std::string loaded = ui::ResourceBundle::GetSharedInstance().ReloadLocaleResources("en-US"); EXPECT_EQ("en-US", loaded); @@ -1436,6 +1438,7 @@ // Verifies that the download directory can be forced by policy. // Set the initial download directory. + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir initial_dir; ASSERT_TRUE(initial_dir.CreateUniqueTempDir()); browser()->profile()->GetPrefs()->SetFilePath( @@ -1834,6 +1837,7 @@ URLRequestMockHTTPJob::GetMockUrl("extensions/*")); const GURL referrer_url(URLRequestMockHTTPJob::GetMockUrl("policy/*")); + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir download_directory; ASSERT_TRUE(download_directory.CreateUniqueTempDir()); DownloadPrefs* download_prefs =
diff --git a/chrome/browser/policy/policy_prefs_browsertest.cc b/chrome/browser/policy/policy_prefs_browsertest.cc index 7517b24..d7f2b93 100644 --- a/chrome/browser/policy/policy_prefs_browsertest.cc +++ b/chrome/browser/policy/policy_prefs_browsertest.cc
@@ -24,6 +24,7 @@ #include "base/stl_util.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" #include "base/values.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" @@ -232,6 +233,7 @@ typedef PolicyTestCaseMap::const_iterator iterator; PolicyTestCases() { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath path = ui_test_utils::GetTestFilePath( base::FilePath(FILE_PATH_LITERAL("policy")), base::FilePath(FILE_PATH_LITERAL("policy_test_cases.json")));
diff --git a/chrome/browser/policy/test/local_policy_test_server.cc b/chrome/browser/policy/test/local_policy_test_server.cc index 0f9a9d9a4..731588ba 100644 --- a/chrome/browser/policy/test/local_policy_test_server.cc +++ b/chrome/browser/policy/test/local_policy_test_server.cc
@@ -17,6 +17,7 @@ #include "base/numerics/safe_conversions.h" #include "base/path_service.h" #include "base/strings/stringprintf.h" +#include "base/threading/thread_restrictions.h" #include "base/values.h" #include "build/build_config.h" #include "components/policy/core/common/cloud/cloud_policy_constants.h" @@ -63,6 +64,7 @@ : net::LocalTestServer(net::BaseTestServer::TYPE_HTTP, net::BaseTestServer::kLocalhost, base::FilePath()) { + base::ThreadRestrictions::ScopedAllowIO allow_io; CHECK(server_data_dir_.CreateUniqueTempDir()); config_file_ = server_data_dir_.GetPath().Append(kPolicyFileName); } @@ -78,6 +80,7 @@ net::BaseTestServer::kLocalhost, base::FilePath()) { // Read configuration from a file in chrome/test/data/policy. + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath source_root; CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &source_root)); config_file_ = source_root @@ -92,6 +95,7 @@ bool LocalPolicyTestServer::SetSigningKeyAndSignature( const crypto::RSAPrivateKey* key, const std::string& signature) { + base::ThreadRestrictions::ScopedAllowIO allow_io; CHECK(server_data_dir_.IsValid()); std::vector<uint8_t> signing_key_bits; @@ -147,6 +151,7 @@ bool LocalPolicyTestServer::UpdatePolicy(const std::string& type, const std::string& entity_id, const std::string& policy) { + base::ThreadRestrictions::ScopedAllowIO allow_io; CHECK(server_data_dir_.IsValid()); std::string selector = GetSelector(type, entity_id); @@ -160,6 +165,7 @@ bool LocalPolicyTestServer::UpdatePolicyData(const std::string& type, const std::string& entity_id, const std::string& data) { + base::ThreadRestrictions::ScopedAllowIO allow_io; CHECK(server_data_dir_.IsValid()); std::string selector = GetSelector(type, entity_id); @@ -175,6 +181,7 @@ } bool LocalPolicyTestServer::SetPythonPath() const { + base::ThreadRestrictions::ScopedAllowIO allow_io; if (!net::LocalTestServer::SetPythonPath()) return false; @@ -222,6 +229,7 @@ bool LocalPolicyTestServer::GetTestServerPath( base::FilePath* testserver_path) const { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath source_root; if (!PathService::Get(base::DIR_SOURCE_ROOT, &source_root)) { LOG(ERROR) << "Failed to get DIR_SOURCE_ROOT"; @@ -238,6 +246,7 @@ bool LocalPolicyTestServer::GenerateAdditionalArguments( base::DictionaryValue* arguments) const { + base::ThreadRestrictions::ScopedAllowIO allow_io; if (!net::LocalTestServer::GenerateAdditionalArguments(arguments)) return false;
diff --git a/chrome/browser/prefs/pref_functional_browsertest.cc b/chrome/browser/prefs/pref_functional_browsertest.cc index 56d90df..ec142db 100644 --- a/chrome/browser/prefs/pref_functional_browsertest.cc +++ b/chrome/browser/prefs/pref_functional_browsertest.cc
@@ -6,6 +6,7 @@ #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" #include "chrome/browser/download/download_prefs.h" #include "chrome/browser/net/prediction_options.h" #include "chrome/browser/ui/browser.h" @@ -52,6 +53,7 @@ IN_PROC_BROWSER_TEST_F(PrefsFunctionalTest, TestDownloadDirPref) { ASSERT_TRUE(embedded_test_server()->Start()); + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir new_download_dir; ASSERT_TRUE(new_download_dir.CreateUniqueTempDir());
diff --git a/chrome/browser/prefs/pref_service_browsertest.cc b/chrome/browser/prefs/pref_service_browsertest.cc index 8f1eec42..f65bbb9 100644 --- a/chrome/browser/prefs/pref_service_browsertest.cc +++ b/chrome/browser/prefs/pref_service_browsertest.cc
@@ -10,6 +10,7 @@ #include "base/json/json_file_value_serializer.h" #include "base/path_service.h" #include "base/test/test_file_util.h" +#include "base/threading/thread_restrictions.h" #include "base/values.h" #include "build/build_config.h" #include "chrome/browser/ui/browser.h" @@ -87,7 +88,11 @@ // The window should open with the new reference profile, with window // placement values stored in the user data directory. JSONFileValueDeserializer deserializer(original_pref_file_); - std::unique_ptr<base::Value> root = deserializer.Deserialize(NULL, NULL); + std::unique_ptr<base::Value> root; + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + root = deserializer.Deserialize(NULL, NULL); + } ASSERT_TRUE(root.get()); ASSERT_TRUE(root->IsType(base::Value::Type::DICTIONARY));
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc index 647c65e..2b22d18a 100644 --- a/chrome/browser/prerender/prerender_browsertest.cc +++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -27,6 +27,7 @@ #include "base/test/scoped_feature_list.h" #include "base/test/simple_test_tick_clock.h" #include "base/test/test_timeouts.h" +#include "base/threading/thread_restrictions.h" #include "base/values.h" #include "build/build_config.h" #include "chrome/browser/browsing_data/browsing_data_helper.h" @@ -3261,10 +3262,13 @@ // Manager API. The page should be killed. IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, AutosigninInPrerenderer) { // Set up a credential in the password store. - PasswordStoreFactory::GetInstance()->SetTestingFactory( - current_browser()->profile(), - password_manager::BuildPasswordStore< - content::BrowserContext, password_manager::TestPasswordStore>); + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + PasswordStoreFactory::GetInstance()->SetTestingFactory( + current_browser()->profile(), + password_manager::BuildPasswordStore< + content::BrowserContext, password_manager::TestPasswordStore>); + } scoped_refptr<password_manager::TestPasswordStore> password_store = static_cast<password_manager::TestPasswordStore*>( PasswordStoreFactory::GetForProfile(
diff --git a/chrome/browser/profiles/profile_browsertest.cc b/chrome/browser/profiles/profile_browsertest.cc index dd3f2bf..20b97e6 100644 --- a/chrome/browser/profiles/profile_browsertest.cc +++ b/chrome/browser/profiles/profile_browsertest.cc
@@ -19,6 +19,7 @@ #include "base/sequenced_task_runner.h" #include "base/synchronization/waitable_event.h" #include "base/task_scheduler/task_scheduler.h" +#include "base/threading/thread_restrictions.h" #include "base/values.h" #include "base/version.h" #include "build/build_config.h" @@ -342,6 +343,7 @@ // Test OnProfileCreate is called with is_new_profile set to true when // creating a new profile synchronously. IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, CreateNewProfileSynchronous) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); @@ -367,6 +369,7 @@ // Test OnProfileCreate is called with is_new_profile set to false when // creating a profile synchronously with an existing prefs file. IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, CreateOldProfileSynchronous) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); CreatePrefsFileInDirectory(temp_dir.GetPath()); @@ -388,6 +391,7 @@ // creating a new profile asynchronously. IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, DISABLED_CreateNewProfileAsynchronous) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); @@ -422,6 +426,7 @@ // creating a profile asynchronously with an existing prefs file. IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, DISABLED_CreateOldProfileAsynchronous) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); CreatePrefsFileInDirectory(temp_dir.GetPath()); @@ -448,6 +453,7 @@ // Flaky: http://crbug.com/393177 // Test that a README file is created for profiles that didn't have it. IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, DISABLED_ProfileReadmeCreated) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); @@ -475,6 +481,7 @@ // Test that repeated setting of exit type is handled correctly. IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, ExitType) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); @@ -566,6 +573,7 @@ } // namespace IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, URLRequestContextIsolation) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); @@ -601,6 +609,7 @@ IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, OffTheRecordURLRequestContextIsolation) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); @@ -666,6 +675,7 @@ IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, WritesProfilesSynchronouslyOnEndSession) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); @@ -777,6 +787,7 @@ // Verifies the cache directory supports multiple profiles when it's overriden // by group policy or command line switches. IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, DiskCacheDirOverride) { + base::ThreadRestrictions::ScopedAllowIO allow_io; int size; const base::FilePath::StringPieceType profile_name = FILE_PATH_LITERAL("Profile 1");
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc index 45c3b9be..2a06e4d9 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
@@ -19,6 +19,7 @@ #include "base/strings/string16.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/browser_process.h" @@ -114,6 +115,7 @@ // Does not work on ChromeOS. Profile* CreateSecondaryProfile(int profile_num) { + base::ThreadRestrictions::ScopedAllowIO allow_io; ProfileManager* profile_manager = g_browser_process->profile_manager(); base::FilePath profile_path = profile_manager->user_data_dir(); profile_path = profile_path.AppendASCII(
diff --git a/chrome/browser/resources/cleanup_tool/cleanup_browser_proxy.js b/chrome/browser/resources/cleanup_tool/cleanup_browser_proxy.js index d62dbe2f..ef22211 100644 --- a/chrome/browser/resources/cleanup_tool/cleanup_browser_proxy.js +++ b/chrome/browser/resources/cleanup_tool/cleanup_browser_proxy.js
@@ -17,6 +17,15 @@ */ var LastScanResult; +/** + * @typedef {{ + * wasCancelled: boolean, + * uwsRemoved: Array<string>, + * requiresReboot: boolean, + * }} + */ +var CleanupResult; + cr.define('cleanup', function() { /** @interface */ function CleanupBrowserProxy() {} @@ -32,6 +41,12 @@ * @return {!Promise<LastScanResult>} */ startScan: function() {}, + + /** + * Opens the prompt to run the Chrome Cleanup Tool. + * @return {!Promise<CleanupResult>} + */ + startCleanup: function() {}, }; /** @@ -50,6 +65,10 @@ startScan: function() { return cr.sendWithPromise('startScan'); }, + /** @override */ + startCleanup: function() { + return cr.sendWithPromise('startCleanup'); + }, }; return {
diff --git a/chrome/browser/resources/cleanup_tool/manager.html b/chrome/browser/resources/cleanup_tool/manager.html index a1c8c4d..769e5cb9 100644 --- a/chrome/browser/resources/cleanup_tool/manager.html +++ b/chrome/browser/resources/cleanup_tool/manager.html
@@ -117,15 +117,19 @@ [[detectionTimeText]] </div> </div> - <div id="spinner-container" hidden="[[!isRunningScanner]]"> + <div id="spinner-container" hidden="[[!isRunning]]"> <paper-spinner active></paper-spinner> </div> <div id="tool-action-container"> <div class="scan-or-cleanup-action" - hidden="[[!shouldShowScan_(hasScanResults, isRunningScanner)]]" + hidden="[[!shouldShowScan_(hasScanResults, isRunning)]]" on-tap="onScanTap_">$i18n{scanAction}</div> - <div hidden="[[!isRunningScanner]]">$i18n{scanning}</div> - <div class="scan-or-cleanup-action" hidden="[[!hasScanResults]]" + <div hidden="[[!shouldShowScanning_(hasScanResults, isRunning)]]"> + $i18n{scanning}</div> + <div hidden="[[!shouldShowCleaning_(hasScanResults, isRunning)]]"> + $i18n{cleaning}</div> + <div class="scan-or-cleanup-action" + hidden="[[!shouldShowClean_(hasScanResults, isRunning)]]" on-tap="onCleanupTap_">$i18n{cleanAction}</div> </div> </div>
diff --git a/chrome/browser/resources/cleanup_tool/manager.js b/chrome/browser/resources/cleanup_tool/manager.js index d9bfa9a8..ce921d61d 100644 --- a/chrome/browser/resources/cleanup_tool/manager.js +++ b/chrome/browser/resources/cleanup_tool/manager.js
@@ -16,7 +16,7 @@ value: false, }, - isRunningScanner: { + isRunning: { type: Boolean, value: false, }, @@ -68,7 +68,21 @@ * @private */ onCleanupTap_: function() { - // TODO implement me. + this.isRunning = true; + this.browserProxy_.startCleanup().then(this.onCleanupResult_.bind(this)); + }, + + /** + * @param {CleanupResult} cleanupResults + */ + onCleanupResult_: function(cleanupResults) { + this.isRunning = false; + + if (!cleanupResults.wasCancelled) + // Assume cleanup was completed and clear infected status. + this.isInfected = false; + + // TODO(proberge): Do something about cleanupResults.uwsRemoved. }, /** @@ -95,13 +109,43 @@ /** * @param {boolean} hasScanResults - * @param {boolean} isRunningScanner - * @return {boolean} True if the "Scan" button should be displayed, false - * otherwise. + * @param {boolean} isRunning + * @return {boolean} Whether the "Scan" button should be displayed. * @private */ - shouldShowScan_: function(hasScanResults, isRunningScanner) { - return !hasScanResults && !isRunningScanner; + shouldShowScan_: function(hasScanResults, isRunning) { + return !hasScanResults && !isRunning; + }, + + /** + * @param {boolean} hasScanResults + * @param {boolean} isRunning + * @return {boolean} Whether the "Run Chrome Cleanup" button should be + * displayed. + * @private + */ + shouldShowClean_: function(hasScanResults, isRunning) { + return hasScanResults && !isRunning; + }, + + /** + * @param {boolean} hasScanResults + * @param {boolean} isRunning + * @return {boolean} True Whether the "Scanning" label should be displayed. + * @private + */ + shouldShowScanning_: function(hasScanResults, isRunning) { + return !hasScanResults && isRunning; + }, + + /** + * @param {boolean} hasScanResults + * @param {boolean} isRunning + * @return {boolean} True Whether the "Cleaning" label should be displayed. + * @private + */ + shouldShowCleaning_: function(hasScanResults, isRunning) { + return hasScanResults && isRunning; }, /**
diff --git a/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.html b/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.html index bb50157..0738762 100644 --- a/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.html +++ b/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.html
@@ -50,11 +50,12 @@ <div id="passwordGroup"> <paper-input id="passwordInput" always-float-label label="$i18n{editPasswordPasswordLabel}" - type="[[getPasswordInputType_(password)]]" + type="[[getPasswordInputType_(item, password)]]" value="[[getPassword_(item, password)]]" readonly on-tap="onReadonlyInputTap_"> </paper-input> <paper-icon-button id="showPasswordButton" + hidden$="[[item.federationText]]" icon="settings:visibility" on-tap="onShowPasswordButtonTap_" title="[[showPasswordTitle_(password, '$i18nPolymer{hidePassword}','$i18nPolymer{showPassword}')]]">
diff --git a/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.js b/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.js index cb9aa3f..94f958b 100644 --- a/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.js +++ b/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.js
@@ -37,12 +37,11 @@ /** * Gets the password input's type. Should be 'text' when password is visible - * and 'password' when it's not. - * @param {string} password + * or when there's federated text otherwise 'password'. * @private */ - getPasswordInputType_: function(password) { - return password ? 'text' : 'password'; + getPasswordInputType_: function() { + return this.password || this.item.federationText ? 'text' : 'password'; }, /** @@ -58,15 +57,16 @@ /** * Gets the text of the password. Will use the value of |password| unless it - * cannot be shown, in which case it will be spaces. - * @param {!chrome.passwordsPrivate.PasswordUiEntry} item - * @param {string} password + * cannot be shown, in which case it will be spaces. It can also be the + * federated text. * @private */ - getPassword_: function(item, password) { - if (password) - return password; - return item ? ' '.repeat(item.numCharactersInPassword) : ''; + getPassword_: function() { + if (!this.item) + return ''; + + return this.item.federationText || this.password || + ' '.repeat(this.item.numCharactersInPassword); }, /**
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc index daab3f7..1c65a29 100644 --- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc +++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc
@@ -225,6 +225,8 @@ content::DownloadManager* manager = content::BrowserContext::GetDownloadManager(browser()->profile()); manager->GetAllDownloads(&download_items); + if (download_items.empty()) + DownloadItemCreatedObserver(manager).WaitForDownloadItem(&download_items); EXPECT_EQ(1U, download_items.size()); return download_items[0]; }
diff --git a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc index ab5ca80..03e93a4 100644 --- a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc +++ b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
@@ -1504,6 +1504,7 @@ EXPECT_TRUE(csd_service->enabled()); // Add a new Profile. SBS should keep running. + base::ThreadRestrictions::ScopedAllowIO allow_io; ASSERT_TRUE(temp_profile_dir_.CreateUniqueTempDir()); std::unique_ptr<Profile> profile2(Profile::CreateProfile( temp_profile_dir_.GetPath(), nullptr, Profile::CREATE_MODE_SYNCHRONOUS)); @@ -1603,7 +1604,10 @@ // Create an additional profile. We need to use the ProfileManager so that // the profile will get destroyed in the normal browser shutdown process. ProfileManager* profile_manager = g_browser_process->profile_manager(); - ASSERT_TRUE(temp_profile_dir_.CreateUniqueTempDir()); + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + ASSERT_TRUE(temp_profile_dir_.CreateUniqueTempDir()); + } profile_manager->CreateProfileAsync( temp_profile_dir_.GetPath(), base::Bind(&SafeBrowsingServiceShutdownTest::OnUnblockOnProfileCreation,
diff --git a/chrome/browser/service_process/service_process_control_browsertest.cc b/chrome/browser/service_process/service_process_control_browsertest.cc index 9a072501..a9340b1d 100644 --- a/chrome/browser/service_process/service_process_control_browsertest.cc +++ b/chrome/browser/service_process/service_process_control_browsertest.cc
@@ -14,6 +14,7 @@ #include "base/process/process_iterator.h" #include "base/single_thread_task_runner.h" #include "base/test/test_timeouts.h" +#include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "chrome/browser/ui/browser.h" @@ -99,6 +100,7 @@ } void ProcessControlLaunched() { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ProcessId service_pid; EXPECT_TRUE(GetServiceProcessData(NULL, &service_pid)); EXPECT_NE(static_cast<base::ProcessId>(0), service_pid); @@ -304,6 +306,7 @@ // Make sure we are connected to the service process. ASSERT_TRUE(ServiceProcessControl::GetInstance()->IsConnected()); base::ProcessId service_pid; + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_TRUE(GetServiceProcessData(NULL, &service_pid)); EXPECT_NE(static_cast<base::ProcessId>(0), service_pid); ForceServiceProcessShutdown(version_info::GetVersionNumber(), service_pid); @@ -317,6 +320,7 @@ #endif IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, MAYBE_CheckPid) { base::ProcessId service_pid; + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_FALSE(GetServiceProcessData(NULL, &service_pid)); // Launch the service process. LaunchServiceProcessControl(true);
diff --git a/chrome/browser/sessions/session_restore_browsertest.cc b/chrome/browser/sessions/session_restore_browsertest.cc index 324bf09..db9b2bc 100644 --- a/chrome/browser/sessions/session_restore_browsertest.cc +++ b/chrome/browser/sessions/session_restore_browsertest.cc
@@ -16,6 +16,7 @@ #include "base/memory/ptr_util.h" #include "base/process/launch.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" #include "base/time/time.h" #include "build/build_config.h" #include "chrome/browser/defaults.h" @@ -1450,6 +1451,7 @@ } IN_PROC_BROWSER_TEST_F(SessionRestoreTest, TabWithDownloadDoesNotGetRestored) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir download_directory; ASSERT_TRUE(download_directory.CreateUniqueTempDir()); ASSERT_TRUE(embedded_test_server()->Start());
diff --git a/chrome/browser/spellchecker/spellcheck_service_browsertest.cc b/chrome/browser/spellchecker/spellcheck_service_browsertest.cc index 0c3895a..21fe47eb 100644 --- a/chrome/browser/spellchecker/spellcheck_service_browsertest.cc +++ b/chrome/browser/spellchecker/spellcheck_service_browsertest.cc
@@ -18,6 +18,7 @@ #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/synchronization/waitable_event.h" +#include "base/threading/thread_restrictions.h" #include "base/values.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/spellchecker/spellcheck_factory.h" @@ -269,10 +270,13 @@ base::FilePath bdict_path = spellcheck::GetVersionedFileName("en-US", dict_dir); - size_t actual = base::WriteFile(bdict_path, - reinterpret_cast<const char*>(kCorruptedBDICT), - arraysize(kCorruptedBDICT)); - EXPECT_EQ(arraysize(kCorruptedBDICT), actual); + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + size_t actual = base::WriteFile( + bdict_path, reinterpret_cast<const char*>(kCorruptedBDICT), + arraysize(kCorruptedBDICT)); + EXPECT_EQ(arraysize(kCorruptedBDICT), actual); + } // Attach an event to the SpellcheckService object so we can receive its // status updates. @@ -304,6 +308,7 @@ content::RunAllPendingInMessageLoop(content::BrowserThread::UI); EXPECT_EQ(SpellcheckService::BDICT_CORRUPTED, SpellcheckService::GetStatusEvent()); + base::ThreadRestrictions::ScopedAllowIO allow_io; if (base::PathExists(bdict_path)) { ADD_FAILURE(); EXPECT_TRUE(base::DeleteFile(bdict_path, true));
diff --git a/chrome/browser/ssl/ssl_browser_tests.cc b/chrome/browser/ssl/ssl_browser_tests.cc index 8324db2e..09273e0a 100644 --- a/chrome/browser/ssl/ssl_browser_tests.cc +++ b/chrome/browser/ssl/ssl_browser_tests.cc
@@ -20,6 +20,7 @@ #include "base/test/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "base/test/simple_test_clock.h" +#include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/default_clock.h" #include "base/time/default_tick_clock.h" @@ -1353,7 +1354,10 @@ std::string pkcs12_data; base::FilePath cert_path = net::GetTestCertsDirectory().Append( FILE_PATH_LITERAL("websocket_client_cert.p12")); - EXPECT_TRUE(base::ReadFileToString(cert_path, &pkcs12_data)); + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + EXPECT_TRUE(base::ReadFileToString(cert_path, &pkcs12_data)); + } EXPECT_EQ(net::OK, cert_db_->ImportFromPKCS12(public_slot.get(), pkcs12_data, base::string16(), true, NULL)); @@ -1436,6 +1440,7 @@ GURL url_non_dangerous = embedded_test_server()->GetURL("/title1.html"); GURL url_dangerous = https_server_expired_.GetURL("/downloads/dangerous/dangerous.exe"); + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir downloads_directory_; // Need empty temp dir to avoid having Chrome ask us for a new filename
diff --git a/chrome/browser/sync/test/integration/bookmarks_helper.cc b/chrome/browser/sync/test/integration/bookmarks_helper.cc index da2ab1c..cfc07f82 100644 --- a/chrome/browser/sync/test/integration/bookmarks_helper.cc +++ b/chrome/browser/sync/test/integration/bookmarks_helper.cc
@@ -24,6 +24,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/synchronization/waitable_event.h" #include "base/task/cancelable_task_tracker.h" +#include "base/threading/thread_restrictions.h" #include "chrome/browser/bookmarks/bookmark_model_factory.h" #include "chrome/browser/bookmarks/managed_bookmark_service_factory.h" #include "chrome/browser/favicon/favicon_service_factory.h" @@ -852,6 +853,7 @@ } gfx::Image Create1xFaviconFromPNGFile(const std::string& path) { + base::ThreadRestrictions::ScopedAllowIO allow_io; const char* kPNGExtension = ".png"; if (!base::EndsWith(path, kPNGExtension, base::CompareCase::INSENSITIVE_ASCII))
diff --git a/chrome/browser/sync/test/integration/single_client_directory_sync_test.cc b/chrome/browser/sync/test/integration/single_client_directory_sync_test.cc index 1768ca8c..ddf9c6f8 100644 --- a/chrome/browser/sync/test/integration/single_client_directory_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_directory_sync_test.cc
@@ -10,6 +10,7 @@ #include "base/single_thread_task_runner.h" #include "base/strings/string_number_conversions.h" #include "base/synchronization/waitable_event.h" +#include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "chrome/browser/sync/test/integration/bookmarks_helper.h" @@ -33,6 +34,7 @@ // will avoid seeing any of those, and return iff Directory database files still // exist. bool FolderContainsFiles(const FilePath& folder) { + base::ThreadRestrictions::ScopedAllowIO allow_io; if (base::DirectoryExists(folder)) { return !FileEnumerator(folder, false, FileEnumerator::FILES).Next().empty(); } else {
diff --git a/chrome/browser/sync/test/integration/sync_extension_helper.cc b/chrome/browser/sync/test/integration/sync_extension_helper.cc index 8fcfd61..55322db 100644 --- a/chrome/browser/sync/test/integration/sync_extension_helper.cc +++ b/chrome/browser/sync/test/integration/sync_extension_helper.cc
@@ -15,6 +15,7 @@ #include "base/memory/ptr_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" +#include "base/threading/thread_restrictions.h" #include "base/values.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_util.h" @@ -84,6 +85,7 @@ std::string SyncExtensionHelper::InstallExtension( Profile* profile, const std::string& name, Manifest::Type type) { + base::ThreadRestrictions::ScopedAllowIO allow_io; scoped_refptr<Extension> extension = GetExtension(profile, name, type); if (!extension.get()) { NOTREACHED() << "Could not install extension " << name;
diff --git a/chrome/browser/sync/test/integration/sync_test.cc b/chrome/browser/sync/test/integration/sync_test.cc index f2a9a285..c783c2b 100644 --- a/chrome/browser/sync/test/integration/sync_test.cc +++ b/chrome/browser/sync/test/integration/sync_test.cc
@@ -25,6 +25,7 @@ #include "base/synchronization/waitable_event.h" #include "base/test/test_timeouts.h" #include "base/threading/platform_thread.h" +#include "base/threading/thread_restrictions.h" #include "base/values.h" #include "build/build_config.h" #include "chrome/browser/bookmarks/bookmark_model_factory.h" @@ -338,6 +339,7 @@ } void SyncTest::CreateProfile(int index) { + base::ThreadRestrictions::ScopedAllowIO allow_io; tmp_profile_paths_[index] = new base::ScopedTempDir(); if (UsingExternalServers() && num_clients_ > 1) { // For multi profile UI signin, profile paths should be outside user data @@ -504,6 +506,7 @@ } bool SyncTest::SetupClients() { + base::ThreadRestrictions::ScopedAllowIO allow_io; if (num_clients_ <= 0) LOG(FATAL) << "num_clients_ incorrectly initialized."; if (!profiles_.empty() || !browsers_.empty() || !clients_.empty()) @@ -646,6 +649,7 @@ } bool SyncTest::SetupSync() { + base::ThreadRestrictions::ScopedAllowIO allow_io; // Create sync profiles and clients if they haven't already been created. if (profiles_.empty()) { if (!SetupClients()) {
diff --git a/chrome/browser/task_manager/providers/web_contents/tab_contents_tag_browsertest.cc b/chrome/browser/task_manager/providers/web_contents/tab_contents_tag_browsertest.cc index 08e35d4..060453c 100644 --- a/chrome/browser/task_manager/providers/web_contents/tab_contents_tag_browsertest.cc +++ b/chrome/browser/task_manager/providers/web_contents/tab_contents_tag_browsertest.cc
@@ -7,6 +7,7 @@ #include "base/macros.h" #include "base/path_service.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" #include "chrome/browser/task_manager/mock_web_contents_task_manager.h" #include "chrome/browser/task_manager/providers/web_contents/web_contents_tags_manager.h" #include "chrome/browser/ui/browser.h" @@ -294,8 +295,12 @@ base::FilePath test_dir; PathService::Get(chrome::DIR_TEST_DATA, &test_dir); std::string favicon_string; - base::ReadFileToString( - test_dir.AppendASCII("favicon").AppendASCII("icon.png"), &favicon_string); + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + base::ReadFileToString( + test_dir.AppendASCII("favicon").AppendASCII("icon.png"), + &favicon_string); + } SkBitmap favicon_bitmap; gfx::PNGCodec::Decode( reinterpret_cast<const unsigned char*>(favicon_string.data()),
diff --git a/chrome/browser/themes/theme_service_browsertest.cc b/chrome/browser/themes/theme_service_browsertest.cc index 182557bc..7ed17415 100644 --- a/chrome/browser/themes/theme_service_browsertest.cc +++ b/chrome/browser/themes/theme_service_browsertest.cc
@@ -6,6 +6,7 @@ #include "base/macros.h" #include "base/threading/sequenced_worker_pool.h" +#include "base/threading/thread_restrictions.h" #include "chrome/browser/extensions/component_loader.h" #include "chrome/browser/extensions/extension_browsertest.h" #include "chrome/browser/profiles/profile.h" @@ -68,6 +69,7 @@ // Add a vestigial .pak file that should be removed when the new one is // created. // TODO(estade): remove when vestigial .pak file deletion is removed. + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_EQ( 1, base::WriteFile(profile->GetPrefs() ->GetFilePath(prefs::kCurrentThemePackFilename) @@ -99,6 +101,7 @@ ->GetPrefs() ->GetFilePath(prefs::kCurrentThemePackFilename) .AppendASCII("Cached Theme Material Design.pak"); + base::ThreadRestrictions::ScopedAllowIO allow_io; EXPECT_FALSE(base::PathExists(old_path)) << "File not deleted: " << old_path.value(); }
diff --git a/chrome/browser/ui/browser_focus_uitest.cc b/chrome/browser/ui/browser_focus_uitest.cc index 17d0c468..10ed864 100644 --- a/chrome/browser/ui/browser_focus_uitest.cc +++ b/chrome/browser/ui/browser_focus_uitest.cc
@@ -14,6 +14,7 @@ #include "base/single_thread_task_runner.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "chrome/browser/chrome_notification_types.h" @@ -179,6 +180,7 @@ class TestInterstitialPage : public content::InterstitialPageDelegate { public: explicit TestInterstitialPage(WebContents* tab) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath file_path; bool success = PathService::Get(chrome::DIR_TEST_DATA, &file_path); EXPECT_TRUE(success);
diff --git a/chrome/browser/ui/cocoa/extensions/extension_install_prompt_test_utils.mm b/chrome/browser/ui/cocoa/extensions/extension_install_prompt_test_utils.mm index 111b4e9..62479d2 100644 --- a/chrome/browser/ui/cocoa/extensions/extension_install_prompt_test_utils.mm +++ b/chrome/browser/ui/cocoa/extensions/extension_install_prompt_test_utils.mm
@@ -8,6 +8,7 @@ #include "base/files/file_util.h" #include "base/json/json_file_value_serializer.h" #include "base/path_service.h" +#include "base/threading/thread_restrictions.h" #include "chrome/common/chrome_paths.h" #include "extensions/common/extension.h" @@ -18,6 +19,7 @@ scoped_refptr<extensions::Extension> LoadInstallPromptExtension( const char* extension_dir_name, const char* manifest_file) { + base::ThreadRestrictions::ScopedAllowIO allow_io; scoped_refptr<Extension> extension; base::FilePath path; @@ -49,6 +51,7 @@ } gfx::Image LoadInstallPromptIcon() { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath path; PathService::Get(chrome::DIR_TEST_DATA, &path); path = path.AppendASCII("extensions")
diff --git a/chrome/browser/ui/find_bar/find_bar_controller.cc b/chrome/browser/ui/find_bar/find_bar_controller.cc index db9cfce..cfacd76 100644 --- a/chrome/browser/ui/find_bar/find_bar_controller.cc +++ b/chrome/browser/ui/find_bar/find_bar_controller.cc
@@ -58,6 +58,10 @@ ResultAction result_action) { find_bar_->Hide(true); + // If the user searches again for this string, it should notify if the result + // comes back empty again. + alerted_search_.clear(); + // |web_contents_| can be NULL for a number of reasons, for example when the // tab is closing. We must guard against that case. See issue 8030. if (web_contents_) { @@ -139,14 +143,24 @@ // are actively tracking. if (content::Source<WebContents>(source).ptr() == web_contents_) { UpdateFindBarForCurrentResult(); + + // A final update can occur multiple times if the document changes. if (find_tab_helper->find_result().final_update() && find_tab_helper->find_result().number_of_matches() == 0) { const base::string16& last_search = find_tab_helper->previous_find_text(); const base::string16& current_search = find_tab_helper->find_text(); - if (!base::StartsWith(last_search, current_search, - base::CompareCase::SENSITIVE)) { - find_bar_->AudibleAlert(); + + // Alert the user once per unique search, if they aren't backspacing. + if (current_search != alerted_search_) { + // Keep track of the last notified search string, even if the + // notification itself is elided. + if (!base::StartsWith(last_search, current_search, + base::CompareCase::SENSITIVE)) { + find_bar_->AudibleAlert(); + } + + alerted_search_ = current_search; } } }
diff --git a/chrome/browser/ui/find_bar/find_bar_controller.h b/chrome/browser/ui/find_bar/find_bar_controller.h index 89d252a..25ecaed1 100644 --- a/chrome/browser/ui/find_bar/find_bar_controller.h +++ b/chrome/browser/ui/find_bar/find_bar_controller.h
@@ -99,6 +99,12 @@ // UpdateFindBarForCurrentResult to avoid flickering. int last_reported_matchcount_; + // Used to keep track of whether the user has been notified that the find came + // up empty. A single find session can result in multiple final updates, if + // the document contents change dynamically. It's a nuisance to notify the + // user more than once that a search came up empty, however. + base::string16 alerted_search_; + DISALLOW_COPY_AND_ASSIGN(FindBarController); };
diff --git a/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc b/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc index 1a1b9ffd..d729463 100644 --- a/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc +++ b/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc
@@ -435,7 +435,10 @@ base::FilePath().AppendASCII("find_in_page"), base::FilePath().AppendASCII("LongFind.txt")); std::string query; - base::ReadFileToString(path, &query); + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + base::ReadFileToString(path, &query); + } EXPECT_EQ(1, FindInPage16(web_contents, base::UTF8ToUTF16(query), kFwd, kIgnoreCase, NULL)); } @@ -501,7 +504,10 @@ ui_test_utils::NavigateToURL(browser(), net::FilePathToFileURL(path)); std::string query; - base::ReadFileToString(path, &query); + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + base::ReadFileToString(path, &query); + } EXPECT_EQ(1, FindInPage16(web_contents, base::UTF8ToUTF16(query), false, false, NULL)); }
diff --git a/chrome/browser/ui/libgtkui/app_indicator_icon.cc b/chrome/browser/ui/libgtkui/app_indicator_icon.cc index d43f6760..e75711761 100644 --- a/chrome/browser/ui/libgtkui/app_indicator_icon.cc +++ b/chrome/browser/ui/libgtkui/app_indicator_icon.cc
@@ -14,7 +14,7 @@ #include "base/memory/ref_counted_memory.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" -#include "base/threading/sequenced_worker_pool.h" +#include "base/task_scheduler/post_task.h" #include "chrome/browser/ui/libgtkui/app_indicator_icon_menu.h" #include "content/public/browser/browser_thread.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -193,8 +193,10 @@ if (icon_) { app_indicator_set_status(icon_, APP_INDICATOR_STATUS_PASSIVE); g_object_unref(icon_); - content::BrowserThread::GetBlockingPool()->PostTask( - FROM_HERE, base::BindOnce(&DeleteTempDirectory, temp_dir_)); + base::PostTaskWithTraits(FROM_HERE, + base::TaskTraits().MayBlock().WithPriority( + base::TaskPriority::BACKGROUND), + base::BindOnce(&DeleteTempDirectory, temp_dir_)); } } @@ -214,21 +216,23 @@ // another thread. SkBitmap safe_bitmap = *image.bitmap(); - scoped_refptr<base::TaskRunner> task_runner = - content::BrowserThread::GetBlockingPool() - ->GetTaskRunnerWithShutdownBehavior( - base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); + const base::TaskTraits kTraits = + base::TaskTraits() + .MayBlock() + .WithPriority(base::TaskPriority::USER_VISIBLE) + .WithShutdownBehavior(base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN); + if (desktop_env_ == base::nix::DESKTOP_ENVIRONMENT_KDE4 || desktop_env_ == base::nix::DESKTOP_ENVIRONMENT_KDE5) { - base::PostTaskAndReplyWithResult( - task_runner.get(), FROM_HERE, + base::PostTaskWithTraitsAndReplyWithResult( + FROM_HERE, kTraits, base::Bind(AppIndicatorIcon::WriteKDE4TempImageOnWorkerThread, safe_bitmap, temp_dir_), base::Bind(&AppIndicatorIcon::SetImageFromFile, weak_factory_.GetWeakPtr())); } else { - base::PostTaskAndReplyWithResult( - task_runner.get(), FROM_HERE, + base::PostTaskWithTraitsAndReplyWithResult( + FROM_HERE, kTraits, base::Bind(AppIndicatorIcon::WriteUnityTempImageOnWorkerThread, safe_bitmap, icon_change_count_, id_), base::Bind(&AppIndicatorIcon::SetImageFromFile, @@ -361,8 +365,10 @@ } if (temp_dir_ != params.parent_temp_dir) { - content::BrowserThread::GetBlockingPool()->PostTask( - FROM_HERE, base::BindOnce(&DeleteTempDirectory, temp_dir_)); + base::PostTaskWithTraits(FROM_HERE, + base::TaskTraits().MayBlock().WithPriority( + base::TaskPriority::BACKGROUND), + base::BindOnce(&DeleteTempDirectory, temp_dir_)); temp_dir_ = params.parent_temp_dir; } }
diff --git a/chrome/browser/ui/search/local_ntp_browsertest.cc b/chrome/browser/ui/search/local_ntp_browsertest.cc index fbdd5aa..6e8fa4e10 100644 --- a/chrome/browser/ui/search/local_ntp_browsertest.cc +++ b/chrome/browser/ui/search/local_ntp_browsertest.cc
@@ -4,6 +4,7 @@ #include "base/command_line.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/search/search.h" @@ -40,6 +41,7 @@ // Switches the browser language to French, and returns true iff successful. bool SwitchToFrench() { + base::ThreadRestrictions::ScopedAllowIO allow_io; // Make sure the default language is not French. std::string default_locale = g_browser_process->GetApplicationLocale(); EXPECT_NE("fr", default_locale); @@ -305,6 +307,7 @@ EXPECT_NE("fr", default_locale); // Switch browser language to French. + base::ThreadRestrictions::ScopedAllowIO allow_io; std::string loaded_locale = ui::ResourceBundle::GetSharedInstance().ReloadLocaleResources("fr"); @@ -349,6 +352,7 @@ } void SetUserSelectedDefaultSearchProvider(const std::string& base_url) { + base::ThreadRestrictions::ScopedAllowIO allow_io; TemplateURLData data; data.SetShortName(base::UTF8ToUTF16(base_url)); data.SetKeyword(base::UTF8ToUTF16(base_url));
diff --git a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc index 16b3334..b137627 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
@@ -13,6 +13,7 @@ #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" #include "base/test/histogram_tester.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" @@ -449,7 +450,11 @@ base::FilePath dest_path = profile_manager->user_data_dir(); dest_path = dest_path.Append(FILE_PATH_LITERAL("New Profile 1")); - Profile* other_profile = profile_manager->GetProfile(dest_path); + Profile* other_profile = nullptr; + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + other_profile = profile_manager->GetProfile(dest_path); + } ASSERT_TRUE(other_profile); // Use a couple arbitrary URLs. @@ -635,6 +640,7 @@ base::FilePath dest_path4 = profile_manager->user_data_dir().Append( FILE_PATH_LITERAL("New Profile 4")); + base::ThreadRestrictions::ScopedAllowIO allow_io; Profile* profile_home1 = profile_manager->GetProfile(dest_path1); ASSERT_TRUE(profile_home1); Profile* profile_home2 = profile_manager->GetProfile(dest_path2); @@ -743,12 +749,18 @@ base::FilePath dest_path3 = profile_manager->user_data_dir().Append( FILE_PATH_LITERAL("New Profile 3")); - Profile* profile_home = profile_manager->GetProfile(dest_path1); - ASSERT_TRUE(profile_home); - Profile* profile_last = profile_manager->GetProfile(dest_path2); - ASSERT_TRUE(profile_last); - Profile* profile_urls = profile_manager->GetProfile(dest_path3); - ASSERT_TRUE(profile_urls); + Profile* profile_home = nullptr; + Profile* profile_last = nullptr; + Profile* profile_urls = nullptr; + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + profile_home = profile_manager->GetProfile(dest_path1); + ASSERT_TRUE(profile_home); + profile_last = profile_manager->GetProfile(dest_path2); + ASSERT_TRUE(profile_last); + profile_urls = profile_manager->GetProfile(dest_path3); + ASSERT_TRUE(profile_urls); + } // Set the profiles to open the home page, last visited pages or URLs. SessionStartupPref pref_home(SessionStartupPref::DEFAULT); @@ -1067,9 +1079,13 @@ // Open the two profiles. base::FilePath dest_path = profile_manager->user_data_dir(); - Profile* profile1 = Profile::CreateProfile( - dest_path.Append(FILE_PATH_LITERAL("New Profile 1")), nullptr, - Profile::CreateMode::CREATE_MODE_SYNCHRONOUS); + Profile* profile1 = nullptr; + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + profile1 = Profile::CreateProfile( + dest_path.Append(FILE_PATH_LITERAL("New Profile 1")), nullptr, + Profile::CreateMode::CREATE_MODE_SYNCHRONOUS); + } ASSERT_TRUE(profile1); profile_manager->RegisterTestingProfile(profile1, true, false);
diff --git a/chrome/browser/ui/startup/startup_browser_creator_corrupt_profiles_browsertest_win.cc b/chrome/browser/ui/startup/startup_browser_creator_corrupt_profiles_browsertest_win.cc index 4b1f1c48..97a9cc7 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_corrupt_profiles_browsertest_win.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_corrupt_profiles_browsertest_win.cc
@@ -15,6 +15,7 @@ #include "base/run_loop.h" #include "base/strings/string_util.h" #include "base/test/test_file_util.h" +#include "base/threading/thread_restrictions.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profile_window.h" @@ -273,6 +274,7 @@ CloseBrowsersSynchronouslyForProfileBasePath("Profile 1"); CreateAndSwitchToProfile("Profile 2"); + base::ThreadRestrictions::ScopedAllowIO allow_io; ASSERT_TRUE(base::CreateDirectory(ProfileManager::GetGuestProfilePath())); ASSERT_TRUE(base::CreateDirectory(ProfileManager::GetSystemProfilePath())); } @@ -302,6 +304,7 @@ // Create the guest profile path, but not the system profile one. This will // make it impossible to create the system profile once the permissions are // locked down during setup. + base::ThreadRestrictions::ScopedAllowIO allow_io; ASSERT_TRUE(base::CreateDirectory(ProfileManager::GetGuestProfilePath())); } @@ -402,6 +405,7 @@ // manager instead. IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorCorruptProfileTest, PRE_DeletedProfileFallbackToUserManager) { + base::ThreadRestrictions::ScopedAllowIO allow_io; ASSERT_TRUE(base::CreateDirectory(ProfileManager::GetGuestProfilePath())); ASSERT_TRUE(base::CreateDirectory(ProfileManager::GetSystemProfilePath())); }
diff --git a/chrome/browser/ui/startup/startup_browser_creator_interactive_uitest.cc b/chrome/browser/ui/startup/startup_browser_creator_interactive_uitest.cc index 5279bce..d664dc82 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_interactive_uitest.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_interactive_uitest.cc
@@ -7,6 +7,7 @@ #include "base/command_line.h" #include "base/files/file_path.h" #include "base/run_loop.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/prefs/session_startup_pref.h" @@ -28,6 +29,7 @@ // And this test is useless without that functionality. #if !defined(OS_CHROMEOS) && !defined(OS_MACOSX) IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorTest, LastUsedProfileActivated) { + base::ThreadRestrictions::ScopedAllowIO allow_io; ProfileManager* profile_manager = g_browser_process->profile_manager(); // Create 4 profiles, they will be scheduled for destruction when the last
diff --git a/chrome/browser/ui/startup/startup_browser_creator_triggered_reset_browsertest_win.cc b/chrome/browser/ui/startup/startup_browser_creator_triggered_reset_browsertest_win.cc index cf25549..2c306aca 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_triggered_reset_browsertest_win.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_triggered_reset_browsertest_win.cc
@@ -10,6 +10,7 @@ #include "base/command_line.h" #include "base/macros.h" #include "base/memory/ptr_util.h" +#include "base/threading/thread_restrictions.h" #include "base/win/windows_version.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/lifetime/keep_alive_types.h" @@ -236,8 +237,12 @@ ProfileManager* profile_manager = g_browser_process->profile_manager(); base::FilePath path = profile_manager->user_data_dir().AppendASCII("test_profile"); - Profile* other_profile = - Profile::CreateProfile(path, nullptr, Profile::CREATE_MODE_SYNCHRONOUS); + Profile* other_profile = nullptr; + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + other_profile = + Profile::CreateProfile(path, nullptr, Profile::CREATE_MODE_SYNCHRONOUS); + } profile_manager->RegisterTestingProfile(other_profile, true, false); // Use a couple same-site HTTP URLs.
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view_browsertest.cc b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view_browsertest.cc index c038dde..46b8fc0 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view_browsertest.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view_browsertest.cc
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/threading/thread_restrictions.h" #include "chrome/browser/bookmarks/bookmark_model_factory.h" #include "chrome/browser/signin/fake_signin_manager_builder.h" #include "chrome/browser/signin/signin_manager_factory.h" @@ -82,17 +83,20 @@ IN_PROC_BROWSER_TEST_F(BookmarkBubbleViewBrowserTest, InvokeDialog_bookmark_details) { + base::ThreadRestrictions::ScopedAllowIO allow_io; RunDialog(); } IN_PROC_BROWSER_TEST_F(BookmarkBubbleViewBrowserTest, InvokeDialog_bookmark_details_signed_in) { + base::ThreadRestrictions::ScopedAllowIO allow_io; RunDialog(); } #if defined(OS_WIN) IN_PROC_BROWSER_TEST_F(BookmarkBubbleViewBrowserTest, InvokeDialog_ios_promotion) { + base::ThreadRestrictions::ScopedAllowIO allow_io; RunDialog(); } #endif
diff --git a/chrome/browser/ui/views/payments/payment_request_payment_response_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_payment_response_browsertest.cc index 66f7dae..ee6d9a0 100644 --- a/chrome/browser/ui/views/payments/payment_request_payment_response_browsertest.cc +++ b/chrome/browser/ui/views/payments/payment_request_payment_response_browsertest.cc
@@ -57,7 +57,8 @@ ExpectBodyContains({"\"billingAddress\": {", "\"666 Erebus St.\"", "\"Apt 8\"", "\"city\": \"Elysium\"", "\"country\": \"US\"", "\"organization\": \"Underworld\"", - "\"phone\": \"16502111111\"", "\"postalCode\": \"91111\"", + "\"phone\": \"+16502111111\"", + "\"postalCode\": \"91111\"", "\"recipient\": \"John H. Doe\"", "\"region\": \"CA\""}); }
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view_browsertest.cc b/chrome/browser/ui/views/profiles/profile_chooser_view_browsertest.cc index 9893a37..34df889 100644 --- a/chrome/browser/ui/views/profiles/profile_chooser_view_browsertest.cc +++ b/chrome/browser/ui/views/profiles/profile_chooser_view_browsertest.cc
@@ -13,6 +13,7 @@ #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" #include "base/test/histogram_tester.h" +#include "base/threading/thread_restrictions.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/extensions/extension_browsertest.h" @@ -41,6 +42,7 @@ namespace { Profile* CreateTestingProfile(const std::string& profile_name) { + base::ThreadRestrictions::ScopedAllowIO allow_io; ProfileManager* profile_manager = g_browser_process->profile_manager(); size_t starting_number_of_profiles = profile_manager->GetNumberOfProfiles(); @@ -59,6 +61,7 @@ } Profile* CreateProfileOutsideUserDataDir() { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath path; if (!base::CreateNewTempDirectory(base::FilePath::StringType(), &path)) NOTREACHED() << "Could not create directory at " << path.MaybeAsASCII(); @@ -73,6 +76,7 @@ // Set up the profiles to enable Lock. Takes as parameter a profile that will be // signed in, and also creates a supervised user (necessary for lock). void SetupProfilesForLock(Profile* signed_in) { + base::ThreadRestrictions::ScopedAllowIO allow_io; const char signed_in_email[] = "me@google.com"; // Set up the |signed_in| profile.
diff --git a/chrome/browser/ui/webui/cleanup_tool/cleanup_action_handler.cc b/chrome/browser/ui/webui/cleanup_tool/cleanup_action_handler.cc index e6bd13e7..d1e6bacc 100644 --- a/chrome/browser/ui/webui/cleanup_tool/cleanup_action_handler.cc +++ b/chrome/browser/ui/webui/cleanup_tool/cleanup_action_handler.cc
@@ -5,10 +5,10 @@ #include "chrome/browser/ui/webui/cleanup_tool/cleanup_action_handler.h" #include "base/bind.h" -#include "base/timer/timer.h" #include "base/values.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/component_updater/sw_reporter_installer_win.h" +#include "components/component_updater/component_updater_service.h" namespace { @@ -22,6 +22,18 @@ component_ids.end(); } +// TODO(proberge): Connect this to the Cleanup Tool manager class once that's +// implemented. +void StartScan(base::Closure callback) { + callback.Run(); +} + +// TODO(proberge): Connect this to the Cleanup Tool manager class once that's +// implemented. +void StartCleanup(base::Closure callback) { + callback.Run(); +} + // TODO(proberge): Localize strings once they are finalized. constexpr char kDetectionOkText[] = "No problems detected"; constexpr char kDetectionUwSText[] = "2 potentially harmful programs detected"; @@ -44,6 +56,9 @@ web_ui()->RegisterMessageCallback( "startScan", base::Bind(&CleanupActionHandler::HandleStartScan, base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "startCleanup", base::Bind(&CleanupActionHandler::HandleStartCleanup, + base::Unretained(this))); } void CleanupActionHandler::OnJavascriptDisallowed() { @@ -52,8 +67,8 @@ void CleanupActionHandler::HandleRequestLastScanResult( const base::ListValue* args) { - std::string webui_callback_id; CHECK_EQ(1U, args->GetSize()); + std::string webui_callback_id; bool success = args->GetString(0, &webui_callback_id); DCHECK(success); @@ -86,9 +101,9 @@ return; } - component_updater::RegisterUserInitiatedSwReporterScan( - base::Bind(&CleanupActionHandler::ReportScanResults, - callback_weak_ptr_factory_.GetWeakPtr(), webui_callback_id)); + StartScan(base::Bind(&CleanupActionHandler::ReportScanResults, + callback_weak_ptr_factory_.GetWeakPtr(), + webui_callback_id)); } void CleanupActionHandler::ReportScanResults(const std::string& callback_id) { @@ -102,3 +117,23 @@ AllowJavascript(); ResolveJavascriptCallback(base::Value(callback_id), scan_results); } + +void CleanupActionHandler::HandleStartCleanup(const base::ListValue* args) { + CHECK_EQ(1U, args->GetSize()); + std::string webui_callback_id; + bool success = args->GetString(0, &webui_callback_id); + DCHECK(success); + + StartCleanup(base::Bind(&CleanupActionHandler::ReportCleanupResults, + base::Unretained(this), webui_callback_id)); +} + +void CleanupActionHandler::ReportCleanupResults( + const std::string& callback_id) { + base::DictionaryValue cleanup_results; + // TODO(proberge): Return real information about the cleanup. + cleanup_results.SetBoolean("wasCancelled", true); + cleanup_results.SetBoolean("requiresReboot", false); + + ResolveJavascriptCallback(base::Value(callback_id), cleanup_results); +}
diff --git a/chrome/browser/ui/webui/cleanup_tool/cleanup_action_handler.h b/chrome/browser/ui/webui/cleanup_tool/cleanup_action_handler.h index 894fc45..97c87f0 100644 --- a/chrome/browser/ui/webui/cleanup_tool/cleanup_action_handler.h +++ b/chrome/browser/ui/webui/cleanup_tool/cleanup_action_handler.h
@@ -8,7 +8,6 @@ #include "base/callback.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "components/component_updater/component_updater_service.h" #include "content/public/browser/web_ui_message_handler.h" // The handler for Javascript messages related to the "Chrome Cleanup" view. @@ -26,11 +25,16 @@ void HandleRequestLastScanResult(const base::ListValue* args); void HandleStartScan(const base::ListValue* args); + void HandleStartCleanup(const base::ListValue* args); // Returns the scan result initiated by HandleStartScan() to the Javascript // caller refererenced by |callback_id|. void ReportScanResults(const std::string& callback_id); + // Returns the cleanup result initiated by HandleStartCleanup() to the + // Javascript caller refererenced by |callback_id|. + void ReportCleanupResults(const std::string& callback_id); + // Used to cancel callbacks when JavaScript becomes disallowed. base::WeakPtrFactory<CleanupActionHandler> callback_weak_ptr_factory_;
diff --git a/chrome/browser/ui/webui/cleanup_tool/cleanup_tool_ui.cc b/chrome/browser/ui/webui/cleanup_tool/cleanup_tool_ui.cc index ee09615..c227104 100644 --- a/chrome/browser/ui/webui/cleanup_tool/cleanup_tool_ui.cc +++ b/chrome/browser/ui/webui/cleanup_tool/cleanup_tool_ui.cc
@@ -20,6 +20,7 @@ html_source->AddString("sectionHeader", "Remove suspicious or unwanted programs"); html_source->AddString("scanAction", "Scan Now"); + html_source->AddString("cleaning", "Cleaning"); html_source->AddString("scanning", "Scanning"); html_source->AddString("cleanAction", "Run Chrome Cleanup"); html_source->AddString("about", "About Chrome Cleanup");
diff --git a/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc b/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc index b9b21f5..f0ce3fa 100644 --- a/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc +++ b/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc
@@ -16,6 +16,7 @@ #include "base/strings/string_split.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" #include "base/values.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/io_thread.h" @@ -290,6 +291,7 @@ void NetInternalsTest::MessageHandler::GetNetLogFileContents( const base::ListValue* list_value) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temp_directory; ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); base::FilePath temp_file;
diff --git a/chrome/browser/ui/webui/policy_ui_browsertest.cc b/chrome/browser/ui/webui/policy_ui_browsertest.cc index c6ed1f25..5514daf 100644 --- a/chrome/browser/ui/webui/policy_ui_browsertest.cc +++ b/chrome/browser/ui/webui/policy_ui_browsertest.cc
@@ -14,6 +14,7 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/run_loop.h" +#include "base/threading/thread_restrictions.h" #include "base/values.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/test_extension_system.h" @@ -280,6 +281,7 @@ IN_PROC_BROWSER_TEST_F(PolicyUITest, ExtensionLoadAndSendPolicy) { ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIPolicyURL)); + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temp_dir_; ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
diff --git a/chrome/browser/ui/webui/test_files_request_filter.cc b/chrome/browser/ui/webui/test_files_request_filter.cc index 4c69de5..2d52912 100644 --- a/chrome/browser/ui/webui/test_files_request_filter.cc +++ b/chrome/browser/ui/webui/test_files_request_filter.cc
@@ -9,6 +9,7 @@ #include "base/memory/ref_counted_memory.h" #include "base/path_service.h" #include "base/strings/string_split.h" +#include "base/threading/thread_restrictions.h" #include "chrome/common/chrome_paths.h" namespace { @@ -16,6 +17,7 @@ bool HandleTestFileRequestCallback( const std::string& path, const content::WebUIDataSource::GotDataCallback& callback) { + base::ThreadRestrictions::ScopedAllowIO allow_io; std::vector<std::string> url_substr = base::SplitString(path, "/", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); if (url_substr.size() != 2 || url_substr[0] != "test")
diff --git a/chrome/renderer/resources/extensions/media_router_bindings.js b/chrome/renderer/resources/extensions/media_router_bindings.js index 1bd47e01..4eac395 100644 --- a/chrome/renderer/resources/extensions/media_router_bindings.js +++ b/chrome/renderer/resources/extensions/media_router_bindings.js
@@ -933,7 +933,7 @@ this.handlers_.onBeforeInvokeHandler(); return this.handlers_ .createMediaRouteController(routeId, controllerRequest, observer) - .then(() => {success: true}, e => {success: false}); + .then(() => ({success: true}), e => ({success: false})); }; mediaRouter = new MediaRouter(new mediaRouterMojom.MediaRouterPtr(
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 961fd6b..d2ccf4f 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -619,6 +619,8 @@ "../browser/chromeos/login/screenshot_testing/SkImageDiffer.h", "../browser/chromeos/login/screenshot_testing/SkPMetric.cpp", "../browser/chromeos/login/screenshot_testing/SkPMetric.h", + "../browser/chromeos/login/screenshot_testing/SkPMetricUtil_gen.h", + "../browser/chromeos/login/screenshot_testing/login_screen_areas.h", "../browser/chromeos/login/screenshot_testing/screenshot_tester.cc", "../browser/chromeos/login/screenshot_testing/screenshot_tester.h", "../browser/chromeos/login/screenshot_testing/screenshot_testing_mixin.cc",
diff --git a/chrome/test/base/in_process_browser_test.cc b/chrome/test/base/in_process_browser_test.cc index 867c5ca5..19b7c7b 100644 --- a/chrome/test/base/in_process_browser_test.cc +++ b/chrome/test/base/in_process_browser_test.cc
@@ -299,6 +299,7 @@ } bool InProcessBrowserTest::RunAccessibilityChecks(std::string* error_message) { + base::ThreadRestrictions::ScopedAllowIO allow_io; if (!browser()) { *error_message = "browser is NULL"; return false;
diff --git a/chrome/test/base/javascript_browser_test.cc b/chrome/test/base/javascript_browser_test.cc index c70778b..e1f1829e 100644 --- a/chrome/test/base/javascript_browser_test.cc +++ b/chrome/test/base/javascript_browser_test.cc
@@ -7,6 +7,7 @@ #include "base/memory/ptr_util.h" #include "base/path_service.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" #include "chrome/common/chrome_paths.h" #include "content/public/browser/web_ui.h" #include "ui/base/resource/resource_bundle.h" @@ -66,6 +67,7 @@ // calls. void JavaScriptBrowserTest::BuildJavascriptLibraries( std::vector<base::string16>* libraries) { + base::ThreadRestrictions::ScopedAllowIO allow_io; ASSERT_TRUE(libraries != NULL); std::vector<base::FilePath>::iterator user_libraries_iterator; for (user_libraries_iterator = user_libraries_.begin();
diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc index edeed785..c43d29f 100644 --- a/chrome/test/base/testing_profile.cc +++ b/chrome/test/base/testing_profile.cc
@@ -16,6 +16,7 @@ #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/strings/string_number_conversions.h" +#include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "chrome/browser/autocomplete/in_memory_url_index_factory.h" @@ -391,6 +392,7 @@ } void TestingProfile::CreateTempProfileDir() { + base::ThreadRestrictions::ScopedAllowIO allow_io; if (!temp_dir_.CreateUniqueTempDir()) { LOG(ERROR) << "Failed to create unique temporary directory."; @@ -418,6 +420,7 @@ } void TestingProfile::Init() { + base::ThreadRestrictions::ScopedAllowIO allow_io; // If threads have been initialized, we should be on the UI thread. DCHECK(!content::BrowserThread::IsThreadInitialized( content::BrowserThread::UI) || @@ -561,6 +564,9 @@ resource_context_ = NULL; content::RunAllPendingInMessageLoop(BrowserThread::IO); } + + base::ThreadRestrictions::ScopedAllowIO allow_io; + ignore_result(temp_dir_.Delete()); } void TestingProfile::CreateFaviconService() {
diff --git a/chrome/test/base/ui_test_utils.cc b/chrome/test/base/ui_test_utils.cc index d74c337f..dbfc6b7f 100644 --- a/chrome/test/base/ui_test_utils.cc +++ b/chrome/test/base/ui_test_utils.cc
@@ -19,6 +19,7 @@ #include "base/path_service.h" #include "base/strings/utf_string_conversions.h" #include "base/test/test_timeouts.h" +#include "base/threading/thread_restrictions.h" #include "base/time/time.h" #include "build/build_config.h" #include "chrome/browser/bookmarks/bookmark_model_factory.h" @@ -281,6 +282,7 @@ base::FilePath GetTestFilePath(const base::FilePath& dir, const base::FilePath& file) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath path; PathService::Get(chrome::DIR_TEST_DATA, &path); return path.Append(dir).Append(file); @@ -291,6 +293,7 @@ } bool GetRelativeBuildDirectory(base::FilePath* build_dir) { + base::ThreadRestrictions::ScopedAllowIO allow_io; // This function is used to find the build directory so TestServer can serve // built files (nexes, etc). TestServer expects a path relative to the source // root. @@ -363,6 +366,7 @@ } void DownloadURL(Browser* browser, const GURL& download_url) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir downloads_directory; ASSERT_TRUE(downloads_directory.CreateUniqueTempDir()); browser->profile()->GetPrefs()->SetFilePath(prefs::kDownloadDefaultDirectory,
diff --git a/chrome/test/base/web_ui_browser_test.cc b/chrome/test/base/web_ui_browser_test.cc index 2313b2c..755e38d 100644 --- a/chrome/test/base/web_ui_browser_test.cc +++ b/chrome/test/base/web_ui_browser_test.cc
@@ -15,6 +15,7 @@ #include "base/path_service.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" #include "base/values.h" #include "chrome/browser/chrome_content_browser_client.h" #include "chrome/browser/profiles/profile.h" @@ -493,6 +494,7 @@ GURL WebUIBrowserTest::WebUITestDataPathToURL( const base::FilePath::StringType& path) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath dir_test_data; EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &dir_test_data)); base::FilePath test_path(dir_test_data.Append(kWebUITestFolder).Append(path));
diff --git a/chrome/test/data/android/webvr_instrumentation/html/test_screen_taps_registered_on_cardboard.html b/chrome/test/data/android/webvr_instrumentation/html/test_screen_taps_registered.html similarity index 80% rename from chrome/test/data/android/webvr_instrumentation/html/test_screen_taps_registered_on_cardboard.html rename to chrome/test/data/android/webvr_instrumentation/html/test_screen_taps_registered.html index e74d5f6..6e53492 100644 --- a/chrome/test/data/android/webvr_instrumentation/html/test_screen_taps_registered_on_cardboard.html +++ b/chrome/test/data/android/webvr_instrumentation/html/test_screen_taps_registered.html
@@ -1,7 +1,8 @@ <!doctype html> <!-- -Tests that screen taps are registered while in VR when viewer is -Cardboard +Tests that either screen taps are registered in VR when viewer is Cardboard +or that controller clicks are registered as screen taps in VR when viewer is +Daydream View. --> <html> <head> @@ -13,7 +14,7 @@ <script src="../resources/webvr_e2e.js"></script> <script src="../resources/webvr_boilerplate.js"></script> <script> - var t = async_test("Screen taps registered when in VR w/ Cardboard"); + var t = async_test("Screen taps/clicks registered when in VR"); window.addEventListener("vrdisplaypresentchange", () => {finishJavaScriptStep();}, false); var numTaps = 0;
diff --git a/chrome/test/data/webui/settings/cr_settings_browsertest.js b/chrome/test/data/webui/settings/cr_settings_browsertest.js index bd9d622..74a26091 100644 --- a/chrome/test/data/webui/settings/cr_settings_browsertest.js +++ b/chrome/test/data/webui/settings/cr_settings_browsertest.js
@@ -1138,7 +1138,7 @@ }; // Failing on ChromiumOS dbg. https://crbug.com/709442 -GEN('#if defined(OS_CHROMEOS) && !defined(NDEBUG)'); +GEN('#if (defined(OS_WIN) || defined(OS_CHROMEOS)) && !defined(NDEBUG)'); GEN('#define MAYBE_All DISABLED_All'); GEN('#else'); GEN('#define MAYBE_All All');
diff --git a/chrome/test/data/webui/settings/site_settings_page_browsertest.js b/chrome/test/data/webui/settings/site_settings_page_browsertest.js index 0b9ade75..fc4929e 100644 --- a/chrome/test/data/webui/settings/site_settings_page_browsertest.js +++ b/chrome/test/data/webui/settings/site_settings_page_browsertest.js
@@ -16,7 +16,7 @@ }; // Failing on ChromiumOS dbg. https://crbug.com/709442 -GEN('#if defined(OS_CHROMEOS) && !defined(NDEBUG)'); +GEN('#if (defined(OS_WIN) || defined(OS_CHROMEOS)) && !defined(NDEBUG)'); GEN('#define MAYBE_labels DISABLED_labels'); GEN('#else'); GEN('#define MAYBE_labels labels');
diff --git a/chrome/test/ppapi/ppapi_browsertest.cc b/chrome/test/ppapi/ppapi_browsertest.cc index bcf0a4a..5eb35753 100644 --- a/chrome/test/ppapi/ppapi_browsertest.cc +++ b/chrome/test/ppapi/ppapi_browsertest.cc
@@ -7,6 +7,7 @@ #include "base/macros.h" #include "base/path_service.h" #include "base/test/test_timeouts.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/extensions/extension_browsertest.h" @@ -1259,7 +1260,10 @@ void LaunchTestingApp(const std::string& extension_dirname) { base::FilePath data_dir; - ASSERT_TRUE(PathService::Get(chrome::DIR_GEN_TEST_DATA, &data_dir)); + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + ASSERT_TRUE(PathService::Get(chrome::DIR_GEN_TEST_DATA, &data_dir)); + } base::FilePath app_dir = data_dir.AppendASCII("ppapi") .AppendASCII("tests") .AppendASCII("extensions")
diff --git a/chrome/test/ppapi/ppapi_filechooser_browsertest.cc b/chrome/test/ppapi/ppapi_filechooser_browsertest.cc index ae3c0a628..897e15b 100644 --- a/chrome/test/ppapi/ppapi_filechooser_browsertest.cc +++ b/chrome/test/ppapi/ppapi_filechooser_browsertest.cc
@@ -11,6 +11,7 @@ #include "base/files/scoped_temp_dir.h" #include "base/strings/string_piece.h" #include "base/strings/string_util.h" +#include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/common/chrome_switches.h" #include "chrome/test/ppapi/ppapi_test.h" @@ -270,6 +271,7 @@ IN_PROC_BROWSER_TEST_F(PPAPIFileChooserTest, FileChooser_Open_Success) { const char kContents[] = "Hello from browser"; + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); @@ -294,6 +296,7 @@ } IN_PROC_BROWSER_TEST_F(PPAPIFileChooserTest, FileChooser_SaveAs_Success) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); base::FilePath suggested_filename = temp_dir.GetPath().AppendASCII("foo"); @@ -310,6 +313,7 @@ IN_PROC_BROWSER_TEST_F(PPAPIFileChooserTest, FileChooser_SaveAs_SafeDefaultName) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); base::FilePath suggested_filename = temp_dir.GetPath().AppendASCII("foo"); @@ -332,6 +336,7 @@ IN_PROC_BROWSER_TEST_F(PPAPIFileChooserTest, FileChooser_SaveAs_UnsafeDefaultName) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); base::FilePath suggested_filename = temp_dir.GetPath().AppendASCII("foo"); @@ -366,6 +371,7 @@ // file is created. This MOTW prevents the file being opened without due // security warnings if the file is executable. IN_PROC_BROWSER_TEST_F(PPAPIFileChooserTest, FileChooser_Quarantine) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); base::FilePath suggested_filename = temp_dir.GetPath().AppendASCII("foo"); @@ -392,6 +398,7 @@ IN_PROC_BROWSER_TEST_F(PPAPIFileChooserTestWithSBService, FileChooser_SaveAs_DangerousExecutable_Allowed) { + base::ThreadRestrictions::ScopedAllowIO allow_io; safe_browsing_test_configuration_.default_result = DownloadProtectionService::DANGEROUS; safe_browsing_test_configuration_.result_map.insert(
diff --git a/chrome/test/ppapi/ppapi_test.cc b/chrome/test/ppapi/ppapi_test.cc index 250c0bc..9ec1b00 100644 --- a/chrome/test/ppapi/ppapi_test.cc +++ b/chrome/test/ppapi/ppapi_test.cc
@@ -13,6 +13,7 @@ #include "base/single_thread_task_runner.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" +#include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "chrome/browser/chrome_notification_types.h" @@ -153,6 +154,7 @@ } GURL PPAPITestBase::GetTestFileUrl(const std::string& test_case) { + base::ThreadRestrictions::ScopedAllowIO allow_io_for_test_setup; base::FilePath test_path; EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &test_path)); test_path = test_path.Append(FILE_PATH_LITERAL("ppapi"));
diff --git a/chrome/test/remoting/qunit_browser_test_runner.cc b/chrome/test/remoting/qunit_browser_test_runner.cc index c309649..b84a30a 100644 --- a/chrome/test/remoting/qunit_browser_test_runner.cc +++ b/chrome/test/remoting/qunit_browser_test_runner.cc
@@ -6,6 +6,7 @@ #include "base/files/file_util.h" #include "base/json/json_reader.h" +#include "base/threading/thread_restrictions.h" #include "base/values.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -39,8 +40,11 @@ } void QUnitBrowserTestRunner::RunTest(const base::FilePath& file) { - ASSERT_TRUE(PathExists(file)) << "Error: The QUnit test suite <" - << file.value() << "> does not exist."; + { + base::ThreadRestrictions::ScopedAllowIO allow_io; + ASSERT_TRUE(PathExists(file)) << "Error: The QUnit test suite <" + << file.value() << "> does not exist."; + } ui_test_utils::NavigateToURL(browser(), net::FilePathToFileURL(file)); content::WebContents* web_contents =
diff --git a/chromecast/public/media/media_pipeline_backend.h b/chromecast/public/media/media_pipeline_backend.h index e6ef3c9..1f346a3 100644 --- a/chromecast/public/media/media_pipeline_backend.h +++ b/chromecast/public/media/media_pipeline_backend.h
@@ -136,7 +136,8 @@ // Returns the pipeline latency: i.e. the amount of data // in the pipeline that have not been rendered yet, in microseconds. - // Returns delay = INT64_MIN if the latency is not available. + // Returns a RenderingDelay.timestamp = INT64_MIN if the latency is not + // available. // Only called when the backend is playing. virtual RenderingDelay GetRenderingDelay() = 0;
diff --git a/chromecast/renderer/media/key_systems_cast.cc b/chromecast/renderer/media/key_systems_cast.cc index 1e29715..df31180a 100644 --- a/chromecast/renderer/media/key_systems_cast.cc +++ b/chromecast/renderer/media/key_systems_cast.cc
@@ -49,6 +49,12 @@ #if BUILDFLAG(ENABLE_HEVC_DEMUXING) codecs |= ::media::EME_CODEC_MP4_HEVC; #endif +#if BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING) + codecs |= ::media::EME_CODEC_MP4_DV_AVC; +#if BUILDFLAG(ENABLE_HEVC_DEMUXING) + codecs |= ::media::EME_CODEC_MP4_DV_HEVC; +#endif +#endif return codecs; } @@ -111,6 +117,12 @@ #if BUILDFLAG(ENABLE_HEVC_DEMUXING) codecs |= ::media::EME_CODEC_MP4_HEVC; #endif +#if BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING) + codecs |= ::media::EME_CODEC_MP4_DV_AVC; +#if BUILDFLAG(ENABLE_HEVC_DEMUXING) + codecs |= ::media::EME_CODEC_MP4_DV_HEVC; +#endif +#endif key_systems_properties->emplace_back(new cdm::WidevineKeySystemProperties( codecs, // Regular codecs. Robustness::HW_SECURE_ALL, // Max audio robustness.
diff --git a/components/autofill/core/browser/data_driven_test.cc b/components/autofill/core/browser/data_driven_test.cc index c339758..e778a8a7 100644 --- a/components/autofill/core/browser/data_driven_test.cc +++ b/components/autofill/core/browser/data_driven_test.cc
@@ -7,6 +7,7 @@ #include "base/files/file_enumerator.h" #include "base/files/file_util.h" #include "base/strings/string_util.h" +#include "base/threading/thread_restrictions.h" #include "testing/gtest/include/gtest/gtest.h" namespace autofill { @@ -35,6 +36,7 @@ const base::FilePath& input_directory, const base::FilePath& output_directory, const base::FilePath::StringType& file_name_pattern) { + base::ThreadRestrictions::ScopedAllowIO allow_io; ASSERT_TRUE(base::DirectoryExists(input_directory)); ASSERT_TRUE(base::DirectoryExists(output_directory)); base::FileEnumerator input_files(input_directory, @@ -52,6 +54,7 @@ void DataDrivenTest::RunOneDataDrivenTest( const base::FilePath& test_file_name, const base::FilePath& output_directory) { + base::ThreadRestrictions::ScopedAllowIO allow_io; // iOS doesn't get rid of removed test files. TODO(estade): remove this after // all iOS bots are clobbered. if (test_file_name.BaseName().value() == FILE_PATH_LITERAL("multimerge.in")) @@ -64,7 +67,9 @@ ReadFile(test_file_name, &input); std::string output; + base::ThreadRestrictions::SetIOAllowed(false); GenerateResults(input, &output); + base::ThreadRestrictions::SetIOAllowed(true); base::FilePath output_file = output_directory.Append( test_file_name.BaseName().StripTrailingSeparators().ReplaceExtension(
diff --git a/components/cdm/browser/cdm_message_filter_android.cc b/components/cdm/browser/cdm_message_filter_android.cc index 849b716..4d7e99d 100644 --- a/components/cdm/browser/cdm_message_filter_android.cc +++ b/components/cdm/browser/cdm_message_filter_android.cc
@@ -41,6 +41,12 @@ #if BUILDFLAG(ENABLE_HEVC_DEMUXING) {media::EME_CODEC_MP4_HEVC, media::kCodecHEVC, "video/mp4"}, #endif +#if BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING) + {media::EME_CODEC_MP4_DV_AVC, media::kCodecDolbyVision, "video/mp4"}, +#if BUILDFLAG(ENABLE_HEVC_DEMUXING) + {media::EME_CODEC_MP4_DV_HEVC, media::kCodecDolbyVision, "video/mp4"}, +#endif +#endif #endif // BUILDFLAG(USE_PROPRIETARY_CODECS) };
diff --git a/components/cronet/ios/Cronet.h b/components/cronet/ios/Cronet.h index 4a29721..f7f6cbe 100644 --- a/components/cronet/ios/Cronet.h +++ b/components/cronet/ios/Cronet.h
@@ -52,6 +52,11 @@ // before |start| is called. + (void)addQuicHint:(NSString*)host port:(int)port altPort:(int)altPort; +// Set experimental Cronet options. Argument is a JSON string; see +// |URLRequestContextConfig| for more details. This method only has +// any effect before |start| is called. ++ (void)setExperimentalOptions:(NSString*)experimentalOptions; + // Sets the User-Agent request header string to be sent with all requests. // If |partial| is set to YES, then actual user agent value is based on device // model, OS version, and |userAgent| argument. For example "Foo/3.0.0.0" is
diff --git a/components/cronet/ios/Cronet.mm b/components/cronet/ios/Cronet.mm index b883049..3adc491 100644 --- a/components/cronet/ios/Cronet.mm +++ b/components/cronet/ios/Cronet.mm
@@ -37,6 +37,7 @@ cronet::URLRequestContextConfig::HttpCacheType gHttpCache = cronet::URLRequestContextConfig::HttpCacheType::DISK; ScopedVector<cronet::URLRequestContextConfig::QuicHint> gQuicHints; +NSString* gExperimentalOptions = @"{}"; NSString* gUserAgent = nil; BOOL gUserAgentPartial = NO; NSString* gSslKeyLogFileName = nil; @@ -168,6 +169,11 @@ base::SysNSStringToUTF8(host), port, altPort)); } ++ (void)setExperimentalOptions:(NSString*)experimentalOptions { + [self checkNotStarted]; + gExperimentalOptions = experimentalOptions; +} + + (void)setUserAgent:(NSString*)userAgent partial:(BOOL)partial { [self checkNotStarted]; gUserAgent = userAgent; @@ -176,7 +182,7 @@ + (void)setSslKeyLogFileName:(NSString*)sslKeyLogFileName { [self checkNotStarted]; - gSslKeyLogFileName = sslKeyLogFileName; + gSslKeyLogFileName = [self getNetLogPathForFile:sslKeyLogFileName]; } + (void)setHttpCacheType:(CRNHttpCacheType)httpCacheType { @@ -213,6 +219,8 @@ gChromeNet.Get()->set_http2_enabled(gHttp2Enabled); gChromeNet.Get()->set_quic_enabled(gQuicEnabled); + gChromeNet.Get()->set_experimental_options( + base::SysNSStringToUTF8(gExperimentalOptions)); gChromeNet.Get()->set_http_cache(gHttpCache); gChromeNet.Get()->set_ssl_key_log_file_name( base::SysNSStringToUTF8(gSslKeyLogFileName));
diff --git a/components/cronet/ios/cronet_environment.h b/components/cronet/ios/cronet_environment.h index 59cb796..a419c2b 100644 --- a/components/cronet/ios/cronet_environment.h +++ b/components/cronet/ios/cronet_environment.h
@@ -91,6 +91,10 @@ http_cache_ = http_cache; } + void set_experimental_options(const std::string& experimental_options) { + experimental_options_ = experimental_options; + } + void SetHostResolverRules(const std::string& host_resolver_rules); void set_ssl_key_log_file_name(const std::string& ssl_key_log_file_name) { @@ -134,6 +138,7 @@ bool quic_enabled_; std::string quic_user_agent_id_; std::string accept_language_; + std::string experimental_options_; std::string ssl_key_log_file_name_; URLRequestContextConfig::HttpCacheType http_cache_;
diff --git a/components/cronet/ios/cronet_environment.mm b/components/cronet/ios/cronet_environment.mm index 651af1d..408fa0e 100644 --- a/components/cronet/ios/cronet_environment.mm +++ b/components/cronet/ios/cronet_environment.mm
@@ -266,12 +266,9 @@ static bool ssl_key_log_file_set = false; if (!ssl_key_log_file_set && !ssl_key_log_file_name_.empty()) { ssl_key_log_file_set = true; - base::FilePath ssl_key_log_file; - if (!PathService::Get(base::DIR_HOME, &ssl_key_log_file)) - return; - net::SSLClientSocket::SetSSLKeyLogFile( - ssl_key_log_file.Append(ssl_key_log_file_name_), - file_thread_->task_runner()); + base::FilePath ssl_key_log_file(ssl_key_log_file_name_); + net::SSLClientSocket::SetSSLKeyLogFile(ssl_key_log_file, + file_thread_->task_runner()); } if (user_agent_partial_) @@ -291,6 +288,8 @@ cache_path.value(); // Storage path for http cache and cookie storage. context_config_builder.user_agent = user_agent_; // User-Agent request header field. + context_config_builder.experimental_options = + experimental_options_; // Set experimental Cronet options. context_config_builder.mock_cert_verifier = std::move( mock_cert_verifier_); // MockCertVerifier to use for testing purposes. std::unique_ptr<URLRequestContextConfig> config =
diff --git a/components/cronet/ios/test/cronet_http_test.mm b/components/cronet/ios/test/cronet_http_test.mm index 5818508..b83a8a1 100644 --- a/components/cronet/ios/test/cronet_http_test.mm +++ b/components/cronet/ios/test/cronet_http_test.mm
@@ -174,6 +174,17 @@ base::scoped_nsobject<TestDelegate> delegate_; }; +TEST_F(HttpTest, CreateFile) { + bool ssl_file_created = [[NSFileManager defaultManager] + fileExistsAtPath:[Cronet getNetLogPathForFile:@"SSLKEYLOGFILE"]]; + + [[NSFileManager defaultManager] + removeItemAtPath:[Cronet getNetLogPathForFile:@"SSLKEYLOGFILE"] + error:nil]; + + EXPECT_TRUE(ssl_file_created); +} + TEST_F(HttpTest, NSURLSessionReceivesData) { NSURL* url = net::NSURLWithGURL(GURL(grpc_support::kTestServerSimpleUrl)); __block BOOL block_used = NO;
diff --git a/components/cronet/ios/test/start_cronet.mm b/components/cronet/ios/test/start_cronet.mm index ca3a8998..f7eee77 100644 --- a/components/cronet/ios/test/start_cronet.mm +++ b/components/cronet/ios/test/start_cronet.mm
@@ -21,7 +21,12 @@ [Cronet setHttp2Enabled:true]; [Cronet setQuicEnabled:true]; [Cronet setAcceptLanguages:@"en-US,en"]; - [Cronet setSslKeyLogFileName:@"SSLKEYLOGFILE"]; + [Cronet + setExperimentalOptions: + [NSString + stringWithFormat:@"{\"ssl_key_log_file\":\"%@\"}", + [Cronet + getNetLogPathForFile:@"SSLKEYLOGFILE"]]]; [Cronet addQuicHint:@"test.example.com" port:443 altPort:443]; [Cronet enableTestCertVerifierForTesting]; [Cronet setHttpCacheType:CRNHttpCacheTypeDisabled];
diff --git a/components/drive/service/fake_drive_service.cc b/components/drive/service/fake_drive_service.cc index 9f06ff8..662557b4 100644 --- a/components/drive/service/fake_drive_service.cc +++ b/components/drive/service/fake_drive_service.cc
@@ -22,6 +22,7 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" #include "base/values.h" #include "components/drive/drive_api_util.h" @@ -813,6 +814,7 @@ const DownloadActionCallback& download_action_callback, const GetContentCallback& get_content_callback, const ProgressCallback& progress_callback) { + base::ThreadRestrictions::ScopedAllowIO allow_io; DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(!download_action_callback.is_null());
diff --git a/components/exo/wm_helper_ash.cc b/components/exo/wm_helper_ash.cc index 4460612..a7ae496 100644 --- a/components/exo/wm_helper_ash.cc +++ b/components/exo/wm_helper_ash.cc
@@ -13,7 +13,7 @@ #include "base/memory/singleton.h" #include "ui/aura/client/focus_client.h" #include "ui/display/manager/display_manager.h" -#include "ui/events/devices/device_data_manager.h" +#include "ui/events/devices/input_device_manager.h" #include "ui/wm/public/activation_client.h" namespace exo { @@ -31,9 +31,7 @@ aura::client::FocusClient* focus_client = aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow()); focus_client->AddObserver(this); - // TODO(crbug.com/709225): Mushrome doesn't have a DeviceDataManager. - if (ash::ShellPort::Get()->GetAshConfig() != ash::Config::MUS) - ui::DeviceDataManager::GetInstance()->AddObserver(this); + ui::InputDeviceManager::GetInstance()->AddObserver(this); ash::Shell::Get()->system_tray_notifier()->AddAccessibilityObserver(this); } @@ -49,9 +47,7 @@ ash::Shell::Get()->cursor_manager()->RemoveObserver(this); ash::Shell::Get()->activation_client()->RemoveObserver(this); ash::Shell::Get()->RemoveShellObserver(this); - // TODO(crbug.com/709225): Mushrome doesn't have a DeviceDataManager. - if (ash::ShellPort::Get()->GetAshConfig() != ash::Config::MUS) - ui::DeviceDataManager::GetInstance()->RemoveObserver(this); + ui::InputDeviceManager::GetInstance()->RemoveObserver(this); ash::Shell::Get()->system_tray_notifier()->RemoveAccessibilityObserver(this); }
diff --git a/components/payments/content/payment_response_helper.h b/components/payments/content/payment_response_helper.h index fde039d7..83a66aa 100644 --- a/components/payments/content/payment_response_helper.h +++ b/components/payments/content/payment_response_helper.h
@@ -20,7 +20,7 @@ // before adding them to the PaymentResponse. // A helper class to facilitate the creation of the PaymentResponse. class PaymentResponseHelper : public PaymentInstrument::Delegate, - AddressNormalizer::Delegate { + public AddressNormalizer::Delegate { public: class Delegate { public:
diff --git a/components/payments/content/payment_response_helper_unittest.cc b/components/payments/content/payment_response_helper_unittest.cc index 658ffac..e1c6f93 100644 --- a/components/payments/content/payment_response_helper_unittest.cc +++ b/components/payments/content/payment_response_helper_unittest.cc
@@ -24,6 +24,8 @@ namespace payments { +namespace { + class FakeAddressNormalizer : public AddressNormalizer { public: FakeAddressNormalizer() {} @@ -53,6 +55,7 @@ : personal_data_manager_(personal_data_manager), locale_("en-US"), last_committed_url_("https://shop.com") {} + void ShowDialog(PaymentRequest* request) override {} void CloseDialog() override {} @@ -95,6 +98,8 @@ DISALLOW_COPY_AND_ASSIGN(FakePaymentRequestDelegate); }; +} // namespace + class PaymentResponseHelperTest : public testing::Test, public PaymentResponseHelper::Delegate { protected:
diff --git a/components/payments/core/autofill_payment_instrument.cc b/components/payments/core/autofill_payment_instrument.cc index 04017e4..e74b389 100644 --- a/components/payments/core/autofill_payment_instrument.cc +++ b/components/payments/core/autofill_payment_instrument.cc
@@ -7,9 +7,11 @@ #include "base/json/json_writer.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" +#include "components/autofill/core/browser/autofill_country.h" #include "components/autofill/core/browser/autofill_data_util.h" #include "components/autofill/core/browser/autofill_type.h" #include "components/autofill/core/browser/field_types.h" +#include "components/autofill/core/browser/personal_data_manager.h" #include "components/autofill/core/browser/validation.h" #include "components/autofill/core/common/autofill_clock.h" #include "components/payments/core/basic_card_response.h" @@ -50,6 +52,31 @@ DCHECK(!delegate_); delegate_ = delegate; + // Get the billing address. + // TODO(crbug.com/709776): Make sure the billing address is valid before + // getting here. + if (!credit_card_.billing_address_id().empty()) { + autofill::AutofillProfile* billing_address = + autofill::PersonalDataManager::GetProfileFromProfilesByGUID( + credit_card_.billing_address_id(), billing_profiles_); + if (billing_address) + billing_address_ = *billing_address; + } + + is_waiting_for_billing_address_normalization_ = true; + is_waiting_for_card_unmask_ = true; + + // Start the normalization of the billing address. + // Use the country code from the profile if it is set, otherwise infer it + // from the |app_locale_|. + std::string country_code = base::UTF16ToUTF8( + billing_address_.GetRawInfo(autofill::ADDRESS_HOME_COUNTRY)); + if (!autofill::data_util::IsValidCountryCode(country_code)) { + country_code = autofill::AutofillCountry::CountryCodeForLocale(app_locale_); + } + payment_request_delegate_->GetAddressNormalizer()->StartAddressNormalization( + billing_address_, country_code, /*timeout_seconds=*/5, this); + payment_request_delegate_->DoFullCardRequest(credit_card_, weak_ptr_factory_.GetWeakPtr()); } @@ -78,14 +105,11 @@ const base::string16& cvc) { DCHECK(delegate_); credit_card_ = card; - std::unique_ptr<base::DictionaryValue> response_value = - payments::data_util::GetBasicCardResponseFromAutofillCreditCard( - credit_card_, cvc, billing_profiles_, app_locale_) - .ToDictionaryValue(); - std::string stringified_details; - base::JSONWriter::Write(*response_value, &stringified_details); - delegate_->OnInstrumentDetailsReady(method_name(), stringified_details); - delegate_ = nullptr; + cvc_ = cvc; + is_waiting_for_card_unmask_ = false; + + if (!is_waiting_for_billing_address_normalization_) + GenerateBasicCardResponse(); } void AutofillPaymentInstrument::OnFullCardRequestFailed() { @@ -93,4 +117,39 @@ delegate_ = nullptr; } +void AutofillPaymentInstrument::OnAddressNormalized( + const autofill::AutofillProfile& normalized_profile) { + DCHECK(is_waiting_for_billing_address_normalization_); + + billing_address_ = normalized_profile; + is_waiting_for_billing_address_normalization_ = false; + + if (!is_waiting_for_card_unmask_) + GenerateBasicCardResponse(); +} + +void AutofillPaymentInstrument::OnCouldNotNormalize( + const autofill::AutofillProfile& profile) { + // Since the phone number is formatted in either case, this profile should be + // used. + OnAddressNormalized(profile); +} + +void AutofillPaymentInstrument::GenerateBasicCardResponse() { + DCHECK(!is_waiting_for_billing_address_normalization_); + DCHECK(!is_waiting_for_card_unmask_); + DCHECK(delegate_); + + std::unique_ptr<base::DictionaryValue> response_value = + payments::data_util::GetBasicCardResponseFromAutofillCreditCard( + credit_card_, cvc_, billing_address_, app_locale_) + .ToDictionaryValue(); + std::string stringified_details; + base::JSONWriter::Write(*response_value, &stringified_details); + delegate_->OnInstrumentDetailsReady(method_name(), stringified_details); + + delegate_ = nullptr; + cvc_ = base::UTF8ToUTF16(""); +} + } // namespace payments
diff --git a/components/payments/core/autofill_payment_instrument.h b/components/payments/core/autofill_payment_instrument.h index c0e49215..315e07e 100644 --- a/components/payments/core/autofill_payment_instrument.h +++ b/components/payments/core/autofill_payment_instrument.h
@@ -10,14 +10,12 @@ #include <vector> #include "base/macros.h" +#include "components/autofill/core/browser/autofill_profile.h" #include "components/autofill/core/browser/credit_card.h" #include "components/autofill/core/browser/payments/full_card_request.h" +#include "components/payments/core/address_normalizer.h" #include "components/payments/core/payment_instrument.h" -namespace autofill { -class AutofillProfile; -} - namespace payments { class PaymentRequestDelegate; @@ -26,7 +24,8 @@ // Request. class AutofillPaymentInstrument : public PaymentInstrument, - public autofill::payments::FullCardRequest::ResultDelegate { + public autofill::payments::FullCardRequest::ResultDelegate, + public AddressNormalizer::Delegate { public: // |billing_profiles| is owned by the caller and should outlive this object. // |payment_request_delegate| must outlive this object. @@ -49,9 +48,17 @@ const base::string16& cvc) override; void OnFullCardRequestFailed() override; + // AddressNormalizer::Delegate: + void OnAddressNormalized( + const autofill::AutofillProfile& normalized_profile) override; + void OnCouldNotNormalize(const autofill::AutofillProfile& profile) override; + autofill::CreditCard* credit_card() { return &credit_card_; } private: + // Generates the basic card response and sends it to the delegate. + void GenerateBasicCardResponse(); + // A copy of the card is owned by this object. autofill::CreditCard credit_card_; // Not owned by this object, should outlive this. @@ -61,6 +68,12 @@ PaymentInstrument::Delegate* delegate_; PaymentRequestDelegate* payment_request_delegate_; + autofill::AutofillProfile billing_address_; + + base::string16 cvc_; + + bool is_waiting_for_card_unmask_; + bool is_waiting_for_billing_address_normalization_; base::WeakPtrFactory<AutofillPaymentInstrument> weak_ptr_factory_;
diff --git a/components/payments/core/autofill_payment_instrument_unittest.cc b/components/payments/core/autofill_payment_instrument_unittest.cc index 622a4e9..6735be8 100644 --- a/components/payments/core/autofill_payment_instrument_unittest.cc +++ b/components/payments/core/autofill_payment_instrument_unittest.cc
@@ -10,12 +10,134 @@ #include "components/autofill/core/browser/autofill_profile.h" #include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/browser/credit_card.h" +#include "components/payments/core/address_normalizer.h" +#include "components/payments/core/payment_request_delegate.h" #include "components/strings/grit/components_strings.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/l10n/l10n_util.h" namespace payments { +namespace { + +class FakePaymentInstrumentDelegate : public PaymentInstrument::Delegate { + public: + FakePaymentInstrumentDelegate() {} + + void OnInstrumentDetailsReady( + const std::string& method_name, + const std::string& stringified_details) override { + on_instrument_details_ready_called_ = true; + } + + void OnInstrumentDetailsError() override { + on_instrument_details_error_called_ = true; + } + + bool WasOnInstrumentDetailsReadyCalled() { + return on_instrument_details_ready_called_; + } + + bool WasOnInstrumentDetailsErrorCalled() { + return on_instrument_details_error_called_; + } + + private: + bool on_instrument_details_ready_called_ = false; + bool on_instrument_details_error_called_ = false; +}; + +class FakeAddressNormalizer : public AddressNormalizer { + public: + FakeAddressNormalizer() {} + + void LoadRulesForRegion(const std::string& region_code) override {} + + bool AreRulesLoadedForRegion(const std::string& region_code) override { + return true; + } + + void StartAddressNormalization( + const autofill::AutofillProfile& profile, + const std::string& region_code, + int timeout_seconds, + AddressNormalizer::Delegate* requester) override { + profile_ = profile; + requester_ = requester; + } + + void OnAddressValidationRulesLoaded(const std::string& region_code, + bool success) override {} + + void CompleteAddressNormalization() { + requester_->OnAddressNormalized(profile_); + } + + private: + autofill::AutofillProfile profile_; + AddressNormalizer::Delegate* requester_; +}; + +class FakePaymentRequestDelegate : public PaymentRequestDelegate { + public: + FakePaymentRequestDelegate() + : locale_("en-US"), last_committed_url_("https://shop.com") {} + void ShowDialog(PaymentRequest* request) override {} + + void CloseDialog() override {} + + void ShowErrorMessage() override {} + + autofill::PersonalDataManager* GetPersonalDataManager() override { + return nullptr; + } + + const std::string& GetApplicationLocale() const override { return locale_; } + + bool IsIncognito() const override { return false; } + + bool IsSslCertificateValid() override { return true; } + + const GURL& GetLastCommittedURL() const override { + return last_committed_url_; + } + + void DoFullCardRequest( + const autofill::CreditCard& credit_card, + base::WeakPtr<autofill::payments::FullCardRequest::ResultDelegate> + result_delegate) override { + full_card_request_card_ = credit_card; + full_card_result_delegate_ = result_delegate; + } + + AddressNormalizer* GetAddressNormalizer() override { + return &address_normalizer_; + } + + FakeAddressNormalizer* GetTestAddressNormalizer() { + return &address_normalizer_; + } + + void CompleteFullCardRequest() { + full_card_result_delegate_->OnFullCardRequestSucceeded( + full_card_request_card_, base::ASCIIToUTF16("123")); + } + + autofill::RegionDataLoader* GetRegionDataLoader() override { return nullptr; } + + private: + std::string locale_; + const GURL last_committed_url_; + FakeAddressNormalizer address_normalizer_; + + autofill::CreditCard full_card_request_card_; + base::WeakPtr<autofill::payments::FullCardRequest::ResultDelegate> + full_card_result_delegate_; + DISALLOW_COPY_AND_ASSIGN(FakePaymentRequestDelegate); +}; + +} // namespace + class AutofillPaymentInstrumentTest : public testing::Test { protected: AutofillPaymentInstrumentTest() @@ -157,4 +279,56 @@ EXPECT_FALSE(instrument.IsValidForCanMakePayment()); } +// Tests that the autofill instrument only calls OnInstrumentDetailsReady when +// the billing address has been normalized and the card has been unmasked. +TEST_F(AutofillPaymentInstrumentTest, + InvokePaymentApp_NormalizationBeforeUnmask) { + FakePaymentRequestDelegate delegate; + + autofill::CreditCard& card = local_credit_card(); + card.SetNumber(base::ASCIIToUTF16("")); + AutofillPaymentInstrument instrument("visa", card, billing_profiles(), + "en-US", &delegate); + + FakePaymentInstrumentDelegate instrument_delegate; + + instrument.InvokePaymentApp(&instrument_delegate); + EXPECT_FALSE(instrument_delegate.WasOnInstrumentDetailsReadyCalled()); + EXPECT_FALSE(instrument_delegate.WasOnInstrumentDetailsErrorCalled()); + + delegate.GetTestAddressNormalizer()->CompleteAddressNormalization(); + EXPECT_FALSE(instrument_delegate.WasOnInstrumentDetailsReadyCalled()); + EXPECT_FALSE(instrument_delegate.WasOnInstrumentDetailsErrorCalled()); + + delegate.CompleteFullCardRequest(); + EXPECT_TRUE(instrument_delegate.WasOnInstrumentDetailsReadyCalled()); + EXPECT_FALSE(instrument_delegate.WasOnInstrumentDetailsErrorCalled()); +} + +// Tests that the autofill instrument only calls OnInstrumentDetailsReady when +// the billing address has been normalized and the card has been unmasked. +TEST_F(AutofillPaymentInstrumentTest, + InvokePaymentApp_UnmaskBeforeNormalization) { + FakePaymentRequestDelegate delegate; + + autofill::CreditCard& card = local_credit_card(); + card.SetNumber(base::ASCIIToUTF16("")); + AutofillPaymentInstrument instrument("visa", card, billing_profiles(), + "en-US", &delegate); + + FakePaymentInstrumentDelegate instrument_delegate; + + instrument.InvokePaymentApp(&instrument_delegate); + EXPECT_FALSE(instrument_delegate.WasOnInstrumentDetailsReadyCalled()); + EXPECT_FALSE(instrument_delegate.WasOnInstrumentDetailsErrorCalled()); + + delegate.CompleteFullCardRequest(); + EXPECT_FALSE(instrument_delegate.WasOnInstrumentDetailsReadyCalled()); + EXPECT_FALSE(instrument_delegate.WasOnInstrumentDetailsErrorCalled()); + + delegate.GetTestAddressNormalizer()->CompleteAddressNormalization(); + EXPECT_TRUE(instrument_delegate.WasOnInstrumentDetailsReadyCalled()); + EXPECT_FALSE(instrument_delegate.WasOnInstrumentDetailsErrorCalled()); +} + } // namespace payments
diff --git a/components/payments/core/payment_request_data_util.cc b/components/payments/core/payment_request_data_util.cc index 596a20e8..3fd13c9 100644 --- a/components/payments/core/payment_request_data_util.cc +++ b/components/payments/core/payment_request_data_util.cc
@@ -71,7 +71,7 @@ BasicCardResponse GetBasicCardResponseFromAutofillCreditCard( const autofill::CreditCard& card, const base::string16& cvc, - const std::vector<autofill::AutofillProfile*>& billing_profiles, + const autofill::AutofillProfile& billing_profile, const std::string& app_locale) { BasicCardResponse response; response.cardholder_name = card.GetRawInfo(autofill::CREDIT_CARD_NAME_FULL); @@ -81,16 +81,8 @@ card.GetRawInfo(autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR); response.card_security_code = cvc; - // TODO(crbug.com/602666): Ensure we reach here only if the card has a billing - // address. Then add DCHECK(!card->billing_address_id().empty()). - if (!card.billing_address_id().empty()) { - const autofill::AutofillProfile* billing_address = - autofill::PersonalDataManager::GetProfileFromProfilesByGUID( - card.billing_address_id(), billing_profiles); - DCHECK(billing_address); - response.billing_address = - GetPaymentAddressFromAutofillProfile(*billing_address, app_locale); - } + response.billing_address = + GetPaymentAddressFromAutofillProfile(billing_profile, app_locale); return response; }
diff --git a/components/payments/core/payment_request_data_util.h b/components/payments/core/payment_request_data_util.h index e69807fb..984fc8b 100644 --- a/components/payments/core/payment_request_data_util.h +++ b/components/payments/core/payment_request_data_util.h
@@ -35,7 +35,7 @@ BasicCardResponse GetBasicCardResponseFromAutofillCreditCard( const autofill::CreditCard& card, const base::string16& cvc, - const std::vector<autofill::AutofillProfile*>& billing_profiles, + const autofill::AutofillProfile& billing_profile, const std::string& app_locale); // Parse the supported card networks from supportedMethods and "basic-card"'s
diff --git a/components/payments/core/payment_request_data_util_unittest.cc b/components/payments/core/payment_request_data_util_unittest.cc index 5ad7e10..df86baee 100644 --- a/components/payments/core/payment_request_data_util_unittest.cc +++ b/components/payments/core/payment_request_data_util_unittest.cc
@@ -49,8 +49,7 @@ card.set_billing_address_id(address.guid()); std::unique_ptr<base::DictionaryValue> response_value = payments::data_util::GetBasicCardResponseFromAutofillCreditCard( - card, base::ASCIIToUTF16("123"), - std::vector<autofill::AutofillProfile*>{&address}, "en-US") + card, base::ASCIIToUTF16("123"), address, "en-US") .ToDictionaryValue(); std::string json_response; base::JSONWriter::Write(*response_value, &json_response);
diff --git a/components/security_interstitials/content/security_interstitial_page.cc b/components/security_interstitials/content/security_interstitial_page.cc index f0733f0..3b64147 100644 --- a/components/security_interstitials/content/security_interstitial_page.cc +++ b/components/security_interstitials/content/security_interstitial_page.cc
@@ -14,7 +14,6 @@ #include "components/safe_browsing_db/safe_browsing_prefs.h" #include "components/security_interstitials/content/security_interstitial_controller_client.h" #include "components/security_interstitials/core/common_string_util.h" -#include "components/security_interstitials/core/metrics_helper.h" #include "content/public/browser/interstitial_page.h" #include "content/public/browser/page_navigator.h" #include "content/public/browser/web_contents.h" @@ -93,11 +92,6 @@ return controller_.get(); } -security_interstitials::MetricsHelper* -SecurityInterstitialPage::metrics_helper() { - return controller_->metrics_helper(); -} - void SecurityInterstitialPage::UpdateMetricsAfterSecurityInterstitial() { if (controller_->GetPrefService()) { safe_browsing::UpdateMetricsAfterSecurityInterstitial(
diff --git a/components/security_interstitials/content/security_interstitial_page.h b/components/security_interstitials/content/security_interstitial_page.h index 1b24add..60fa290 100644 --- a/components/security_interstitials/content/security_interstitial_page.h +++ b/components/security_interstitials/content/security_interstitial_page.h
@@ -22,7 +22,6 @@ } namespace security_interstitials { -class MetricsHelper; class SecurityInterstitialControllerClient; class SecurityInterstitialPage : public content::InterstitialPageDelegate { @@ -66,8 +65,6 @@ SecurityInterstitialControllerClient* controller(); - MetricsHelper* metrics_helper(); - // Update metrics when the interstitial is closed. void UpdateMetricsAfterSecurityInterstitial(); @@ -90,8 +87,6 @@ // For subclasses that don't have their own ControllerClients yet. std::unique_ptr<SecurityInterstitialControllerClient> controller_; - std::unique_ptr<MetricsHelper> metrics_helper_; - DISALLOW_COPY_AND_ASSIGN(SecurityInterstitialPage); };
diff --git a/components/subresource_filter/core/common/test_ruleset_creator.cc b/components/subresource_filter/core/common/test_ruleset_creator.cc index 408a984..939dff3 100644 --- a/components/subresource_filter/core/common/test_ruleset_creator.cc +++ b/components/subresource_filter/core/common/test_ruleset_creator.cc
@@ -8,7 +8,9 @@ #include "base/files/file_util.h" #include "base/logging.h" +#include "base/memory/ptr_util.h" #include "base/strings/string_number_conversions.h" +#include "base/threading/thread_restrictions.h" #include "components/subresource_filter/core/common/indexed_ruleset.h" #include "components/subresource_filter/core/common/proto/rules.pb.h" #include "components/subresource_filter/core/common/test_ruleset_utils.h" @@ -25,6 +27,7 @@ void WriteRulesetContents(const std::vector<uint8_t>& contents, base::FilePath path) { + base::ThreadRestrictions::ScopedAllowIO allow_io; int ruleset_size_as_int = base::checked_cast<int>(contents.size()); int num_bytes_written = base::WriteFile(path, reinterpret_cast<const char*>(contents.data()), @@ -65,6 +68,7 @@ // static base::File TestRuleset::Open(const TestRuleset& ruleset) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::File file; file.Initialize(ruleset.path, base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_SHARE_DELETE); @@ -105,8 +109,13 @@ // TestRulesetCreator ---------------------------------------------------------- -TestRulesetCreator::TestRulesetCreator() = default; -TestRulesetCreator::~TestRulesetCreator() = default; +TestRulesetCreator::TestRulesetCreator() + : scoped_temp_dir_(base::MakeUnique<base::ScopedTempDir>()) {} + +TestRulesetCreator::~TestRulesetCreator() { + base::ThreadRestrictions::ScopedAllowIO allow_io; + scoped_temp_dir_.reset(); +} void TestRulesetCreator::CreateRulesetToDisallowURLsWithPathSuffix( base::StringPiece suffix, @@ -161,9 +170,10 @@ void TestRulesetCreator::GetUniqueTemporaryPath(base::FilePath* path) { DCHECK(path); - ASSERT_TRUE(scoped_temp_dir_.IsValid() || - scoped_temp_dir_.CreateUniqueTempDir()); - *path = scoped_temp_dir_.GetPath().AppendASCII( + base::ThreadRestrictions::ScopedAllowIO allow_io; + ASSERT_TRUE(scoped_temp_dir_->IsValid() || + scoped_temp_dir_->CreateUniqueTempDir()); + *path = scoped_temp_dir_->GetPath().AppendASCII( base::IntToString(next_unique_file_suffix++)); }
diff --git a/components/subresource_filter/core/common/test_ruleset_creator.h b/components/subresource_filter/core/common/test_ruleset_creator.h index 88338f6..cb07526 100644 --- a/components/subresource_filter/core/common/test_ruleset_creator.h +++ b/components/subresource_filter/core/common/test_ruleset_creator.h
@@ -98,7 +98,7 @@ void CreateTestRulesetFromContents(std::vector<uint8_t> ruleset_contents, TestRuleset* ruleset); - base::ScopedTempDir scoped_temp_dir_; + std::unique_ptr<base::ScopedTempDir> scoped_temp_dir_; int next_unique_file_suffix = 1; DISALLOW_COPY_AND_ASSIGN(TestRulesetCreator);
diff --git a/components/webcrypto/algorithms/hkdf.cc b/components/webcrypto/algorithms/hkdf.cc index f3381100..be01683 100644 --- a/components/webcrypto/algorithms/hkdf.cc +++ b/components/webcrypto/algorithms/hkdf.cc
@@ -71,6 +71,9 @@ if (!has_optional_length_bits) return Status::ErrorHkdfDeriveBitsLengthNotSpecified(); + if (optional_length_bits % 8) + return Status::ErrorHkdfLengthNotWholeByte(); + const blink::WebCryptoHkdfParams* params = algorithm.HkdfParams(); const EVP_MD* digest_algorithm = GetDigest(params->GetHash()); @@ -78,7 +81,7 @@ return Status::ErrorUnsupported(); // Size output to fit length - unsigned int derived_bytes_len = NumBitsToBytes(optional_length_bits); + unsigned int derived_bytes_len = optional_length_bits / 8; derived_bytes->resize(derived_bytes_len); // Algorithm dispatch checks that the algorithm in |base_key| matches @@ -96,7 +99,6 @@ return Status::OperationError(); } - TruncateToBitLength(optional_length_bits, derived_bytes); return Status::Success(); }
diff --git a/components/webcrypto/status.cc b/components/webcrypto/status.cc index 7dcbb93c..3645279c 100644 --- a/components/webcrypto/status.cc +++ b/components/webcrypto/status.cc
@@ -331,6 +331,11 @@ "The length provided for HKDF is too large."); } +Status Status::ErrorHkdfLengthNotWholeByte() { + return Status(blink::kWebCryptoErrorTypeOperation, + "The length provided for HKDF is not a multiple of 8 bits."); +} + Status Status::ErrorHkdfDeriveBitsLengthNotSpecified() { // TODO(nharper): The spec might change so that an OperationError should be // thrown here instead of a TypeError.
diff --git a/components/webcrypto/status.h b/components/webcrypto/status.h index 5933623..2c7dfa7 100644 --- a/components/webcrypto/status.h +++ b/components/webcrypto/status.h
@@ -258,6 +258,9 @@ // The requested length for HKDF was too large. static Status ErrorHkdfLengthTooLong(); + // The length to HKDF's deriveBits() was not a multiple of 8. + static Status ErrorHkdfLengthNotWholeByte(); + // No length parameter was provided for HKDF's Derive Bits operation. static Status ErrorHkdfDeriveBitsLengthNotSpecified();
diff --git a/content/app/content_main_runner.cc b/content/app/content_main_runner.cc index dffa556..2016a617 100644 --- a/content/app/content_main_runner.cc +++ b/content/app/content_main_runner.cc
@@ -603,7 +603,6 @@ crypto::EarlySetupForNSSInit(); #endif - ui::RegisterPathProvider(); RegisterPathProvider(); RegisterContentSchemes(true);
diff --git a/content/browser/child_process_launcher_helper.cc b/content/browser/child_process_launcher_helper.cc index 9aa83459..5d6e9aa 100644 --- a/content/browser/child_process_launcher_helper.cc +++ b/content/browser/child_process_launcher_helper.cc
@@ -104,30 +104,27 @@ AfterLaunchOnLauncherThread(process, options); if (is_synchronous_launch) { - PostLaunchOnLauncherThread(std::move(process), launch_result, false); + PostLaunchOnLauncherThread(std::move(process), launch_result); } } void ChildProcessLauncherHelper::PostLaunchOnLauncherThread( ChildProcessLauncherHelper::Process process, - int launch_result, - bool post_launch_on_client_thread_called) { + int launch_result) { // Release the client handle now that the process has been started (the pipe // may not signal when the process dies otherwise and we would not detect the // child process died). mojo_client_handle_.reset(); if (process.process.IsValid()) { - RecordHistogramsOnLauncherThread( - base::TimeTicks::Now() - begin_launch_time_); + RecordHistogramsOnLauncherThread(base::TimeTicks::Now() - + begin_launch_time_); } - if (!post_launch_on_client_thread_called) { - BrowserThread::PostTask( - client_thread_id_, FROM_HERE, - base::Bind(&ChildProcessLauncherHelper::PostLaunchOnClientThread, - this, base::Passed(&process), launch_result)); - } + BrowserThread::PostTask( + client_thread_id_, FROM_HERE, + base::Bind(&ChildProcessLauncherHelper::PostLaunchOnClientThread, this, + base::Passed(&process), launch_result)); } void ChildProcessLauncherHelper::PostLaunchOnClientThread(
diff --git a/content/browser/child_process_launcher_helper.h b/content/browser/child_process_launcher_helper.h index 6c8ed7d..7132956 100644 --- a/content/browser/child_process_launcher_helper.h +++ b/content/browser/child_process_launcher_helper.h
@@ -122,14 +122,10 @@ const base::LaunchOptions& options); // Called once the process has been created, successfully or not. - // If |post_launch_on_client_thread_called| is false, - // this calls PostLaunchOnClientThread on the client thread. void PostLaunchOnLauncherThread(ChildProcessLauncherHelper::Process process, - int launch_result, - bool post_launch_on_client_thread_called); + int launch_result); - // Note that this could be called before PostLaunchOnLauncherThread() is - // called. + // Posted by PostLaunchOnLauncherThread onto the client thread. void PostLaunchOnClientThread(ChildProcessLauncherHelper::Process process, int error_code);
diff --git a/content/browser/child_process_launcher_helper_android.cc b/content/browser/child_process_launcher_helper_android.cc index b498bb4f..fafbc5d 100644 --- a/content/browser/child_process_launcher_helper_android.cc +++ b/content/browser/child_process_launcher_helper_android.cc
@@ -199,14 +199,14 @@ return base::File(base::android::OpenApkAsset(path.value(), region)); } -// Called from ChildProcessLauncher.java when the ChildProcess was -// started. +// Called from ChildProcessLauncher.java when the ChildProcess was started. // |handle| is the processID of the child process as originated in Java, 0 if // the ChildProcess could not be created. void ChildProcessLauncherHelper::OnChildProcessStarted( JNIEnv*, const base::android::JavaParamRef<jobject>& obj, jint handle) { + DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER); scoped_refptr<ChildProcessLauncherHelper> ref(this); Release(); // Balances with LaunchProcessOnLauncherThread. @@ -214,28 +214,9 @@ ? LAUNCH_RESULT_FAILURE : LAUNCH_RESULT_SUCCESS; - // TODO(jcivelli): Remove this by defining better what happens on what thread - // in the corresponding Java code. ChildProcessLauncherHelper::Process process; process.process = base::Process(handle); - if (BrowserThread::CurrentlyOn(BrowserThread::PROCESS_LAUNCHER)) { - PostLaunchOnLauncherThread(std::move(process), launch_result, - false); // post_launch_on_client_thread_called - return; - } - - bool on_client_thread = BrowserThread::CurrentlyOn( - static_cast<BrowserThread::ID>(client_thread_id())); - BrowserThread::PostTask( - BrowserThread::PROCESS_LAUNCHER, FROM_HERE, - base::Bind(&ChildProcessLauncherHelper::PostLaunchOnLauncherThread, this, - base::Passed(std::move(process)), launch_result, - on_client_thread)); - if (on_client_thread) { - ChildProcessLauncherHelper::Process process; - process.process = base::Process(handle); - PostLaunchOnClientThread(std::move(process), launch_result); - } + PostLaunchOnLauncherThread(std::move(process), launch_result); } // static
diff --git a/content/browser/download/download_file_impl.cc b/content/browser/download/download_file_impl.cc index dd2cb85..b17e42bb 100644 --- a/content/browser/download/download_file_impl.cc +++ b/content/browser/download/download_file_impl.cc
@@ -476,7 +476,7 @@ source_stream->stream_reader()->RegisterCallback(base::Closure()); source_stream->set_finished(true); if (should_terminate) - CancelRequestOnUIThread(source_stream->offset()); + CancelRequest(source_stream->offset()); if (source_stream->length() == DownloadSaveInfo::kLengthFullContent) { SetPotentialFileLength(source_stream->offset() + source_stream->bytes_written()); @@ -650,7 +650,7 @@ DCHECK_EQ(stream.second->bytes_written(), 0); stream.second->stream_reader()->RegisterCallback(base::Closure()); stream.second->set_finished(true); - CancelRequestOnUIThread(stream.second->offset()); + CancelRequest(stream.second->offset()); num_active_streams_--; } } @@ -690,7 +690,7 @@ return ret; } -void DownloadFileImpl::CancelRequestOnUIThread(int64_t offset) { +void DownloadFileImpl::CancelRequest(int64_t offset) { if (!cancel_request_callback_.is_null()) { BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(cancel_request_callback_, offset));
diff --git a/content/browser/download/download_file_impl.h b/content/browser/download/download_file_impl.h index 5376b33..23d6ce58 100644 --- a/content/browser/download/download_file_impl.h +++ b/content/browser/download/download_file_impl.h
@@ -231,7 +231,7 @@ SourceStream* FindPrecedingNeighbor(SourceStream* source_stream); // See |cancel_request_callback_|. - void CancelRequestOnUIThread(int64_t offset); + void CancelRequest(int64_t offset); // Print the internal states for debugging. void DebugStates() const;
diff --git a/content/browser/download/download_file_unittest.cc b/content/browser/download/download_file_unittest.cc index 11b943e..808926b 100644 --- a/content/browser/download/download_file_unittest.cc +++ b/content/browser/download/download_file_unittest.cc
@@ -989,7 +989,7 @@ DestroyDownloadFile(0, false); } -// Activate and deplete one stream, later add the second stream. +// Activate and deplete one stream, later add the second stream. TEST_F(DownloadFileTest, MutipleStreamsFirstStreamWriteAllData) { int64_t stream_0_length = GetBuffersLength(kTestData8, 4);
diff --git a/content/browser/download/download_job.cc b/content/browser/download/download_job.cc index cbdf35f..cd7f619 100644 --- a/content/browser/download/download_job.cc +++ b/content/browser/download/download_job.cc
@@ -62,7 +62,9 @@ } } -void DownloadJob::CancelRequestWithOffset(int64_t offset) {} +void DownloadJob::CancelRequestWithOffset(int64_t offset) { + NOTREACHED(); +} bool DownloadJob::IsParallelizable() const { return false;
diff --git a/content/browser/download/download_job.h b/content/browser/download/download_job.h index 2f12b18b..cae4f1ab 100644 --- a/content/browser/download/download_job.h +++ b/content/browser/download/download_job.h
@@ -46,6 +46,7 @@ // Cancel a particular request starts from |offset|, while the download is not // canceled. Used in parallel download. + // TODO(xingliu): Remove this function if download job owns download file. virtual void CancelRequestWithOffset(int64_t offset); protected:
diff --git a/content/browser/download/parallel_download_job.cc b/content/browser/download/parallel_download_job.cc index b6e5cae5..5f282c3 100644 --- a/content/browser/download/parallel_download_job.cc +++ b/content/browser/download/parallel_download_job.cc
@@ -100,8 +100,8 @@ } auto it = workers_.find(offset); - if (it != workers_.end()) - it->second->Cancel(); + DCHECK(it != workers_.end()); + it->second->Cancel(); } void ParallelDownloadJob::BuildParallelRequestAfterDelay() {
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 40b9c06..e42f92e 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -3331,17 +3331,14 @@ void RenderFrameHostImpl::GetInterfaceProvider( service_manager::mojom::InterfaceProviderRequest interfaces) { - service_manager::InterfaceProviderSpec browser_spec, renderer_spec; - // TODO(beng): CHECK these return true. - service_manager::GetInterfaceProviderSpec( - mojom::kNavigation_FrameSpec, browser_info_.interface_provider_specs, - &browser_spec); - service_manager::GetInterfaceProviderSpec( - mojom::kNavigation_FrameSpec, renderer_info_.interface_provider_specs, - &renderer_spec); - interface_registry_->Bind(std::move(interfaces), - browser_info_.identity, browser_spec, - renderer_info_.identity, renderer_spec); + service_manager::Identity child_identity = GetProcess()->GetChildIdentity(); + child_identity.set_user_id( + BrowserContext::GetServiceUserIdFor(GetProcess()->GetBrowserContext())); + service_manager::Connector* connector = + BrowserContext::GetConnectorFor(GetProcess()->GetBrowserContext()); + connector->FilterInterfaces( + mojom::kNavigation_FrameSpec, child_identity, std::move(interfaces), + interface_provider_bindings_.CreateInterfacePtrAndBind(this)); } #if BUILDFLAG(USE_EXTERNAL_POPUP_MENU) @@ -3641,6 +3638,15 @@ media_interface_proxy_.reset(); } +void RenderFrameHostImpl::GetInterface( + const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) { + if (interface_registry_.get()) { + interface_registry_->BindInterface(interface_name, + std::move(interface_pipe)); + } +} + std::unique_ptr<NavigationHandleImpl> RenderFrameHostImpl::TakeNavigationHandleForCommit( const FrameHostMsg_DidCommitProvisionalLoad_Params& params) {
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index b2e398f..c28f7d5 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -43,6 +43,7 @@ #include "content/public/common/javascript_dialog_type.h" #include "content/public/common/previews_state.h" #include "media/mojo/interfaces/interface_factory.mojom.h" +#include "mojo/public/cpp/bindings/binding_set.h" #include "mojo/public/cpp/system/data_pipe.h" #include "net/http/http_response_headers.h" #include "services/service_manager/public/cpp/interface_factory.h" @@ -117,6 +118,7 @@ public SiteInstanceImpl::Observer, public NON_EXPORTED_BASE( service_manager::InterfaceFactory<media::mojom::InterfaceFactory>), + public NON_EXPORTED_BASE(service_manager::mojom::InterfaceProvider), public CSPContext { public: using AXTreeSnapshotCallback = @@ -894,6 +896,10 @@ // Callback for connection error on the media::mojom::InterfaceFactory client. void OnMediaInterfaceFactoryConnectionError(); + // service_manager::mojom::InterfaceProvider: + void GetInterface(const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) override; + // Allows tests to disable the swapout event timer to simulate bugs that // happen before it fires (to avoid flakiness). void DisableSwapOutTimerForTesting(); @@ -1184,6 +1190,9 @@ std::unique_ptr<service_manager::InterfaceRegistry> java_interface_registry_; #endif + mojo::BindingSet<service_manager::mojom::InterfaceProvider> + interface_provider_bindings_; + // NOTE: This must be the last member. base::WeakPtrFactory<RenderFrameHostImpl> weak_ptr_factory_;
diff --git a/content/browser/media/capture/desktop_capture_device.cc b/content/browser/media/capture/desktop_capture_device.cc index 78a05f95..655418b 100644 --- a/content/browser/media/capture/desktop_capture_device.cc +++ b/content/browser/media/capture/desktop_capture_device.cc
@@ -18,6 +18,7 @@ #include "base/strings/string_number_conversions.h" #include "base/synchronization/lock.h" #include "base/threading/thread.h" +#include "base/threading/thread_restrictions.h" #include "base/timer/timer.h" #include "build/build_config.h" #include "content/browser/media/capture/desktop_capture_device_uma_types.h" @@ -435,6 +436,7 @@ void DesktopCaptureDevice::StopAndDeAllocate() { if (core_) { + base::ThreadRestrictions::ScopedAllowIO allow_io; thread_.task_runner()->DeleteSoon(FROM_HERE, core_.release()); thread_.Stop(); }
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 04f3a54..553ca5e 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1455,6 +1455,11 @@ child_connection_->BindInterface(interface_name, std::move(interface_pipe)); } +const service_manager::Identity& RenderProcessHostImpl::GetChildIdentity() + const { + return child_connection_->child_identity(); +} + std::unique_ptr<base::SharedPersistentMemoryAllocator> RenderProcessHostImpl::TakeMetricsAllocator() { return std::move(metrics_allocator_);
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h index 72df6663..fce8dc8f 100644 --- a/content/browser/renderer_host/render_process_host_impl.h +++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -169,6 +169,7 @@ void ResumeDeferredNavigation(const GlobalRequestID& request_id) override; void BindInterface(const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) override; + const service_manager::Identity& GetChildIdentity() const override; std::unique_ptr<base::SharedPersistentMemoryAllocator> TakeMetricsAllocator() override; const base::TimeTicks& GetInitTimeForNavigationMetrics() const override;
diff --git a/content/public/android/java/src/org/chromium/content/browser/BindingManager.java b/content/public/android/java/src/org/chromium/content/browser/BindingManager.java index dfa3581..3f38056 100644 --- a/content/public/android/java/src/org/chromium/content/browser/BindingManager.java +++ b/content/public/android/java/src/org/chromium/content/browser/BindingManager.java
@@ -48,7 +48,7 @@ * binding. It's safe to call it multiple times, only the first call matters. * @param pid handle of the service process */ - void determinedVisibility(int pid); + void onDeterminedVisibility(int pid); /** * Called when the embedding application is sent to background. We want to maintain a strong
diff --git a/content/public/android/java/src/org/chromium/content/browser/BindingManagerImpl.java b/content/public/android/java/src/org/chromium/content/browser/BindingManagerImpl.java index 81ee555..583a76c 100644 --- a/content/public/android/java/src/org/chromium/content/browser/BindingManagerImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/BindingManagerImpl.java
@@ -9,7 +9,6 @@ import android.content.Context; import android.content.res.Configuration; import android.os.Build; -import android.os.Handler; import android.util.LruCache; import android.util.SparseArray; @@ -20,12 +19,10 @@ import org.chromium.base.metrics.RecordHistogram; import java.util.Map; -import java.util.concurrent.atomic.AtomicReference; - -import javax.annotation.concurrent.GuardedBy; /** * Manages oom bindings used to bound child services. + * This object must only be accessed from the launcher thread. */ class BindingManagerImpl implements BindingManager { private static final String TAG = "cr.BindingManager"; @@ -48,38 +45,46 @@ private static class ModerateBindingPool extends LruCache<Integer, ManagedConnection> implements ComponentCallbacks2 { - private final Object mDelayedClearerLock = new Object(); - - @GuardedBy("mDelayedClearerLock") private Runnable mDelayedClearer; - private final Handler mHandler = new Handler(ThreadUtils.getUiThreadLooper()); - public ModerateBindingPool(int maxSize) { super(maxSize); } @Override - public void onTrimMemory(int level) { - Log.i(TAG, "onTrimMemory: level=%d, size=%d", level, size()); - if (size() > 0) { - if (level <= TRIM_MEMORY_RUNNING_MODERATE) { - reduce(MODERATE_BINDING_LOW_REDUCE_RATIO); - } else if (level <= TRIM_MEMORY_RUNNING_LOW) { - reduce(MODERATE_BINDING_HIGH_REDUCE_RATIO); - } else if (level == TRIM_MEMORY_UI_HIDDEN) { - // This will be handled by |mDelayedClearer|. - return; - } else { - evictAll(); + public void onTrimMemory(final int level) { + ThreadUtils.assertOnUiThread(); + LauncherThread.post(new Runnable() { + @Override + public void run() { + Log.i(TAG, "onTrimMemory: level=%d, size=%d", level, size()); + if (size() <= 0) { + return; + } + if (level <= TRIM_MEMORY_RUNNING_MODERATE) { + reduce(MODERATE_BINDING_LOW_REDUCE_RATIO); + } else if (level <= TRIM_MEMORY_RUNNING_LOW) { + reduce(MODERATE_BINDING_HIGH_REDUCE_RATIO); + } else if (level == TRIM_MEMORY_UI_HIDDEN) { + // This will be handled by |mDelayedClearer|. + return; + } else { + evictAll(); + } } - } + }); } @Override public void onLowMemory() { - Log.i(TAG, "onLowMemory: evict %d bindings", size()); - evictAll(); + ThreadUtils.assertOnUiThread(); + LauncherThread.post(new Runnable() { + @Override + public void run() { + Log.i(TAG, "onLowMemory: evict %d bindings", size()); + evictAll(); + } + }); } @Override @@ -135,37 +140,31 @@ void onSentToBackground(final boolean onTesting) { if (size() == 0) return; - synchronized (mDelayedClearerLock) { - mDelayedClearer = new Runnable() { - @Override - public void run() { - synchronized (mDelayedClearerLock) { - if (mDelayedClearer == null) return; - mDelayedClearer = null; - } - Log.i(TAG, "Release moderate connections: %d", size()); - if (!onTesting) { - RecordHistogram.recordCountHistogram( - "Android.ModerateBindingCount", size()); - } - evictAll(); + mDelayedClearer = new Runnable() { + @Override + public void run() { + if (mDelayedClearer == null) return; + mDelayedClearer = null; + Log.i(TAG, "Release moderate connections: %d", size()); + if (!onTesting) { + RecordHistogram.recordCountHistogram( + "Android.ModerateBindingCount", size()); } - }; - mHandler.postDelayed(mDelayedClearer, MODERATE_BINDING_POOL_CLEARER_DELAY_MILLIS); - } + evictAll(); + } + }; + LauncherThread.postDelayed(mDelayedClearer, MODERATE_BINDING_POOL_CLEARER_DELAY_MILLIS); } void onBroughtToForeground() { - synchronized (mDelayedClearerLock) { - if (mDelayedClearer == null) return; - mHandler.removeCallbacks(mDelayedClearer); + if (mDelayedClearer != null) { + LauncherThread.removeCallbacks(mDelayedClearer); mDelayedClearer = null; } } } - private final AtomicReference<ModerateBindingPool> mModerateBindingPool = - new AtomicReference<>(); + private ModerateBindingPool mModerateBindingPool; /** * Wraps ManagedChildProcessConnection keeping track of additional information needed to manage @@ -204,8 +203,7 @@ if (connection == null) return; connection.addStrongBinding(); - ModerateBindingPool moderateBindingPool = mModerateBindingPool.get(); - if (moderateBindingPool != null) moderateBindingPool.removeConnection(this); + if (mModerateBindingPool != null) mModerateBindingPool.removeConnection(this); } /** Removes a strong service binding. */ @@ -232,7 +230,7 @@ if (mIsLowMemoryDevice) { doUnbind.run(); } else { - ThreadUtils.postOnUiThreadDelayed(doUnbind, DETACH_AS_ACTIVE_HIGH_END_DELAY_MILLIS); + LauncherThread.postDelayed(doUnbind, DETACH_AS_ACTIVE_HIGH_END_DELAY_MILLIS); } } @@ -242,9 +240,8 @@ * @param connection The ChildProcessConnection to add to the moderate binding pool. */ private void addConnectionToModerateBindingPool(ManagedChildProcessConnection connection) { - ModerateBindingPool moderateBindingPool = mModerateBindingPool.get(); - if (moderateBindingPool != null && !connection.isStrongBindingBound()) { - moderateBindingPool.addConnection(ManagedConnection.this); + if (mModerateBindingPool != null && !connection.isStrongBindingBound()) { + mModerateBindingPool.addConnection(ManagedConnection.this); } } @@ -295,7 +292,7 @@ /** * Called when it is safe to rely on setInForeground() for binding management. */ - void determinedVisibility() { + void onDeterminedVisibility() { if (!removeInitialBinding()) return; // Decrease the likelihood of a recently created background tab getting evicted by // immediately adding moderate binding. @@ -317,26 +314,20 @@ } void clearConnection() { - ModerateBindingPool moderateBindingPool = mModerateBindingPool.get(); - if (moderateBindingPool != null) moderateBindingPool.removeConnection(this); + if (mModerateBindingPool != null) mModerateBindingPool.removeConnection(this); mConnection = null; } } - // This can be manipulated on different threads, synchronize access on mManagedConnections. private final SparseArray<ManagedConnection> mManagedConnections = new SparseArray<ManagedConnection>(); // The connection that was most recently set as foreground (using setInForeground()). This is // used to add additional binding on it when the embedder goes to background. On low-end, this - // is also used to drop process bidnings when a new one is created, making sure that only one + // is also used to drop process bindings when a new one is created, making sure that only one // renderer process at a time is protected from oom killing. private ManagedConnection mLastInForeground; - // Synchronizes operations that access mLastInForeground: setInForeground() and - // addNewConnection(). - private final Object mLastInForegroundLock = new Object(); - // The connection bound with additional binding in onSentToBackground(). private ManagedConnection mBoundForBackgroundPeriod; @@ -348,11 +339,13 @@ * Use factory methods to create an instance. */ private BindingManagerImpl(boolean isLowMemoryDevice, boolean onTesting) { + assert LauncherThread.runningOnLauncherThread(); mIsLowMemoryDevice = isLowMemoryDevice; mOnTesting = onTesting; } public static BindingManagerImpl createBindingManager() { + assert LauncherThread.runningOnLauncherThread(); return new BindingManagerImpl(SysUtils.isLowEndDevice(), false); } @@ -362,92 +355,78 @@ * @param isLowEndDevice true iff the created instance should apply low-end binding policies */ public static BindingManagerImpl createBindingManagerForTesting(boolean isLowEndDevice) { + assert LauncherThread.runningOnLauncherThread(); return new BindingManagerImpl(isLowEndDevice, true); } @Override public void addNewConnection(int pid, ManagedChildProcessConnection connection) { + assert LauncherThread.runningOnLauncherThread(); // This will reset the previous entry for the pid in the unlikely event of the OS // reusing renderer pids. - synchronized (mManagedConnections) { - mManagedConnections.put(pid, new ManagedConnection(connection)); - } + mManagedConnections.put(pid, new ManagedConnection(connection)); } @Override public void setInForeground(int pid, boolean inForeground) { - ManagedConnection managedConnection; - synchronized (mManagedConnections) { - managedConnection = mManagedConnections.get(pid); - } - + assert LauncherThread.runningOnLauncherThread(); + ManagedConnection managedConnection = mManagedConnections.get(pid); if (managedConnection == null) { Log.w(TAG, "Cannot setInForeground() - never saw a connection for the pid: %d", pid); return; } - synchronized (mLastInForegroundLock) { - if (inForeground && mIsLowMemoryDevice && mLastInForeground != null - && mLastInForeground != managedConnection) { - mLastInForeground.dropBindings(); - } - - managedConnection.setInForeground(inForeground); - if (inForeground) mLastInForeground = managedConnection; + if (inForeground && mIsLowMemoryDevice && mLastInForeground != null + && mLastInForeground != managedConnection) { + mLastInForeground.dropBindings(); } + + managedConnection.setInForeground(inForeground); + if (inForeground) mLastInForeground = managedConnection; } @Override - public void determinedVisibility(int pid) { - ManagedConnection managedConnection; - synchronized (mManagedConnections) { - managedConnection = mManagedConnections.get(pid); - } - + public void onDeterminedVisibility(int pid) { + assert LauncherThread.runningOnLauncherThread(); + ManagedConnection managedConnection = mManagedConnections.get(pid); if (managedConnection == null) { Log.w(TAG, "Cannot call determinedVisibility() - never saw a connection for the pid: " + "%d", pid); return; } - managedConnection.determinedVisibility(); + managedConnection.onDeterminedVisibility(); } @Override public void onSentToBackground() { + assert LauncherThread.runningOnLauncherThread(); assert mBoundForBackgroundPeriod == null; - synchronized (mLastInForegroundLock) { - // mLastInForeground can be null at this point as the embedding application could be - // used in foreground without spawning any renderers. - if (mLastInForeground != null) { - mLastInForeground.setBoundForBackgroundPeriod(true); - mBoundForBackgroundPeriod = mLastInForeground; - } + // mLastInForeground can be null at this point as the embedding application could be + // used in foreground without spawning any renderers. + if (mLastInForeground != null) { + mLastInForeground.setBoundForBackgroundPeriod(true); + mBoundForBackgroundPeriod = mLastInForeground; } - ModerateBindingPool moderateBindingPool = mModerateBindingPool.get(); - if (moderateBindingPool != null) moderateBindingPool.onSentToBackground(mOnTesting); + if (mModerateBindingPool != null) mModerateBindingPool.onSentToBackground(mOnTesting); } @Override public void onBroughtToForeground() { + assert LauncherThread.runningOnLauncherThread(); if (mBoundForBackgroundPeriod != null) { mBoundForBackgroundPeriod.setBoundForBackgroundPeriod(false); mBoundForBackgroundPeriod = null; } - ModerateBindingPool moderateBindingPool = mModerateBindingPool.get(); - if (moderateBindingPool != null) moderateBindingPool.onBroughtToForeground(); + if (mModerateBindingPool != null) mModerateBindingPool.onBroughtToForeground(); } @Override public void removeConnection(int pid) { - ManagedConnection managedConnection; - synchronized (mManagedConnections) { - managedConnection = mManagedConnections.get(pid); - if (managedConnection != null) { - mManagedConnections.remove(pid); - } - } + assert LauncherThread.runningOnLauncherThread(); + ManagedConnection managedConnection = mManagedConnections.get(pid); if (managedConnection != null) { + mManagedConnections.remove(pid); managedConnection.clearConnection(); } } @@ -455,27 +434,32 @@ /** @return true iff the connection reference is no longer held */ @VisibleForTesting public boolean isConnectionCleared(int pid) { - synchronized (mManagedConnections) { - return mManagedConnections.get(pid) == null; - } + assert LauncherThread.runningOnLauncherThread(); + return mManagedConnections.get(pid) == null; } @Override public void startModerateBindingManagement(Context context, int maxSize) { + assert LauncherThread.runningOnLauncherThread(); if (mIsLowMemoryDevice) return; - ModerateBindingPool pool = new ModerateBindingPool(maxSize); - if (mModerateBindingPool.compareAndSet(null, pool)) { + + if (mModerateBindingPool == null) { Log.i(TAG, "Moderate binding enabled: maxSize=%d", maxSize); - if (context != null) context.registerComponentCallbacks(pool); + mModerateBindingPool = new ModerateBindingPool(maxSize); + if (context != null) { + // Note that it is safe to call Context.registerComponentCallbacks from a background + // thread. + context.registerComponentCallbacks(mModerateBindingPool); + } } } @Override public void releaseAllModerateBindings() { - ModerateBindingPool moderateBindingPool = mModerateBindingPool.get(); - if (moderateBindingPool != null) { - Log.i(TAG, "Release all moderate bindings: %d", moderateBindingPool.size()); - moderateBindingPool.evictAll(); + assert LauncherThread.runningOnLauncherThread(); + if (mModerateBindingPool != null) { + Log.i(TAG, "Release all moderate bindings: %d", mModerateBindingPool.size()); + mModerateBindingPool.evictAll(); } } }
diff --git a/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java b/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java index 611e2a1b..df63669 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java +++ b/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java
@@ -222,16 +222,49 @@ * Called when the renderer commits a navigation. This signals a time at which it is safe to * rely on renderer visibility signalled through setInForeground. See http://crbug.com/421041. */ - public static void determinedVisibility(int pid) { - getBindingManager().determinedVisibility(pid); + public static void determinedVisibility(final int pid) { + assert ThreadUtils.runningOnUiThread(); + LauncherThread.post(new Runnable() { + @Override + public void run() { + getBindingManager().onDeterminedVisibility(pid); + } + }); } /** * Called when the embedding application is sent to background. */ public static void onSentToBackground() { + assert ThreadUtils.runningOnUiThread(); sApplicationInForeground = false; - getBindingManager().onSentToBackground(); + LauncherThread.post(new Runnable() { + @Override + public void run() { + getBindingManager().onSentToBackground(); + } + }); + } + + /** + * Called when the embedding application is brought to foreground. + */ + public static void onBroughtToForeground() { + assert ThreadUtils.runningOnUiThread(); + sApplicationInForeground = true; + LauncherThread.post(new Runnable() { + @Override + public void run() { + getBindingManager().onBroughtToForeground(); + } + }); + } + + /** + * Returns whether the application is currently in the foreground. + */ + static boolean isApplicationInForeground() { + return sApplicationInForeground; } /** @@ -244,25 +277,16 @@ * binding to a render process when it is created and remove the moderate binding when Chrome is * sent to the background. */ - public static void startModerateBindingManagement(Context context) { - getBindingManager().startModerateBindingManagement(context, - ChildConnectionAllocator.getNumberOfServices( - context, true, context.getPackageName())); - } - - /** - * Called when the embedding application is brought to foreground. - */ - public static void onBroughtToForeground() { - sApplicationInForeground = true; - getBindingManager().onBroughtToForeground(); - } - - /** - * Returns whether the application is currently in the foreground. - */ - static boolean isApplicationInForeground() { - return sApplicationInForeground; + public static void startModerateBindingManagement(final Context context) { + assert ThreadUtils.runningOnUiThread(); + LauncherThread.post(new Runnable() { + @Override + public void run() { + getBindingManager().startModerateBindingManagement(context, + ChildConnectionAllocator.getNumberOfServices( + context, true, context.getPackageName())); + } + }); } /** @@ -322,15 +346,14 @@ } /** - * Spawns and connects to a child process. May be called on any thread. It will not block, but - * will instead callback to {@link #nativeOnChildProcessStarted} when the connection is - * established. Note this callback will not necessarily be from the same thread (currently it - * always comes from the main thread). + * Spawns and connects to a child process. It will not block, but will instead callback to + * {@link #LaunchCallback} on the launcher thread when the connection is established on. * * @param context Context used to obtain the application context. * @param paramId Key used to retrieve ChildProcessCreationParams. * @param commandLine The child process command line argv. * @param filesToBeMapped File IDs, FDs, offsets, and lengths to pass through. + * @param launchCallback Callback invoked when the connection is established. */ static void start(Context context, int paramId, final String[] commandLine, int childProcessId, FileDescriptorInfo[] filesToBeMapped, LaunchCallback launchCallback) { @@ -473,6 +496,7 @@ new BaseChildProcessConnection.ConnectionCallback() { @Override public void onConnected(BaseChildProcessConnection connection) { + assert LauncherThread.runningOnLauncherThread(); if (connection != null) { int pid = connection.getPid(); Log.d(TAG, "on connect callback, pid=%d", pid);
diff --git a/content/public/android/java/src/org/chromium/content/browser/LauncherThread.java b/content/public/android/java/src/org/chromium/content/browser/LauncherThread.java index f9732a60..6069269 100644 --- a/content/public/android/java/src/org/chromium/content/browser/LauncherThread.java +++ b/content/public/android/java/src/org/chromium/content/browser/LauncherThread.java
@@ -34,6 +34,10 @@ sHandler.postDelayed(r, delayMillis); } + public static void removeCallbacks(Runnable r) { + sHandler.removeCallbacks(r); + } + public static boolean runningOnLauncherThread() { return sHandler.getLooper() == Looper.myLooper(); }
diff --git a/content/public/android/junit/src/org/chromium/content/browser/BindingManagerImplTest.java b/content/public/android/junit/src/org/chromium/content/browser/BindingManagerImplTest.java index f10218b..425782383 100644 --- a/content/public/android/junit/src/org/chromium/content/browser/BindingManagerImplTest.java +++ b/content/public/android/junit/src/org/chromium/content/browser/BindingManagerImplTest.java
@@ -297,7 +297,7 @@ } /** - * Verifies that the initial binding is removed after determinedVisibility() is called. + * Verifies that the initial binding is removed after onDeterminedVisibility() is called. */ @Test @Feature({"ProcessManagement"}) @@ -315,8 +315,8 @@ // Verify that the initial binding is held. Assert.assertTrue(connection.isInitialBindingBound()); - // Call determinedVisibility() and verify that the initial binding was released. - manager.determinedVisibility(connection.getPid()); + // Call onDeterminedVisibility() and verify that the initial binding was released. + manager.onDeterminedVisibility(connection.getPid()); Assert.assertFalse(connection.isInitialBindingBound()); } } @@ -344,7 +344,7 @@ // After initial binding is removed, the connection is no longer oom protected. manager.setInForeground(connection.getPid(), false); - manager.determinedVisibility(connection.getPid()); + manager.onDeterminedVisibility(connection.getPid()); ShadowLooper.runUiThreadTasksIncludingDelayedTasks(); Assert.assertFalse(message, connection.isOomProtectedOrWasWhenDied()); @@ -624,7 +624,7 @@ Assert.assertFalse(connection.isModerateBindingBound()); manager.setInForeground(connection.getPid(), false); - manager.determinedVisibility(connection.getPid()); + manager.onDeterminedVisibility(connection.getPid()); Assert.assertFalse(connection.isInitialBindingBound()); Assert.assertTrue(connection.isModerateBindingBound()); } @@ -647,7 +647,7 @@ Assert.assertFalse(connection.isModerateBindingBound()); manager.setInForeground(connection.getPid(), true); - manager.determinedVisibility(connection.getPid()); + manager.onDeterminedVisibility(connection.getPid()); Assert.assertFalse(connection.isInitialBindingBound()); Assert.assertTrue(connection.isStrongBindingBound()); Assert.assertFalse(connection.isModerateBindingBound()); @@ -667,7 +667,7 @@ connection.start(null /* startCallback */); manager.addNewConnection(connection.getPid(), connection); manager.setInForeground(connection.getPid(), false); - manager.determinedVisibility(connection.getPid()); + manager.onDeterminedVisibility(connection.getPid()); Assert.assertTrue(connection.isModerateBindingBound()); manager.onSentToBackground();
diff --git a/content/public/browser/render_process_host.h b/content/public/browser/render_process_host.h index 1330045..6a3b7c9e 100644 --- a/content/public/browser/render_process_host.h +++ b/content/public/browser/render_process_host.h
@@ -29,6 +29,10 @@ class TimeDelta; } +namespace service_manager { +class Identity; +} + namespace content { class BrowserContext; class BrowserMessageFilter; @@ -279,6 +283,8 @@ virtual void BindInterface(const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) = 0; + virtual const service_manager::Identity& GetChildIdentity() const = 0; + // Extracts any persistent-memory-allocator used for renderer metrics. // Ownership is passed to the caller. To support sharing of histogram data // between the Renderer and the Browser, the allocator is created when the
diff --git a/content/public/test/browser_test_base.cc b/content/public/test/browser_test_base.cc index 69afea6..c424c6ec 100644 --- a/content/public/test/browser_test_base.cc +++ b/content/public/test/browser_test_base.cc
@@ -305,7 +305,7 @@ bool old_io_allowed_value = false; if (!disable_io_checks_) - base::ThreadRestrictions::SetIOAllowed(false); + old_io_allowed_value = base::ThreadRestrictions::SetIOAllowed(false); RunTestOnMainThread(); if (!disable_io_checks_) base::ThreadRestrictions::SetIOAllowed(old_io_allowed_value);
diff --git a/content/public/test/mock_render_process_host.cc b/content/public/test/mock_render_process_host.cc index cb56a83..878462df 100644 --- a/content/public/test/mock_render_process_host.cc +++ b/content/public/test/mock_render_process_host.cc
@@ -270,6 +270,11 @@ binder_overrides_[interface_name].Run(std::move(interface_pipe)); } +const service_manager::Identity& MockRenderProcessHost::GetChildIdentity() + const { + return child_identity_; +} + std::unique_ptr<base::SharedPersistentMemoryAllocator> MockRenderProcessHost::TakeMetricsAllocator() { return nullptr;
diff --git a/content/public/test/mock_render_process_host.h b/content/public/test/mock_render_process_host.h index fbb4934..2e751dd3 100644 --- a/content/public/test/mock_render_process_host.h +++ b/content/public/test/mock_render_process_host.h
@@ -19,6 +19,7 @@ #include "ipc/ipc_test_sink.h" #include "media/media_features.h" #include "mojo/public/cpp/bindings/associated_interface_ptr.h" +#include "services/service_manager/public/cpp/identity.h" #include "services/service_manager/public/cpp/interface_provider.h" class StoragePartition; @@ -104,6 +105,7 @@ void ResumeDeferredNavigation(const GlobalRequestID& request_id) override; void BindInterface(const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) override; + const service_manager::Identity& GetChildIdentity() const override; std::unique_ptr<base::SharedPersistentMemoryAllocator> TakeMetricsAllocator() override; const base::TimeTicks& GetInitTimeForNavigationMetrics() const override; @@ -171,6 +173,7 @@ std::unique_ptr<mojo::AssociatedInterfacePtr<mojom::Renderer>> renderer_interface_; std::map<std::string, InterfaceBinder> binder_overrides_; + service_manager::Identity child_identity_; DISALLOW_COPY_AND_ASSIGN(MockRenderProcessHost); };
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc index f09319c7..3666836 100644 --- a/content/renderer/gpu/render_widget_compositor.cc +++ b/content/renderer/gpu/render_widget_compositor.cc
@@ -949,6 +949,9 @@ callback, base::Passed(&result))); }, callback, base::Passed(&main_thread_task_runner))); + // Force a redraw to ensure that the copy swap promise isn't cancelled due to + // no damage. + SetNeedsForcedRedraw(); layer_tree_host_->QueueSwapPromise( delegate_->RequestCopyOfOutputForLayoutTest(std::move(request)));
diff --git a/content/renderer/media/android/media_player_renderer_client_factory.cc b/content/renderer/media/android/media_player_renderer_client_factory.cc index 0776318..09dad61 100644 --- a/content/renderer/media/android/media_player_renderer_client_factory.cc +++ b/content/renderer/media/android/media_player_renderer_client_factory.cc
@@ -43,4 +43,9 @@ std::move(stream_texture_wrapper), video_renderer_sink); } +media::MediaResource::Type +MediaPlayerRendererClientFactory::GetRequiredMediaResourceType() { + return media::MediaResource::Type::URL; +} + } // namespace content
diff --git a/content/renderer/media/android/media_player_renderer_client_factory.h b/content/renderer/media/android/media_player_renderer_client_factory.h index eaaee06..a0809fec 100644 --- a/content/renderer/media/android/media_player_renderer_client_factory.h +++ b/content/renderer/media/android/media_player_renderer_client_factory.h
@@ -36,6 +36,9 @@ media::VideoRendererSink* video_renderer_sink, const media::RequestSurfaceCB& request_surface_cb) override; + // The MediaPlayerRenderer uses a Type::URL. + media::MediaResource::Type GetRequiredMediaResourceType() override; + private: GetStreamTextureWrapperCB get_stream_texture_wrapper_cb_;
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index e20d9dfc..d11d877 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -177,6 +177,7 @@ #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "net/http/http_util.h" #include "ppapi/features/features.h" +#include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "services/service_manager/public/cpp/interface_registry.h" #include "services/ui/public/cpp/gpu/context_provider_command_buffer.h" @@ -1319,6 +1320,12 @@ blame_context_->Initialize(); } +void RenderFrameImpl::GetInterface( + const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) { + interface_registry_->BindInterface(interface_name, std::move(interface_pipe)); +} + RenderWidget* RenderFrameImpl::GetRenderWidget() { return GetLocalRoot()->render_widget_.get(); } @@ -2734,21 +2741,12 @@ void RenderFrameImpl::GetInterfaceProvider( service_manager::mojom::InterfaceProviderRequest request) { - service_manager::ServiceInfo child_info = - ChildThreadImpl::current()->GetChildServiceInfo(); service_manager::ServiceInfo browser_info = ChildThreadImpl::current()->GetBrowserServiceInfo(); - - service_manager::InterfaceProviderSpec child_spec, browser_spec; - // TODO(beng): CHECK these return true. - service_manager::GetInterfaceProviderSpec( - mojom::kNavigation_FrameSpec, child_info.interface_provider_specs, - &child_spec); - service_manager::GetInterfaceProviderSpec( - mojom::kNavigation_FrameSpec, browser_info.interface_provider_specs, - &browser_spec); - interface_registry_->Bind(std::move(request), child_info.identity, child_spec, - browser_info.identity, browser_spec); + service_manager::Connector* connector = ChildThread::Get()->GetConnector(); + connector->FilterInterfaces( + mojom::kNavigation_FrameSpec, browser_info.identity, std::move(request), + interface_provider_bindings_.CreateInterfacePtrAndBind(this)); } void RenderFrameImpl::AllowBindings(int32_t enabled_bindings_flags) { @@ -2897,63 +2895,67 @@ std::unique_ptr<media::MediaLog> media_log( new RenderMediaLog(url::Origin(security_origin).GetURL())); - bool use_fallback_path = false; + auto factory_selector = base::MakeUnique<media::RendererFactorySelector>(); + #if defined(OS_ANDROID) - use_fallback_path = UseMediaPlayerRenderer(url); + // The only MojoRendererService that is registered at the RenderFrameHost + // level uses the MediaPlayerRenderer as its underlying media::Renderer. + auto mojo_media_player_renderer_factory = + base::MakeUnique<media::MojoRendererFactory>( + media::MojoRendererFactory::GetGpuFactoriesCB(), + GetRemoteInterfaces()->get()); + + // Always give |factory_selector| a MediaPlayerRendererClient factory. WMPI + // might fallback to it if the final redirected URL is an HLS url. + factory_selector->AddFactory( + media::RendererFactorySelector::FactoryType::MEDIA_PLAYER, + base::MakeUnique<MediaPlayerRendererClientFactory>( + render_thread->compositor_task_runner(), + std::move(mojo_media_player_renderer_factory), + base::Bind(&StreamTextureWrapperImpl::Create, + render_thread->EnableStreamTextureCopy(), + render_thread->GetStreamTexureFactory(), + base::ThreadTaskRunnerHandle::Get()))); + + factory_selector->SetUseMediaPlayer(UseMediaPlayerRenderer(url)); #endif // defined(OS_ANDROID) + // |factory_type| will be overwritten in all possible path below, and the + // DEFAULT value is not accurate. However, this prevents the compiler from + // issuing a -Wsometimes-uninitialized warning. + // TODO(tguilbert): Remove |factory_type|, and clean up the logic. The work is + // already completed and incrementally being submitted. See crbug.com/663503. + auto factory_type = media::RendererFactorySelector::FactoryType::DEFAULT; std::unique_ptr<media::RendererFactory> media_renderer_factory; - media::RendererFactorySelector::FactoryType factory_type; - if (use_fallback_path) { -#if defined(OS_ANDROID) - auto mojo_renderer_factory = base::MakeUnique<media::MojoRendererFactory>( - media::MojoRendererFactory::GetGpuFactoriesCB(), - GetRemoteInterfaces()->get()); - media_renderer_factory = base::MakeUnique<MediaPlayerRendererClientFactory>( - render_thread->compositor_task_runner(), - std::move(mojo_renderer_factory), - base::Bind(&StreamTextureWrapperImpl::Create, - render_thread->EnableStreamTextureCopy(), - render_thread->GetStreamTexureFactory(), - base::ThreadTaskRunnerHandle::Get())); -#endif // defined(OS_ANDROID) - - // TODO(tguilbert): Move this line back into an #if defined(OS_ANDROID). - // This will never be reached, unless we are on Android. Moving this line - // outside of the #if/#endif block fixes a "sometimes-uninitialized" error - // on desktop. This will be fixed with the next CL for crbug.com/663503. - factory_type = media::RendererFactorySelector::FactoryType::MEDIA_PLAYER; - } else { #if defined(ENABLE_MOJO_RENDERER) #if BUILDFLAG(ENABLE_RUNTIME_MEDIA_RENDERER_SELECTION) - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableMojoRenderer)) { - media_renderer_factory = base::MakeUnique<media::DefaultRendererFactory>( - media_log.get(), GetDecoderFactory(), - base::Bind(&RenderThreadImpl::GetGpuFactories, - base::Unretained(render_thread))); - - factory_type = media::RendererFactorySelector::FactoryType::DEFAULT; - } -#endif // BUILDFLAG(ENABLE_RUNTIME_MEDIA_RENDERER_SELECTION) - if (!media_renderer_factory) { - media_renderer_factory = base::MakeUnique<media::MojoRendererFactory>( - base::Bind(&RenderThreadImpl::GetGpuFactories, - base::Unretained(render_thread)), - GetMediaInterfaceProvider()); - - factory_type = media::RendererFactorySelector::FactoryType::MOJO; - } -#else + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableMojoRenderer)) { media_renderer_factory = base::MakeUnique<media::DefaultRendererFactory>( media_log.get(), GetDecoderFactory(), base::Bind(&RenderThreadImpl::GetGpuFactories, base::Unretained(render_thread))); factory_type = media::RendererFactorySelector::FactoryType::DEFAULT; -#endif // defined(ENABLE_MOJO_RENDERER) } +#endif // BUILDFLAG(ENABLE_RUNTIME_MEDIA_RENDERER_SELECTION) + if (!media_renderer_factory) { + media_renderer_factory = base::MakeUnique<media::MojoRendererFactory>( + base::Bind(&RenderThreadImpl::GetGpuFactories, + base::Unretained(render_thread)), + GetMediaInterfaceProvider()); + + factory_type = media::RendererFactorySelector::FactoryType::MOJO; + } +#else + media_renderer_factory = base::MakeUnique<media::DefaultRendererFactory>( + media_log.get(), GetDecoderFactory(), + base::Bind(&RenderThreadImpl::GetGpuFactories, + base::Unretained(render_thread))); + + factory_type = media::RendererFactorySelector::FactoryType::DEFAULT; +#endif // defined(ENABLE_MOJO_RENDERER) #if BUILDFLAG(ENABLE_MEDIA_REMOTING) media_renderer_factory = @@ -2966,8 +2968,6 @@ if (!url_index_.get() || url_index_->frame() != frame_) url_index_.reset(new media::UrlIndex(frame_)); - auto factory_selector = base::MakeUnique<media::RendererFactorySelector>(); - factory_selector->AddFactory(factory_type, std::move(media_renderer_factory)); factory_selector->SetBaseFactoryType(factory_type); @@ -2997,7 +2997,6 @@ #if defined(OS_ANDROID) // WMPI_CAST media_player->SetMediaPlayerManager(GetMediaPlayerManager()); media_player->SetDeviceScaleFactor(render_view_->GetDeviceScaleFactor()); - media_player->SetUseFallbackPath(use_fallback_path); #endif // defined(OS_ANDROID) return media_player;
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 4884aac..7c44d2b 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -52,6 +52,7 @@ #include "media/mojo/interfaces/remoting.mojom.h" #include "mojo/public/cpp/bindings/associated_binding.h" #include "mojo/public/cpp/bindings/binding.h" +#include "mojo/public/cpp/bindings/binding_set.h" #include "mojo/public/cpp/system/data_pipe.h" #include "ppapi/features/features.h" #include "services/service_manager/public/cpp/service_info.h" @@ -187,7 +188,8 @@ NON_EXPORTED_BASE(mojom::HostZoom), NON_EXPORTED_BASE(mojom::FrameBindingsControl), NON_EXPORTED_BASE(public blink::WebFrameClient), - NON_EXPORTED_BASE(public blink::WebFrameSerializerClient) { + NON_EXPORTED_BASE(public blink::WebFrameSerializerClient), + NON_EXPORTED_BASE(service_manager::mojom::InterfaceProvider) { public: // Creates a new RenderFrame as the main frame of |render_view|. static RenderFrameImpl* CreateMainFrame( @@ -1123,6 +1125,10 @@ void InitializeBlameContext(RenderFrameImpl* parent_frame); + // service_manager::mojom::InterfaceProvider: + void GetInterface(const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) override; + // Stores the WebLocalFrame we are associated with. This is null from the // constructor until BindToWebFrame is called, and it is null after // frameDetached is called until destruction (which is asynchronous in the @@ -1427,6 +1433,9 @@ // is used and released in didStartProvisionalLoad(). std::unique_ptr<PendingNavigationInfo> pending_navigation_info_; + mojo::BindingSet<service_manager::mojom::InterfaceProvider> + interface_provider_bindings_; + base::WeakPtrFactory<RenderFrameImpl> weak_factory_; DISALLOW_COPY_AND_ASSIGN(RenderFrameImpl);
diff --git a/content/test/layouttest_support.cc b/content/test/layouttest_support.cc index 9c19b34..5b003d7 100644 --- a/content/test/layouttest_support.cc +++ b/content/test/layouttest_support.cc
@@ -354,7 +354,7 @@ std::move(compositor_context_provider), std::move(worker_context_provider), nullptr /* shared_bitmap_manager */, gpu_memory_buffer_manager, settings.renderer_settings, task_runner, - synchronous_composite, false /* force_disable_reclaim_resources */); + synchronous_composite); compositor_frame_sink->SetClient(this); compositor_frame_sinks_[routing_id] = compositor_frame_sink.get(); return std::move(compositor_frame_sink);
diff --git a/device/vr/vr_math.cc b/device/vr/vr_math.cc index cd95d5eb..567fe6f 100644 --- a/device/vr/vr_math.cc +++ b/device/vr/vr_math.cc
@@ -177,6 +177,69 @@ {{0.0f, 0.0f, 0.0f, 1.0f}}}}; } +vr::Quatf GetVectorRotation(const gfx::Vector3dF& from, + const gfx::Vector3dF& to) { + float dot = gfx::DotProduct(from, to); + float norm = sqrt(from.LengthSquared() * to.LengthSquared()); + float real = norm + dot; + gfx::Vector3dF w; + if (real < 1.e-6f * norm) { + real = 0.0f; + w = fabsf(from.x()) > fabsf(from.z()) + ? gfx::Vector3dF{-from.y(), from.x(), 0.0f} + : gfx::Vector3dF{0.0f, -from.z(), from.y()}; + } else { + w = gfx::CrossProduct(from, to); + } + vr::Quatf result{w.x(), w.y(), w.z(), real}; + NormalizeQuat(&result); + return result; +} + +vr::Quatf QuatSum(const vr::Quatf& a, const vr::Quatf& b) { + return {a.qx + b.qx, a.qy + b.qy, a.qz + b.qz, a.qw + b.qw}; +} + +vr::Quatf QuatProduct(const vr::Quatf& a, const vr::Quatf& b) { + return {a.qw * b.qx + a.qx * b.qw + a.qy * b.qz - a.qz * b.qy, + a.qw * b.qy - a.qx * b.qz + a.qy * b.qw + a.qz * b.qx, + a.qw * b.qz + a.qx * b.qy - a.qy * b.qx + a.qz * b.qw, + a.qw * b.qw - a.qx * b.qx - a.qy * b.qy - a.qz * b.qz}; +} + +vr::Quatf ScaleQuat(const vr::Quatf& q, float s) { + return {q.qx * s, q.qy * s, q.qz * s, q.qw * s}; +} + +vr::Quatf InvertQuat(const vr::Quatf& quat) { + return {-quat.qx, -quat.qy, -quat.qz, quat.qw}; +} + +float QuatAngleDegrees(const vr::Quatf& a, const vr::Quatf& b) { + return QuatProduct(b, InvertQuat(a)).qw; +} + +vr::Quatf QuatLerp(const vr::Quatf& a, const vr::Quatf& b, float t) { + auto result = QuatSum(ScaleQuat(a, 1.0f - t), ScaleQuat(b, t)); + NormalizeQuat(&result); + return result; +} + +gfx::Vector3dF QuatSlerp(const gfx::Vector3dF& v_start, + const gfx::Vector3dF& v_end, + float percent) { + auto start = v_start; + auto end = v_end; + NormalizeVector(&start); + NormalizeVector(&end); + float dot = Clampf(gfx::DotProduct(start, end), -1.0f, 1.0f); + float theta = acos(dot) * percent; + auto relative_vec = end - gfx::ScaleVector3d(start, dot); + NormalizeVector(&relative_vec); + return gfx::ScaleVector3d(start, cos(theta)) + + gfx::ScaleVector3d(relative_vec, sin(theta)); +} + gfx::Point3F GetRayPoint(const gfx::Point3F& rayOrigin, const gfx::Vector3dF& rayVector, float scale) { @@ -199,4 +262,28 @@ return true; } +gfx::Vector3dF ToVector(const gfx::Point3F& p) { + return {p.x(), p.y(), p.z()}; +} + +gfx::Point3F ToPoint(const gfx::Vector3dF& p) { + return {p.x(), p.y(), p.z()}; +} + +gfx::Point3F ScalePoint(const gfx::Point3F& p, const gfx::Vector3dF& s) { + return gfx::ScalePoint(p, s.x(), s.y(), s.z()); +} + +gfx::Vector3dF ScaleVector(const gfx::Vector3dF& v, const gfx::Vector3dF& s) { + return gfx::ScaleVector3d(v, s.x(), s.y(), s.z()); +} + +float Clampf(float value, float min, float max) { + if (value < min) + return min; + if (value > max) + return max; + return value; +} + } // namespace vr
diff --git a/device/vr/vr_math.h b/device/vr/vr_math.h index 2426b3dc..55c165c 100644 --- a/device/vr/vr_math.h +++ b/device/vr/vr_math.h
@@ -33,6 +33,27 @@ void DEVICE_VR_EXPORT QuatToMatrix(const Quatf& quat, Mat4f* out); +// Creates a rotation which rotates `from` vector to `to`. +vr::Quatf DEVICE_VR_EXPORT GetVectorRotation(const gfx::Vector3dF& from, + const gfx::Vector3dF& to); + +vr::Quatf DEVICE_VR_EXPORT QuatSum(const vr::Quatf& a, const vr::Quatf& b); +vr::Quatf DEVICE_VR_EXPORT QuatProduct(const vr::Quatf& a, const vr::Quatf& b); +vr::Quatf DEVICE_VR_EXPORT ScaleQuat(const vr::Quatf& q, float s); + +vr::Quatf DEVICE_VR_EXPORT InvertQuat(const vr::Quatf& quat); + +float DEVICE_VR_EXPORT QuatAngleDegrees(const vr::Quatf& a, const vr::Quatf& b); + +vr::Quatf DEVICE_VR_EXPORT QuatLerp(const vr::Quatf& a, + const vr::Quatf& b, + float t); + +// Spherical linear interpolation. +gfx::Vector3dF DEVICE_VR_EXPORT QuatSlerp(const gfx::Vector3dF& v_start, + const gfx::Vector3dF& v_end, + float percent); + // Normalize a vector, and return its original length. float DEVICE_VR_EXPORT NormalizeVector(gfx::Vector3dF* vec); @@ -49,6 +70,20 @@ const gfx::Vector3dF& vec2, float* angle); +gfx::Vector3dF DEVICE_VR_EXPORT ToVector(const gfx::Point3F& p); + +gfx::Point3F DEVICE_VR_EXPORT ToPoint(const gfx::Vector3dF& p); + +// Scale components of the point by the components of the vector. +gfx::Point3F DEVICE_VR_EXPORT ScalePoint(const gfx::Point3F& p, + const gfx::Vector3dF& s); + +// Scale components of a vector by the components of another. +gfx::Vector3dF DEVICE_VR_EXPORT ScaleVector(const gfx::Vector3dF& p, + const gfx::Vector3dF& s); + +float DEVICE_VR_EXPORT Clampf(float value, float min, float max); + } // namespace vr #endif // DEVICE_VR_VR_MATH_H_
diff --git a/extensions/browser/api/printer_provider/printer_provider_apitest.cc b/extensions/browser/api/printer_provider/printer_provider_apitest.cc index d0b8cb40..b53ac100 100644 --- a/extensions/browser/api/printer_provider/printer_provider_apitest.cc +++ b/extensions/browser/api/printer_provider/printer_provider_apitest.cc
@@ -18,6 +18,7 @@ #include "base/run_loop.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" #include "device/usb/mock_usb_device.h" #include "device/usb/mock_usb_service.h" #include "extensions/browser/api/printer_provider/printer_provider_api.h" @@ -99,7 +100,10 @@ }; PrinterProviderApiTest() {} - ~PrinterProviderApiTest() override {} + ~PrinterProviderApiTest() override { + base::ThreadRestrictions::ScopedAllowIO allow_io; + ignore_result(data_dir_.Delete()); + } void StartGetPrintersRequest( const PrinterProviderAPI::GetPrintersCallback& callback) { @@ -238,10 +242,12 @@ case PRINT_REQUEST_DATA_TYPE_FILE: ASSERT_TRUE(StartPrintRequestUsingFileInfo(extension_id, callback)); break; - case PRINT_REQUEST_DATA_TYPE_FILE_DELETED: + case PRINT_REQUEST_DATA_TYPE_FILE_DELETED: { ASSERT_TRUE(StartPrintRequestUsingFileInfo(extension_id, callback)); + base::ThreadRestrictions::ScopedAllowIO allow_io; ASSERT_TRUE(data_dir_.Delete()); break; + } case PRINT_REQUEST_DATA_TYPE_BYTES: StartPrintRequestUsingDocumentBytes(extension_id, callback); break; @@ -349,6 +355,7 @@ int size, base::FilePath* path, base::File::Info* file_info) { + base::ThreadRestrictions::ScopedAllowIO allow_io; if (!data_dir_.IsValid() && !data_dir_.CreateUniqueTempDir()) return false;
diff --git a/extensions/browser/guest_view/app_view/app_view_apitest.cc b/extensions/browser/guest_view/app_view/app_view_apitest.cc index ffa7020..276c4b1 100644 --- a/extensions/browser/guest_view/app_view/app_view_apitest.cc +++ b/extensions/browser/guest_view/app_view/app_view_apitest.cc
@@ -5,6 +5,7 @@ #include "base/command_line.h" #include "base/path_service.h" #include "base/strings/stringprintf.h" +#include "base/threading/thread_restrictions.h" #include "components/guest_view/browser/guest_view_manager.h" #include "components/guest_view/browser/guest_view_manager_factory.h" #include "components/guest_view/browser/test_guest_view_manager.h" @@ -112,6 +113,7 @@ } const Extension* LoadApp(const std::string& app_location) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath test_data_dir; PathService::Get(DIR_TEST_DATA, &test_data_dir); test_data_dir = test_data_dir.AppendASCII(app_location.c_str());
diff --git a/extensions/browser/guest_view/web_view/web_view_apitest.cc b/extensions/browser/guest_view/web_view/web_view_apitest.cc index 6206dd12..aef32e9 100644 --- a/extensions/browser/guest_view/web_view/web_view_apitest.cc +++ b/extensions/browser/guest_view/web_view/web_view_apitest.cc
@@ -11,6 +11,7 @@ #include "base/path_service.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "components/guest_view/browser/guest_view_manager.h" #include "components/guest_view/browser/guest_view_manager_delegate.h" @@ -138,6 +139,7 @@ } void WebViewAPITest::LaunchApp(const std::string& app_location) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath test_data_dir; PathService::Get(DIR_TEST_DATA, &test_data_dir); test_data_dir = test_data_dir.AppendASCII(app_location.c_str()); @@ -203,6 +205,7 @@ test_config_.SetInteger(kTestServerPort, embedded_test_server()->port()); + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath test_data_dir; PathService::Get(DIR_TEST_DATA, &test_data_dir); test_data_dir = test_data_dir.AppendASCII(app_location.c_str());
diff --git a/extensions/renderer/api_binding.cc b/extensions/renderer/api_binding.cc index 9e1aee5..8652b713 100644 --- a/extensions/renderer/api_binding.cc +++ b/extensions/renderer/api_binding.cc
@@ -257,24 +257,32 @@ std::vector<std::string> rule_conditions; const base::DictionaryValue* options = nullptr; bool supports_rules = false; - if (event_dict->GetDictionary("options", &options) && - options->GetBoolean("supportsRules", &supports_rules) && - supports_rules) { - bool supports_listeners = false; - DCHECK(options->GetBoolean("supportsListeners", &supports_listeners)); - DCHECK(!supports_listeners) - << "Events cannot support rules and listeners."; - auto get_values = [options](base::StringPiece name, - std::vector<std::string>* out_value) { - const base::ListValue* list = nullptr; - CHECK(options->GetList(name, &list)); - for (const auto& entry : *list) { - DCHECK(entry.is_string()); - out_value->push_back(entry.GetString()); - } - }; - get_values("actions", &rule_actions); - get_values("conditions", &rule_conditions); + if (event_dict->GetDictionary("options", &options)) { + bool temp_supports_filters = false; + // TODO(devlin): For some reason, schemas indicate supporting filters + // either through having a 'filters' property *or* through having + // a 'supportsFilters' property. We should clean that up. + supports_filters |= + (options->GetBoolean("supportsFilters", &temp_supports_filters) && + temp_supports_filters); + if (options->GetBoolean("supportsRules", &supports_rules) && + supports_rules) { + bool supports_listeners = false; + DCHECK(options->GetBoolean("supportsListeners", &supports_listeners)); + DCHECK(!supports_listeners) + << "Events cannot support rules and listeners."; + auto get_values = [options](base::StringPiece name, + std::vector<std::string>* out_value) { + const base::ListValue* list = nullptr; + CHECK(options->GetList(name, &list)); + for (const auto& entry : *list) { + DCHECK(entry.is_string()); + out_value->push_back(entry.GetString()); + } + }; + get_values("actions", &rule_actions); + get_values("conditions", &rule_conditions); + } } events_.push_back(base::MakeUnique<EventData>(
diff --git a/extensions/renderer/api_binding_unittest.cc b/extensions/renderer/api_binding_unittest.cc index 389fe96..fc82ff4 100644 --- a/extensions/renderer/api_binding_unittest.cc +++ b/extensions/renderer/api_binding_unittest.cc
@@ -1188,4 +1188,69 @@ reset_last_request(); } +TEST_F(APIBindingUnittest, FilteredEvents) { + const char kEvents[] = + "[{" + " 'name': 'unfilteredOne'," + " 'parameters': []" + "}, {" + " 'name': 'unfilteredTwo'," + " 'filters': []," + " 'parameters': []" + "}, {" + " 'name': 'unfilteredThree'," + " 'options': {'supportsFilters': false}," + " 'parameters': []" + "}, {" + " 'name': 'filteredOne'," + " 'options': {'supportsFilters': true}," + " 'parameters': []" + "}, {" + " 'name': 'filteredTwo'," + " 'filters': [" + " {'name': 'url', 'type': 'array', 'items': {'type': 'any'}}" + " ]," + " 'parameters': []" + "}]"; + SetEvents(kEvents); + InitializeBinding(); + + v8::HandleScope handle_scope(isolate()); + v8::Local<v8::Context> context = MainContext(); + + v8::Local<v8::Object> binding_object = + binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); + + const char kAddFilteredListener[] = + "(function(evt) {\n" + " evt.addListener(function() {},\n" + " {url: [{pathContains: 'simple2.html'}]});\n" + "})"; + v8::Local<v8::Function> function = + FunctionFromString(context, kAddFilteredListener); + ASSERT_FALSE(function.IsEmpty()); + + auto check_supports_filters = [context, binding_object, function]( + base::StringPiece name, + bool expect_supports) { + SCOPED_TRACE(name); + v8::Local<v8::Value> event = + GetPropertyFromObject(binding_object, context, name); + v8::Local<v8::Value> args[] = {event}; + if (expect_supports) { + RunFunction(function, context, context->Global(), arraysize(args), args); + } else { + RunFunctionAndExpectError( + function, context, context->Global(), arraysize(args), args, + "Uncaught TypeError: This event does not support filters"); + } + }; + + check_supports_filters("unfilteredOne", false); + check_supports_filters("unfilteredTwo", false); + check_supports_filters("unfilteredThree", false); + check_supports_filters("filteredOne", true); + check_supports_filters("filteredTwo", true); +} + } // namespace extensions
diff --git a/extensions/shell/test/shell_apitest.cc b/extensions/shell/test/shell_apitest.cc index c5aa1182..b8b7829 100644 --- a/extensions/shell/test/shell_apitest.cc +++ b/extensions/shell/test/shell_apitest.cc
@@ -6,6 +6,7 @@ #include "base/files/file_path.h" #include "base/path_service.h" +#include "base/threading/thread_restrictions.h" #include "content/public/browser/notification_service.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/notification_types.h" @@ -22,6 +23,7 @@ } const Extension* ShellApiTest::LoadApp(const std::string& app_dir) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath test_data_dir; PathService::Get(extensions::DIR_TEST_DATA, &test_data_dir); test_data_dir = test_data_dir.AppendASCII(app_dir);
diff --git a/extensions/shell/test/shell_test.cc b/extensions/shell/test/shell_test.cc index a6930d9..ccfaed9 100644 --- a/extensions/shell/test/shell_test.cc +++ b/extensions/shell/test/shell_test.cc
@@ -55,9 +55,6 @@ extension_system_->Init(); DCHECK(base::MessageLoopForUI::IsCurrent()); base::RunLoop().RunUntilIdle(); - - // TODO(jam): remove this. - disable_io_checks(); } void AppShellTest::PostRunTestOnMainThread() {
diff --git a/headless/lib/browser/headless_tab_socket_impl.h b/headless/lib/browser/headless_tab_socket_impl.h index 7990dc7..93cc610 100644 --- a/headless/lib/browser/headless_tab_socket_impl.h +++ b/headless/lib/browser/headless_tab_socket_impl.h
@@ -31,14 +31,15 @@ void CreateMojoService(mojo::InterfaceRequest<TabSocket> request); private: - mojo::BindingSet<TabSocket> mojo_bindings_; - base::Lock lock_; // Protects everything below. AwaitNextMessageFromEmbedderCallback waiting_for_message_cb_; std::list<std::string> outgoing_message_queue_; std::list<std::string> incoming_message_queue_; Listener* listener_; // NOT OWNED + // Must be listed last so it gets destructed before |waiting_for_message_cb_|. + mojo::BindingSet<TabSocket> mojo_bindings_; + DISALLOW_COPY_AND_ASSIGN(HeadlessTabSocketImpl); };
diff --git a/headless/lib/headless_web_contents_browsertest.cc b/headless/lib/headless_web_contents_browsertest.cc index 07a542fa..bf11b95 100644 --- a/headless/lib/headless_web_contents_browsertest.cc +++ b/headless/lib/headless_web_contents_browsertest.cc
@@ -190,6 +190,11 @@ class HeadlessTabSocketTest : public HeadlessAsyncDevTooledBrowserTest, public HeadlessTabSocket::Listener { public: + void SetUp() override { + options()->mojo_service_names.insert("headless::TabSocket"); + HeadlessAsyncDevTooledBrowserTest::SetUp(); + } + void RunDevTooledTest() override { devtools_client_->GetRuntime()->Evaluate( R"(window.TabSocket.onmessage =
diff --git a/ios/chrome/browser/ui/payments/payment_request_coordinator.mm b/ios/chrome/browser/ui/payments/payment_request_coordinator.mm index f0e9e6d6..68fb049 100644 --- a/ios/chrome/browser/ui/payments/payment_request_coordinator.mm +++ b/ios/chrome/browser/ui/payments/payment_request_coordinator.mm
@@ -220,8 +220,23 @@ ? base::ASCIIToUTF16("basic-card") : base::ASCIIToUTF16(basic_card_type); + // Get the billing address + autofill::AutofillProfile billingAddress; + + // TODO(crbug.com/714768): Make sure the billing address is set and valid + // before getting here. Once the bug is addressed, there will be no need to + // copy the address, *billing_address_ptr can be used to get the basic card + // response. + if (!card.billing_address_id().empty()) { + autofill::AutofillProfile* billingAddressPtr = + autofill::PersonalDataManager::GetProfileFromProfilesByGUID( + card.billing_address_id(), _paymentRequest->billing_profiles()); + if (billingAddressPtr) + billingAddress = *billingAddressPtr; + } + paymentResponse.details = GetBasicCardResponseFromAutofillCreditCard( - card, cvc, _paymentRequest->billing_profiles(), + card, cvc, billingAddress, GetApplicationContext()->GetApplicationLocale()); if (_paymentRequest->request_shipping()) {
diff --git a/ios/web/app/web_main_loop.mm b/ios/web/app/web_main_loop.mm index 55c274d..8d79449 100644 --- a/ios/web/app/web_main_loop.mm +++ b/ios/web/app/web_main_loop.mm
@@ -71,6 +71,10 @@ WebMainLoop::WebMainLoop() : result_code_(0), created_threads_(false) { DCHECK(!g_current_web_main_loop); g_current_web_main_loop = this; + + // Use an empty string as TaskScheduler name to match the suffix of browser + // process TaskScheduler histograms. + base::TaskScheduler::Create(""); } WebMainLoop::~WebMainLoop() { @@ -145,14 +149,15 @@ } int WebMainLoop::CreateThreads() { - auto task_scheduler_init_params = - GetWebClient()->GetTaskSchedulerInitParams(); - if (!task_scheduler_init_params) - task_scheduler_init_params = GetDefaultTaskSchedulerInitParams(); - DCHECK(task_scheduler_init_params); - - base::TaskScheduler::CreateAndSetDefaultTaskScheduler( - "", *task_scheduler_init_params.get()); + { + auto task_scheduler_init_params = + GetWebClient()->GetTaskSchedulerInitParams(); + if (!task_scheduler_init_params) + task_scheduler_init_params = GetDefaultTaskSchedulerInitParams(); + DCHECK(task_scheduler_init_params); + base::TaskScheduler::GetInstance()->Start( + *task_scheduler_init_params.get()); + } GetWebClient()->PerformExperimentalTaskSchedulerRedirections();
diff --git a/media/base/eme_constants.h b/media/base/eme_constants.h index 1d9fd910..a3acdb9 100644 --- a/media/base/eme_constants.h +++ b/media/base/eme_constants.h
@@ -31,18 +31,28 @@ EME_CODEC_MP4_AVC1 = 1 << 5, EME_CODEC_COMMON_VP9 = 1 << 6, EME_CODEC_MP4_HEVC = 1 << 7, + EME_CODEC_MP4_DV_AVC = 1 << 8, + EME_CODEC_MP4_DV_HEVC = 1 << 9, EME_CODEC_WEBM_AUDIO_ALL = EME_CODEC_WEBM_OPUS | EME_CODEC_WEBM_VORBIS, EME_CODEC_WEBM_VIDEO_ALL = (EME_CODEC_WEBM_VP8 | EME_CODEC_WEBM_VP9 | EME_CODEC_COMMON_VP9), EME_CODEC_WEBM_ALL = (EME_CODEC_WEBM_AUDIO_ALL | EME_CODEC_WEBM_VIDEO_ALL), #if BUILDFLAG(USE_PROPRIETARY_CODECS) EME_CODEC_MP4_AUDIO_ALL = EME_CODEC_MP4_AAC, -#if !BUILDFLAG(ENABLE_HEVC_DEMUXING) - EME_CODEC_MP4_VIDEO_ALL = (EME_CODEC_MP4_AVC1 | EME_CODEC_COMMON_VP9), -#else - EME_CODEC_MP4_VIDEO_ALL = - (EME_CODEC_MP4_AVC1 | EME_CODEC_COMMON_VP9 | EME_CODEC_MP4_HEVC), -#endif + EME_CODEC_MP4_VIDEO_ALL = (EME_CODEC_MP4_AVC1 | EME_CODEC_COMMON_VP9 +#if BUILDFLAG(ENABLE_HEVC_DEMUXING) + | + EME_CODEC_MP4_HEVC +#endif // BUILDFLAG(ENABLE_HEVC_DEMUXING) +#if BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING) + | + EME_CODEC_MP4_DV_AVC +#if BUILDFLAG(ENABLE_HEVC_DEMUXING) + | + EME_CODEC_MP4_DV_HEVC +#endif // BUILDFLAG(ENABLE_HEVC_DEMUXING) +#endif // BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING) + ), EME_CODEC_MP4_ALL = (EME_CODEC_MP4_AUDIO_ALL | EME_CODEC_MP4_VIDEO_ALL), EME_CODEC_AUDIO_ALL = (EME_CODEC_WEBM_AUDIO_ALL | EME_CODEC_MP4_AUDIO_ALL), EME_CODEC_VIDEO_ALL = (EME_CODEC_WEBM_VIDEO_ALL | EME_CODEC_MP4_VIDEO_ALL),
diff --git a/media/base/key_systems.cc b/media/base/key_systems.cc index 41f83b58..708750a 100644 --- a/media/base/key_systems.cc +++ b/media/base/key_systems.cc
@@ -45,7 +45,7 @@ {"video/webm", EME_CODEC_WEBM_VIDEO_ALL}, #if BUILDFLAG(USE_PROPRIETARY_CODECS) {"audio/mp4", EME_CODEC_MP4_AUDIO_ALL}, - {"video/mp4", EME_CODEC_MP4_VIDEO_ALL} + {"video/mp4", EME_CODEC_MP4_VIDEO_ALL}, #endif // BUILDFLAG(USE_PROPRIETARY_CODECS) }; @@ -66,6 +66,14 @@ {"hev1", EME_CODEC_MP4_HEVC}, // HEV1. {"hvc1", EME_CODEC_MP4_HEVC}, // HVC1. #endif +#if BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING) + {"dva1", EME_CODEC_MP4_DV_AVC}, // DolbyVision AVC + {"dvav", EME_CODEC_MP4_DV_AVC}, // DolbyVision AVC +#if BUILDFLAG(ENABLE_HEVC_DEMUXING) + {"dvh1", EME_CODEC_MP4_DV_HEVC}, // DolbyVision HEVC + {"dvhe", EME_CODEC_MP4_DV_HEVC}, // DolbyVision HEVC +#endif +#endif #endif // BUILDFLAG(USE_PROPRIETARY_CODECS) };
diff --git a/media/base/media_url_demuxer.cc b/media/base/media_url_demuxer.cc index 190ff244..653d481 100644 --- a/media/base/media_url_demuxer.cc +++ b/media/base/media_url_demuxer.cc
@@ -75,13 +75,9 @@ void MediaUrlDemuxer::OnEnabledAudioTracksChanged( const std::vector<MediaTrack::Id>& track_ids, - base::TimeDelta curr_time) { - NOTIMPLEMENTED(); -} + base::TimeDelta curr_time) {} void MediaUrlDemuxer::OnSelectedVideoTrackChanged( base::Optional<MediaTrack::Id> selected_track_id, - base::TimeDelta curr_time) { - NOTIMPLEMENTED(); -} + base::TimeDelta curr_time) {} } // namespace media
diff --git a/media/base/renderer_factory.cc b/media/base/renderer_factory.cc index 2824baa..693520b 100644 --- a/media/base/renderer_factory.cc +++ b/media/base/renderer_factory.cc
@@ -6,10 +6,12 @@ namespace media { -RendererFactory::RendererFactory() { -} +RendererFactory::RendererFactory() {} -RendererFactory::~RendererFactory() { +RendererFactory::~RendererFactory() {} + +MediaResource::Type RendererFactory::GetRequiredMediaResourceType() { + return MediaResource::Type::STREAM; } } // namespace media
diff --git a/media/base/renderer_factory.h b/media/base/renderer_factory.h index f0a375f..c65f960 100644 --- a/media/base/renderer_factory.h +++ b/media/base/renderer_factory.h
@@ -10,6 +10,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "media/base/media_export.h" +#include "media/base/media_resource.h" #include "media/base/renderer.h" #include "media/base/surface_manager.h" @@ -41,6 +42,11 @@ VideoRendererSink* video_renderer_sink, const RequestSurfaceCB& request_surface_cb) = 0; + // Returns the MediaResource::Type that should be used with the renderers + // created by this factory. + // NOTE: Returns Type::STREAM by default. + virtual MediaResource::Type GetRequiredMediaResourceType(); + private: DISALLOW_COPY_AND_ASSIGN(RendererFactory); };
diff --git a/media/base/renderer_factory_selector.cc b/media/base/renderer_factory_selector.cc index 49e3fce0..3eb41fc 100644 --- a/media/base/renderer_factory_selector.cc +++ b/media/base/renderer_factory_selector.cc
@@ -23,22 +23,38 @@ void RendererFactorySelector::SetBaseFactoryType(FactoryType type) { DCHECK(factories_[type]); base_factory_type_ = type; + current_factory_needs_update_ = true; } -RendererFactory* RendererFactorySelector::GetCurrentFactory() { +// For the moment, this method should only be called once or twice. +// This method will be regularly called whenever the logic in choosing a +// renderer type is moved out of the AdaptiveRendererFactory, into this method. +void RendererFactorySelector::UpdateCurrentFactory() { DCHECK(base_factory_type_); FactoryType next_factory_type = base_factory_type_.value(); - RendererFactory* factory = factories_[next_factory_type].get(); + if (use_media_player_) + next_factory_type = FactoryType::MEDIA_PLAYER; - if (factory == nullptr) { - NOTREACHED(); - return nullptr; - } + DVLOG(1) << __func__ << " Selecting factory type: " << next_factory_type; - DVLOG(1) << __func__ << " Selected factory type: " << next_factory_type; - - return factory; + current_factory_ = factories_[next_factory_type].get(); + current_factory_needs_update_ = false; } +RendererFactory* RendererFactorySelector::GetCurrentFactory() { + if (current_factory_needs_update_) + UpdateCurrentFactory(); + + DCHECK(current_factory_); + return current_factory_; +} + +#if defined(OS_ANDROID) +void RendererFactorySelector::SetUseMediaPlayer(bool use_media_player) { + use_media_player_ = use_media_player; + current_factory_needs_update_ = true; +} +#endif + } // namespace media
diff --git a/media/base/renderer_factory_selector.h b/media/base/renderer_factory_selector.h index 4a6f4e05..d40c20a 100644 --- a/media/base/renderer_factory_selector.h +++ b/media/base/renderer_factory_selector.h
@@ -36,11 +36,24 @@ // be used by default. void SetBaseFactoryType(FactoryType type); - // SetBaseFactoryType() must be called before calling this method. - // NOTE: This only returns the base factory type at the moment. + // Updates |current_factory_| if necessary, and returns its value. + // NOTE: SetBaseFactoryType() must be called before calling this method. RendererFactory* GetCurrentFactory(); +#if defined(OS_ANDROID) + // Sets whether we should be using the MEDIA_PLAYER factory instead of the + // base factory. + void SetUseMediaPlayer(bool use_media_player); +#endif + private: + void UpdateCurrentFactory(); + + bool use_media_player_ = false; + + bool current_factory_needs_update_ = true; + RendererFactory* current_factory_ = nullptr; + base::Optional<FactoryType> base_factory_type_; std::unique_ptr<RendererFactory> factories_[FACTORY_TYPE_MAX + 1]; DISALLOW_COPY_AND_ASSIGN(RendererFactorySelector);
diff --git a/media/base/renderer_factory_selector_unittest.cc b/media/base/renderer_factory_selector_unittest.cc index b920866..20241264 100644 --- a/media/base/renderer_factory_selector_unittest.cc +++ b/media/base/renderer_factory_selector_unittest.cc
@@ -70,4 +70,21 @@ EXPECT_EQ(FactoryType::MOJO, GetCurrentlySelectedFactoryType()); } +#if defined(OS_ANDROID) +TEST_F(RendererFactorySelectorTest, SetUseMediaPlayer) { + AddFactory(FactoryType::DEFAULT); + AddFactory(FactoryType::MEDIA_PLAYER); + selector_.SetBaseFactoryType(FactoryType::DEFAULT); + + selector_.SetUseMediaPlayer(false); + EXPECT_EQ(FactoryType::DEFAULT, GetCurrentlySelectedFactoryType()); + + selector_.SetUseMediaPlayer(true); + EXPECT_EQ(FactoryType::MEDIA_PLAYER, GetCurrentlySelectedFactoryType()); + + selector_.SetUseMediaPlayer(false); + EXPECT_EQ(FactoryType::DEFAULT, GetCurrentlySelectedFactoryType()); +} +#endif + } // namespace media
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc index e1f11db4..97695bee 100644 --- a/media/blink/webmediaplayer_impl.cc +++ b/media/blink/webmediaplayer_impl.cc
@@ -235,7 +235,6 @@ overlay_surface_id_(SurfaceManager::kNoSurfaceID), suppress_destruction_errors_(false), suspend_enabled_(params->allow_suspend()), - use_fallback_path_(false), is_encrypted_(false), preroll_attempt_pending_(false), observer_(params->media_observer()), @@ -405,8 +404,8 @@ // Set subresource URL for crash reporting. base::debug::SetCrashKeyValue("subresource_url", gurl.spec()); - if (use_fallback_path_) - fallback_url_ = gurl; + // Used for HLS playback. + loaded_url_ = gurl; load_type_ = load_type; @@ -816,9 +815,10 @@ const bool is_finite_stream = data_source_ && data_source_->IsStreaming() && std::isfinite(seekable_end); - // Do not change the seekable range when using the fallback path. - // The MediaPlayerRenderer will take care of dropping invalid seeks. - const bool force_seeks_to_zero = !use_fallback_path_ && is_finite_stream; + // Do not change the seekable range when using the MediaPlayerRenderer. It + // will take care of dropping invalid seeks. + const bool force_seeks_to_zero = + !using_media_player_renderer_ && is_finite_stream; // TODO(dalecurtis): Technically this allows seeking on media which return an // infinite duration so long as DataSource::IsStreaming() is false. While not @@ -1611,10 +1611,6 @@ cast_impl_.SetDeviceScaleFactor(scale_factor); } -void WebMediaPlayerImpl::SetUseFallbackPath(bool use_fallback_path) { - use_fallback_path_ = use_fallback_path; -} - void WebMediaPlayerImpl::SetPoster(const blink::WebURL& poster) { cast_impl_.setPoster(poster); } @@ -1626,18 +1622,15 @@ #if defined(OS_ANDROID) // We can't play HLS URLs with WebMediaPlayerImpl, so in cases where they are - // encountered, instruct the HTML media element to create a new WebMediaPlayer - // instance with the correct URL to trigger the creation of WMPI with a - // MediaPlayerRendererFactory instead. + // encountered, instruct the HTML media element to use the MediaPlayerRenderer + // instead. // - // TODO(tguilbert): Allow 'hotswapping' renderer factories to prevent reloads - // and/or rely on demuxer extracted MediaContainerNames. See crbug.com/663503. - if (data_source_ && !use_fallback_path_) { + // TODO(tguilbert): Detect the presence of HLS based on demuxing results, + // rather than the URL string. See crbug.com/663503. + if (data_source_) { const GURL url_after_redirects = data_source_->GetUrlAfterRedirects(); if (MediaCodecUtil::IsHLSURL(url_after_redirects)) { - client_->RequestReload(url_after_redirects); - // |this| may be destructed, do nothing after this. - return; + renderer_factory_selector_->SetUseMediaPlayer(true); } } #endif @@ -1683,7 +1676,6 @@ const SurfaceCreatedCB& set_surface_cb) { DCHECK(main_task_runner_->BelongsToCurrentThread()); DCHECK(surface_manager_); - DCHECK(!use_fallback_path_); // A null callback indicates that the decoder is going away. if (set_surface_cb.is_null()) { @@ -1733,9 +1725,20 @@ BindToCurrentLoop(base::Bind( &WebMediaPlayerImpl::OnEncryptedMediaInitData, AsWeakPtr())); - if (use_fallback_path_) { + if (renderer_factory_selector_->GetCurrentFactory() + ->GetRequiredMediaResourceType() == MediaResource::Type::URL) { + if (data_source_) + loaded_url_ = data_source_->GetUrlAfterRedirects(); + + // MediaPlayerRendererClient factory is the only factory that a + // MediaResource::Type::URL for the moment. This might no longer be true + // when we remove WebMediaPlayerCast. + // + // TODO(tguilbert/avayvod): Update this flag when removing |cast_impl_|. + using_media_player_renderer_ = true; + demuxer_.reset( - new MediaUrlDemuxer(media_task_runner_, fallback_url_, + new MediaUrlDemuxer(media_task_runner_, loaded_url_, frame_->GetDocument().FirstPartyForCookies())); pipeline_controller_.Start(demuxer_.get(), this, false, false); return;
diff --git a/media/blink/webmediaplayer_impl.h b/media/blink/webmediaplayer_impl.h index dd29a33..de05e09 100644 --- a/media/blink/webmediaplayer_impl.h +++ b/media/blink/webmediaplayer_impl.h
@@ -656,8 +656,15 @@ // Used for HLS playback and in certain fallback paths (e.g. on older devices // that can't support the unified media pipeline). - GURL fallback_url_; - bool use_fallback_path_; + GURL loaded_url_; + + // NOTE: |using_media_player_renderer_| is set based on the usage of a + // MediaResource::Type::URL in StartPipeline(). This currently works because + // the MediaPlayerRendererClient factory is the only factory that returns that + // Type, but this may no longer be accurate when we remove |cast_impl_| and + // WebMediaPlayerCast. This flag should be renamed/updated accordingly when + // removing |cast_impl_|. + bool using_media_player_renderer_ = false; // Called sometime after the media is suspended in a playing state in // OnFrameHidden(), causing the state to change to paused.
diff --git a/mojo/public/interfaces/bindings/tests/test_associated_interfaces.mojom b/mojo/public/interfaces/bindings/tests/test_associated_interfaces.mojom index 3858330a..6df1e8b 100644 --- a/mojo/public/interfaces/bindings/tests/test_associated_interfaces.mojom +++ b/mojo/public/interfaces/bindings/tests/test_associated_interfaces.mojom
@@ -40,6 +40,11 @@ Send(int32 value); }; +interface StringSender { + Echo(string value) => (string value); + Send(string value); +}; + interface IntegerSenderConnection { GetSender(associated IntegerSender& sender); AsyncGetSender() => (associated IntegerSender sender); @@ -50,6 +55,11 @@ SetSender(associated IntegerSender sender) => (int32 value); }; +interface SenderConnection { + GetIntegerSender(associated IntegerSender& sender); + GetStringSender(associated StringSender& sender); +}; + interface AssociatedPingProvider { GetPing(associated PingService& request); };
diff --git a/mojo/public/js/connector.js b/mojo/public/js/connector.js index 012e3c7..d51b429 100644 --- a/mojo/public/js/connector.js +++ b/mojo/public/js/connector.js
@@ -18,6 +18,7 @@ this.incomingReceiver_ = null; this.readWatcher_ = null; this.errorHandler_ = null; + this.paused_ = false; if (handle) { this.readWatcher_ = support.watch(handle, @@ -37,6 +38,31 @@ } }; + Connector.prototype.pauseIncomingMethodCallProcessing = function() { + if (this.paused_) { + return; + } + this.paused_= true; + + if (this.readWatcher_) { + support.cancelWatch(this.readWatcher_); + this.readWatcher_ = null; + } + }; + + Connector.prototype.resumeIncomingMethodCallProcessing = function() { + if (!this.paused_) { + return; + } + this.paused_= false; + + if (this.handle_) { + this.readWatcher_ = support.watch(this.handle_, + core.HANDLE_SIGNAL_READABLE, + this.readMore_.bind(this)); + } + }; + Connector.prototype.accept = function(message) { if (this.error_) return false; @@ -85,6 +111,10 @@ Connector.prototype.readMore_ = function(result) { for (;;) { + if (this.paused_) { + return; + } + var read = core.readMessage(this.handle_, core.READ_MESSAGE_FLAG_NONE); if (this.handle_ == null) // The connector has been closed.
diff --git a/mojo/public/js/router.js b/mojo/public/js/router.js index 401a222..dfe7c28 100644 --- a/mojo/public/js/router.js +++ b/mojo/public/js/router.js
@@ -72,6 +72,9 @@ }); this.setInterfaceIdNamespaceBit_ = setInterfaceIdNamespaceBit; + // |cachedMessageData| caches infomation about a message, so it can be + // processed later if a client is not yet attached to the target endpoint. + this.cachedMessageData = null; this.controlMessageHandler_ = new PipeControlMessageHandler(this); this.controlMessageProxy_ = new PipeControlMessageProxy(this.connector_); this.nextInterfaceIdValue_ = 1; @@ -132,6 +135,31 @@ endpoint.client.notifyError.bind(endpoint.client)); } + if (this.cachedMessageData && interfaceEndpointHandle.id() === + this.cachedMessageData.message.getInterfaceId()) { + timer.createOneShot(0, (function() { + if (!this.cachedMessageData) { + return; + } + + var targetEndpoint = this.endpoints_.get( + this.cachedMessageData.message.getInterfaceId()); + // Check that the target endpoint's client still exists. + if (targetEndpoint && targetEndpoint.client) { + var message = this.cachedMessageData.message; + var messageValidator = this.cachedMessageData.messageValidator; + this.cachedMessageData = null; + this.connector_.resumeIncomingMethodCallProcessing(); + var ok = endpoint.client.handleIncomingMessage(message, + messageValidator); + + if (!ok) { + this.handleInvalidIncomingMessage_(); + } + } + }).bind(this)); + } + return endpoint; }; @@ -199,9 +227,10 @@ if (!endpoint.client) { // We need to wait until a client is attached in order to dispatch // further messages. - // TODO(wangjimmy): Cache the message and send when the appropriate - // endpoint client is attached. - return false; + this.cachedMessageData = {message: message, + messageValidator: messageValidator}; + this.connector_.pauseIncomingMethodCallProcessing(); + return true; } ok = endpoint.client.handleIncomingMessage(message, messageValidator); } @@ -290,6 +319,12 @@ if (!types.isMasterInterfaceId(interfaceId) || reason) { this.controlMessageProxy_.notifyPeerEndpointClosed(interfaceId, reason); } + + if (this.cachedMessageData && interfaceId === + this.cachedMessageData.message.getInterfaceId()) { + this.cachedMessageData = null; + this.connector_.resumeIncomingMethodCallProcessing(); + } }; Router.prototype.updateEndpointStateMayRemove = function(endpoint,
diff --git a/net/http/http_cache.cc b/net/http/http_cache.cc index 968cffa..42f8c17 100644 --- a/net/http/http_cache.cc +++ b/net/http/http_cache.cc
@@ -96,28 +96,29 @@ //----------------------------------------------------------------------------- HttpCache::ActiveEntry::ActiveEntry(disk_cache::Entry* entry) - : disk_entry(entry), - writer(NULL), - will_process_pending_queue(false), - doomed(false) { -} + : disk_entry(entry) {} HttpCache::ActiveEntry::~ActiveEntry() { if (disk_entry) { disk_entry->Close(); - disk_entry = NULL; + disk_entry = nullptr; } } size_t HttpCache::ActiveEntry::EstimateMemoryUsage() const { // Skip |disk_entry| which is tracked in simple_backend_impl; Skip |readers| - // and |pending_queue| because the Transactions are owned by their respective - // URLRequestHttpJobs. + // and |add_to_entry_queue| because the Transactions are owned by their + // respective URLRequestHttpJobs. return 0; } bool HttpCache::ActiveEntry::HasNoTransactions() { - return !writer && readers.empty() && pending_queue.empty(); + return !writer && readers.empty() && add_to_entry_queue.empty() && + done_headers_queue.empty() && !headers_transaction; +} + +bool HttpCache::ActiveEntry::HasNoActiveTransactions() { + return !writer && readers.empty() && !headers_transaction; } //----------------------------------------------------------------------------- @@ -342,15 +343,17 @@ weak_factory_.InvalidateWeakPtrs(); // If we have any active entries remaining, then we need to deactivate them. - // We may have some pending calls to OnProcessPendingQueue, but since those - // won't run (due to our destruction), we can simply ignore the corresponding - // will_process_pending_queue flag. + // We may have some pending tasks to process queued transactions ,but since + // those won't run (due to our destruction), we can simply ignore the + // corresponding flags. while (!active_entries_.empty()) { ActiveEntry* entry = active_entries_.begin()->second.get(); - entry->will_process_pending_queue = false; - entry->pending_queue.clear(); + entry->will_process_queued_transactions = false; + entry->add_to_entry_queue.clear(); entry->readers.clear(); - entry->writer = NULL; + entry->done_headers_queue.clear(); + entry->headers_transaction = nullptr; + entry->writer = nullptr; DeactivateEntry(entry); } @@ -611,7 +614,8 @@ entry_ptr->doomed = true; DCHECK(entry_ptr->writer || !entry_ptr->readers.empty() || - entry_ptr->will_process_pending_queue); + entry_ptr->headers_transaction || + entry_ptr->will_process_queued_transactions); return OK; } @@ -667,7 +671,7 @@ HttpCache::ActiveEntry* HttpCache::FindActiveEntry(const std::string& key) { auto it = active_entries_.find(key); - return it != active_entries_.end() ? it->second.get() : NULL; + return it != active_entries_.end() ? it->second.get() : nullptr; } HttpCache::ActiveEntry* HttpCache::ActivateEntry( @@ -679,7 +683,7 @@ } void HttpCache::DeactivateEntry(ActiveEntry* entry) { - DCHECK(!entry->will_process_pending_queue); + DCHECK(!entry->will_process_queued_transactions); DCHECK(!entry->doomed); DCHECK(entry->disk_entry); DCHECK(entry->HasNoTransactions()); @@ -809,121 +813,261 @@ } } -int HttpCache::AddTransactionToEntry(ActiveEntry* entry, Transaction* trans) { +int HttpCache::AddTransactionToEntry(ActiveEntry* entry, + Transaction* transaction) { DCHECK(entry); DCHECK(entry->disk_entry); - - // We implement a basic reader/writer lock for the disk cache entry. If - // there is already a writer, then everyone has to wait for the writer to - // finish before they can access the cache entry. There can be multiple - // readers. - // - // NOTE: If the transaction can only write, then the entry should not be in - // use (since any existing entry should have already been doomed). - - if (entry->writer || entry->will_process_pending_queue) { - entry->pending_queue.push_back(trans); - return ERR_IO_PENDING; - } - - if (trans->mode() & Transaction::WRITE) { - // transaction needs exclusive access to the entry - if (entry->readers.empty()) { - entry->writer = trans; - } else { - entry->pending_queue.push_back(trans); - return ERR_IO_PENDING; - } - } else { - // transaction needs read access to the entry - entry->readers.insert(trans); - } - - // We do this before calling EntryAvailable to force any further calls to - // AddTransactionToEntry to add their transaction to the pending queue, which - // ensures FIFO ordering. - if (!entry->writer && !entry->pending_queue.empty()) - ProcessPendingQueue(entry); - - return OK; + // Always add a new transaction to the queue to maintain FIFO order. + entry->add_to_entry_queue.push_back(transaction); + ProcessQueuedTransactions(entry); + return ERR_IO_PENDING; } -void HttpCache::DoneWithEntry(ActiveEntry* entry, Transaction* trans, +int HttpCache::DoneWithResponseHeaders(ActiveEntry* entry, + Transaction* transaction) { + // If |transaction| is the current writer, do nothing. This can happen for + // range requests since they can go back to headers phase after starting to + // write. + if (entry->writer == transaction) + return OK; + + DCHECK_EQ(entry->headers_transaction, transaction); + + entry->headers_transaction = nullptr; + + // If transaction is responsible for writing the response body, then do not go + // through done_headers_queue for performance benefit. (Also, in case of + // writer transaction, the consumer sometimes depend on synchronous behaviour + // e.g. while computing raw headers size. (crbug.com/711766)) + if (transaction->mode() & Transaction::WRITE) { + DCHECK(entry->done_headers_queue.empty()); + DCHECK(!entry->writer); + entry->writer = transaction; + ProcessQueuedTransactions(entry); + return OK; + } + + // If this is not the first transaction in done_headers_queue, it should be a + // read-mode transaction. + DCHECK(entry->done_headers_queue.empty() || + !(transaction->mode() & Transaction::WRITE)); + + entry->done_headers_queue.push_back(transaction); + ProcessQueuedTransactions(entry); + return ERR_IO_PENDING; +} + +void HttpCache::DoneWithEntry(ActiveEntry* entry, + Transaction* transaction, bool cancel) { - // If we already posted a task to move on to the next transaction and this was - // the writer, there is nothing to cancel. - if (entry->will_process_pending_queue && entry->readers.empty()) + // Transaction is waiting in the done_headers_queue. + auto it = std::find(entry->done_headers_queue.begin(), + entry->done_headers_queue.end(), transaction); + if (it != entry->done_headers_queue.end()) { + entry->done_headers_queue.erase(it); + if (cancel) + ProcessEntryFailure(entry); return; + } - if (entry->writer) { - DCHECK(trans == entry->writer); + // Transaction is removed in the headers phase. + if (transaction == entry->headers_transaction) { + // If the response is not written (cancel is true), consider it a failure. + DoneWritingToEntry(entry, !cancel, transaction); + return; + } + // Transaction is removed in the writing phase. + if (transaction == entry->writer) { // Assume there was a failure. bool success = false; if (cancel) { DCHECK(entry->disk_entry); // This is a successful operation in the sense that we want to keep the // entry. - success = trans->AddTruncatedFlag(); + success = transaction->AddTruncatedFlag(); // The previous operation may have deleted the entry. - if (!trans->entry()) + if (!transaction->entry()) return; } - DoneWritingToEntry(entry, success); - } else { - DoneReadingFromEntry(entry, trans); + DoneWritingToEntry(entry, success, transaction); + return; } + + // Transaction is reading from the entry. + DoneReadingFromEntry(entry, transaction); } -void HttpCache::DoneWritingToEntry(ActiveEntry* entry, bool success) { - DCHECK(entry->readers.empty()); +void HttpCache::DoneWritingToEntry(ActiveEntry* entry, + bool success, + Transaction* transaction) { + DCHECK(transaction == entry->writer || + transaction == entry->headers_transaction); - entry->writer = NULL; + if (transaction == entry->writer) + entry->writer = nullptr; + else + entry->headers_transaction = nullptr; - if (success) { - ProcessPendingQueue(entry); - } else { - DCHECK(!entry->will_process_pending_queue); - - // We failed to create this entry. - TransactionList pending_queue; - pending_queue.swap(entry->pending_queue); - - entry->disk_entry->Doom(); - DestroyEntry(entry); - - // We need to do something about these pending entries, which now need to - // be added to a new entry. - while (!pending_queue.empty()) { - // ERR_CACHE_RACE causes the transaction to restart the whole process. - pending_queue.front()->io_callback().Run(ERR_CACHE_RACE); - pending_queue.pop_front(); - } + // If writer fails, restart the headers_transaction by setting its state. + // Since the headers_transactions is awaiting an asynchronous operation + // completion, when it's IO callback is invoked, it will be restarted. + if (!success && entry->headers_transaction) { + entry->headers_transaction->SetValidatingCannotProceed(); + entry->headers_transaction = nullptr; + DCHECK(entry->HasNoActiveTransactions()); } + if (!success) + ProcessEntryFailure(entry); + else + ProcessQueuedTransactions(entry); } -void HttpCache::DoneReadingFromEntry(ActiveEntry* entry, Transaction* trans) { +void HttpCache::DoneReadingFromEntry(ActiveEntry* entry, + Transaction* transaction) { DCHECK(!entry->writer); - - auto it = entry->readers.find(trans); + auto it = entry->readers.find(transaction); DCHECK(it != entry->readers.end()); - entry->readers.erase(it); - ProcessPendingQueue(entry); + ProcessQueuedTransactions(entry); } -void HttpCache::ConvertWriterToReader(ActiveEntry* entry) { - DCHECK(entry->writer); - DCHECK(entry->writer->mode() == Transaction::READ_WRITE); - DCHECK(entry->readers.empty()); +void HttpCache::RemoveAllQueuedTransactions(ActiveEntry* entry, + TransactionList* list) { + // Process done_headers_queue before add_to_entry_queue to maintain FIFO + // order. + for (auto* transaction : entry->done_headers_queue) + list->push_back(transaction); + entry->done_headers_queue.clear(); - Transaction* trans = entry->writer; + for (auto* transaction : entry->add_to_entry_queue) + list->push_back(transaction); + entry->add_to_entry_queue.clear(); +} - entry->writer = NULL; - entry->readers.insert(trans); +void HttpCache::ProcessEntryFailure(ActiveEntry* entry) { + // Failure case is either writer failing to completely write the response to + // the cache or validating transaction received a non-304 response. + TransactionList list; + if (entry->HasNoActiveTransactions() && + !entry->will_process_queued_transactions) { + entry->disk_entry->Doom(); + RemoveAllQueuedTransactions(entry, &list); + DestroyEntry(entry); + } else { + DoomActiveEntry(entry->disk_entry->GetKey()); + RemoveAllQueuedTransactions(entry, &list); + } + // ERR_CACHE_RACE causes the transaction to restart the whole process. + for (auto* transaction : list) + transaction->io_callback().Run(net::ERR_CACHE_RACE); +} - ProcessPendingQueue(entry); +void HttpCache::ProcessQueuedTransactions(ActiveEntry* entry) { + // Multiple readers may finish with an entry at once, so we want to batch up + // calls to OnProcessQueuedTransactions. This flag also tells us that we + // should not delete the entry before OnProcessQueuedTransactions runs. + if (entry->will_process_queued_transactions) + return; + + entry->will_process_queued_transactions = true; + + // Post a task instead of invoking the io callback of another transaction here + // to avoid re-entrancy. + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::Bind(&HttpCache::OnProcessQueuedTransactions, GetWeakPtr(), entry)); +} + +void HttpCache::ProcessAddToEntryQueue(ActiveEntry* entry) { + DCHECK(!entry->add_to_entry_queue.empty()); + + // Note the entry may be new or may already have a response body written to + // it. In both cases, a transaction needs to wait since only one transaction + // can be in the headers phase at a time. + if (entry->headers_transaction) { + return; + } + Transaction* transaction = entry->add_to_entry_queue.front(); + entry->add_to_entry_queue.erase(entry->add_to_entry_queue.begin()); + entry->headers_transaction = transaction; + + transaction->io_callback().Run(OK); +} + +void HttpCache::ProcessDoneHeadersQueue(ActiveEntry* entry) { + DCHECK(!entry->writer); + DCHECK(!entry->done_headers_queue.empty()); + + Transaction* transaction = entry->done_headers_queue.front(); + + // If this transaction is responsible for writing the response body. + if (transaction->mode() & Transaction::WRITE) { + entry->writer = transaction; + } else { + // If a transaction is in front of this queue with only read mode set and + // there is no writer, it implies response body is already written, convert + // to a reader. + auto return_val = entry->readers.insert(transaction); + DCHECK_EQ(return_val.second, true); + } + + // Post another task to give a chance to more transactions to either join + // readers or another transaction to start parallel validation. + ProcessQueuedTransactions(entry); + + entry->done_headers_queue.erase(entry->done_headers_queue.begin()); + transaction->io_callback().Run(OK); +} + +bool HttpCache::CanTransactionWriteResponseHeaders(ActiveEntry* entry, + Transaction* transaction, + bool is_match) const { + if (transaction != entry->headers_transaction) + return false; + + if (!(transaction->mode() & Transaction::WRITE)) + return false; + + // If its not a match then check if it is the transaction responsible for + // writing the response body. + if (!is_match) { + return !entry->writer && entry->done_headers_queue.empty() && + entry->readers.empty(); + } + + return true; +} + +bool HttpCache::IsTransactionWritingIncomplete( + ActiveEntry* entry, + Transaction* transaction, + const std::string& method) const { + if (transaction == entry->writer) + return true; + + if (method == "HEAD" || method == "DELETE") + return false; + + // Check if transaction is about to start writing to the cache. + + // Transaction's mode may have been set to NONE if StopCaching was invoked. + if (!(transaction->mode() & Transaction::WRITE || + transaction->mode() == Transaction::NONE)) { + return false; + } + + // If a transaction is completing headers or done with headers phase with + // write mode then it should be the future writer. Just checking the front of + // done_headers_queue since the rest should anyways be READ mode transactions + // as they would be a result of validation match. + return transaction == entry->headers_transaction || + transaction == entry->done_headers_queue.front(); +} + +bool HttpCache::IsWritingInProgress(ActiveEntry* entry) const { + return entry->writer != nullptr; } LoadState HttpCache::GetLoadStateForPendingTransaction( @@ -973,14 +1117,15 @@ } bool HttpCache::RemovePendingTransactionFromEntry(ActiveEntry* entry, - Transaction* trans) { - TransactionList& pending_queue = entry->pending_queue; + Transaction* transaction) { + TransactionList& add_to_entry_queue = entry->add_to_entry_queue; - auto j = find(pending_queue.begin(), pending_queue.end(), trans); - if (j == pending_queue.end()) + auto j = + find(add_to_entry_queue.begin(), add_to_entry_queue.end(), transaction); + if (j == add_to_entry_queue.end()) return false; - pending_queue.erase(j); + add_to_entry_queue.erase(j); return true; } @@ -1002,22 +1147,11 @@ return false; } -void HttpCache::ProcessPendingQueue(ActiveEntry* entry) { - // Multiple readers may finish with an entry at once, so we want to batch up - // calls to OnProcessPendingQueue. This flag also tells us that we should - // not delete the entry before OnProcessPendingQueue runs. - if (entry->will_process_pending_queue) - return; - entry->will_process_pending_queue = true; +void HttpCache::OnProcessQueuedTransactions(ActiveEntry* entry) { + entry->will_process_queued_transactions = false; - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::Bind(&HttpCache::OnProcessPendingQueue, GetWeakPtr(), entry)); -} - -void HttpCache::OnProcessPendingQueue(ActiveEntry* entry) { - entry->will_process_pending_queue = false; - DCHECK(!entry->writer); + // Note that this function should only invoke one transaction's IO callback + // since its possible for IO callbacks' consumers to destroy the cache/entry. // If no one is interested in this entry, then we can deactivate it. if (entry->HasNoTransactions()) { @@ -1025,20 +1159,22 @@ return; } - if (entry->pending_queue.empty()) + if (entry->done_headers_queue.empty() && entry->add_to_entry_queue.empty()) return; - // Promote next transaction from the pending queue. - Transaction* next = entry->pending_queue.front(); - if ((next->mode() & Transaction::WRITE) && !entry->readers.empty()) - return; // Have to wait. + // To maintain FIFO order of transactions, done_headers_queue should be + // checked for processing before add_to_entry_queue. - entry->pending_queue.erase(entry->pending_queue.begin()); - - int rv = AddTransactionToEntry(entry, next); - if (rv != ERR_IO_PENDING) { - next->io_callback().Run(rv); + // If another transaction is writing the response, let validated transactions + // wait till the response is complete. If the response is not yet started, the + // done_headers_queue transaction should start writing it. + if (!entry->writer && !entry->done_headers_queue.empty()) { + ProcessDoneHeadersQueue(entry); + return; } + + if (!entry->add_to_entry_queue.empty()) + ProcessAddToEntryQueue(entry); } void HttpCache::OnIOComplete(int result, PendingOp* pending_op) {
diff --git a/net/http/http_cache.h b/net/http/http_cache.h index 635cb92d..ca8ba08 100644 --- a/net/http/http_cache.h +++ b/net/http/http_cache.h
@@ -244,10 +244,32 @@ friend class ViewCacheHelper; struct PendingOp; // Info for an entry under construction. + // To help with testing. + friend class MockHttpCache; + using TransactionList = std::list<Transaction*>; using TransactionSet = std::unordered_set<Transaction*>; typedef std::list<std::unique_ptr<WorkItem>> WorkItemList; + // We implement a basic reader/writer lock for the disk cache entry. If there + // is a writer, then all transactions must wait to read the body. But the + // waiting transactions can start their headers phase in parallel. Headers + // phase is allowed for one transaction at a time so that if it doesn't match + // the existing headers, remaining transactions do not also try to match the + // existing entry in parallel leading to wasted network requests. If the + // headers do not match, this entry will be doomed. + // + // A transaction goes through these state transitions. + // + // Write mode transactions: + // add_to_entry_queue-> headers_transaction -> writer + // add_to_entry_queue-> headers_transaction -> done_headers_queue -> readers + // (once the data is written to the cache by another writer) + // + // Read only transactions: + // add_to_entry_queue-> headers_transaction -> done_headers_queue -> readers + // (once the data is written to the cache by the writer) + struct ActiveEntry { explicit ActiveEntry(disk_cache::Entry* entry); ~ActiveEntry(); @@ -256,12 +278,36 @@ // Returns true if no transactions are associated with this entry. bool HasNoTransactions(); - disk_cache::Entry* disk_entry; - Transaction* writer; + // Returns true if no active readers/writer transactions are associated + // with this entry. + bool HasNoActiveTransactions(); + + disk_cache::Entry* disk_entry = nullptr; + + // Transactions waiting to be added to entry. + TransactionList add_to_entry_queue; + + // Transaction currently in the headers phase, either validating the + // response or getting new headers. This can exist simultaneously with + // writer or readers while validating existing headers. + Transaction* headers_transaction = nullptr; + + // Transactions that have completed their headers phase and are waiting + // to read the response body or write the response body. + TransactionList done_headers_queue; + + // Transaction currently reading from the network and writing to the cache. + Transaction* writer = nullptr; + + // Transactions that can only read from the cache. Only one of writer or + // readers can exist at a time. TransactionSet readers; - TransactionList pending_queue; - bool will_process_pending_queue; - bool doomed; + + // The following variables are true if OnProcessQueuedTransactions is posted + bool will_process_queued_transactions = false; + + // True if entry is doomed. + bool doomed = false; }; using ActiveEntriesMap = @@ -342,28 +388,73 @@ // Destroys an ActiveEntry (active or doomed). void DestroyEntry(ActiveEntry* entry); - // Adds a transaction to an ActiveEntry. If this method returns ERR_IO_PENDING - // the transaction will be notified about completion via its IO callback. This - // method returns ERR_CACHE_RACE to signal the transaction that it cannot be - // added to the provided entry, and it should retry the process with another - // one (in this case, the entry is no longer valid). - int AddTransactionToEntry(ActiveEntry* entry, Transaction* trans); + // Adds a transaction to an ActiveEntry. This method returns ERR_IO_PENDING + // and the transaction will be notified about completion via its IO callback. + // In a failure case, the callback will be invoked with ERR_CACHE_RACE. + int AddTransactionToEntry(ActiveEntry* entry, Transaction* transaction); + + // Transaction invokes this when its response headers phase is complete + // If the transaction is responsible for writing the response body, + // it becomes the writer and returns OK. In other cases ERR_IO_PENDING is + // returned and the transaction will be notified about completion via its + // IO callback. In a failure case, the callback will be invoked with + // ERR_CACHE_RACE. + int DoneWithResponseHeaders(ActiveEntry* entry, Transaction* transaction); // Called when the transaction has finished working with this entry. |cancel| // is true if the operation was cancelled by the caller instead of running // to completion. - void DoneWithEntry(ActiveEntry* entry, Transaction* trans, bool cancel); + void DoneWithEntry(ActiveEntry* entry, Transaction* transaction, bool cancel); // Called when the transaction has finished writing to this entry. |success| // is false if the cache entry should be deleted. - void DoneWritingToEntry(ActiveEntry* entry, bool success); + void DoneWritingToEntry(ActiveEntry* entry, + bool success, + Transaction* transaction); // Called when the transaction has finished reading from this entry. - void DoneReadingFromEntry(ActiveEntry* entry, Transaction* trans); + void DoneReadingFromEntry(ActiveEntry* entry, Transaction* transaction); - // Converts the active writer transaction to a reader so that other - // transactions can start reading from this entry. - void ConvertWriterToReader(ActiveEntry* entry); + // Removes and returns all queued transactions in |entry| in FIFO order. This + // includes transactions that have completed the headers phase and those that + // have not been added to the entry yet in that order. |list| is the output + // argument. + void RemoveAllQueuedTransactions(ActiveEntry* entry, TransactionList* list); + + // Processes either writer's failure to write response body or + // headers_transactions's failure to write headers. Also invoked when headers + // transaction's validation result is not a match. + void ProcessEntryFailure(ActiveEntry* entry); + + // Resumes processing the queued transactions of |entry|. + void ProcessQueuedTransactions(ActiveEntry* entry); + + // Checks if a transaction can be added to the entry. If yes, it will + // invoke the IO callback of the transaction. This is a helper function for + // OnProcessQueuedTransactions. It will take a transaction from + // add_to_entry_queue and make it a headers_transaction, if one doesn't exist + // already. + void ProcessAddToEntryQueue(ActiveEntry* entry); + + // Invoked when a transaction that has already completed the response headers + // phase can resume reading/writing the response body. It will invoke the IO + // callback of the transaction. This is a helper function for + // OnProcessQueuedTransactions. + void ProcessDoneHeadersQueue(ActiveEntry* entry); + + // Returns true if this transaction can write headers to the entry. + bool CanTransactionWriteResponseHeaders(ActiveEntry* entry, + Transaction* transaction, + bool is_match) const; + + // Returns true if |transaction| is about to start writing response body or + // already started but not yet finished. + bool IsTransactionWritingIncomplete(ActiveEntry* entry, + Transaction* transaction, + const std::string& method) const; + + // Returns true if a transaction is currently writing the response body. + bool IsWritingInProgress(ActiveEntry* entry) const; // Returns the LoadState of the provided pending transaction. LoadState GetLoadStateForPendingTransaction(const Transaction* trans); @@ -379,12 +470,10 @@ // Removes the transaction |trans|, from the pending list of |pending_op|. bool RemovePendingTransactionFromPendingOp(PendingOp* pending_op, Transaction* trans); - // Resumes processing the pending list of |entry|. - void ProcessPendingQueue(ActiveEntry* entry); // Events (called via PostTask) --------------------------------------------- - void OnProcessPendingQueue(ActiveEntry* entry); + void OnProcessQueuedTransactions(ActiveEntry* entry); // Callbacks ----------------------------------------------------------------
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc index 5189446..b10bf90 100644 --- a/net/http/http_cache_transaction.cc +++ b/net/http/http_cache_transaction.cc
@@ -156,6 +156,7 @@ new_entry_(NULL), new_response_(NULL), mode_(NONE), + original_mode_(NONE), reading_(false), invalid_range_(false), truncated_(false), @@ -196,16 +197,12 @@ if (cache_) { if (entry_) { - bool cancel_request = reading_ && response_.headers.get(); - if (cancel_request) { - if (partial_) { - entry_->disk_entry->CancelSparseIO(); - } else { - cancel_request &= (response_.headers->response_code() == 200); - } - } + bool writing_incomplete = cache_->IsTransactionWritingIncomplete( + entry_, this, request_->method); + if (writing_incomplete && partial_) + entry_->disk_entry->CancelSparseIO(); - cache_->DoneWithEntry(entry_, this, cancel_request); + cache_->DoneWithEntry(entry_, this, writing_incomplete); } else if (cache_pending_) { cache_->RemovePendingTransaction(this); } @@ -565,6 +562,12 @@ old_connection_attempts_.end()); } +void HttpCache::Transaction::SetValidatingCannotProceed() { + DCHECK(!reading_); + next_state_ = STATE_HEADERS_PHASE_CANNOT_PROCEED; + entry_ = nullptr; +} + size_t HttpCache::Transaction::EstimateMemoryUsage() const { // TODO(xunjieli): Consider improving the coverage. crbug.com/669108. return 0; @@ -579,7 +582,7 @@ // GetBackend* -> InitEntry -> OpenEntry* -> CreateEntry* -> AddToEntry* -> // SendRequest* -> SuccessfulSendRequest -> OverwriteCachedResponse -> // CacheWriteResponse* -> TruncateCachedData* -> TruncateCachedMetadata* -> -// PartialHeadersReceived +// PartialHeadersReceived -> FinishHeaders* // // Read(): // NetworkRead* -> CacheWriteData* @@ -588,7 +591,7 @@ // Start(): // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> -// BeginCacheValidation() -> SetupEntryForRead() +// BeginCacheValidation() -> SetupEntryForRead() -> FinishHeaders* // // Read(): // CacheReadData* @@ -600,7 +603,7 @@ // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> // UpdateCachedResponse -> CacheWriteUpdatedResponse* -> // UpdateCachedResponseComplete -> OverwriteCachedResponse -> -// PartialHeadersReceived +// PartialHeadersReceived -> FinishHeaders* // // Read(): // CacheReadData* @@ -611,7 +614,7 @@ // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> // OverwriteCachedResponse -> CacheWriteResponse* -> DoTruncateCachedData* -> -// TruncateCachedMetadata* -> PartialHeadersReceived +// TruncateCachedMetadata* -> PartialHeadersReceived -> FinishHeaders* // // Read(): // NetworkRead* -> CacheWriteData* @@ -625,7 +628,7 @@ // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> // UpdateCachedResponse -> CacheWriteUpdatedResponse* -> // UpdateCachedResponseComplete -> OverwriteCachedResponse -> -// PartialHeadersReceived +// PartialHeadersReceived -> FinishHeaders* // // Read() 1: // NetworkRead* -> CacheWriteData* @@ -666,7 +669,7 @@ // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* // -> CacheDispatchValidation -> BeginPartialCacheValidation() -> // BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest -> -// OverwriteCachedResponse +// OverwriteCachedResponse -> FinishHeaders* // // 10. HEAD. Sparse entry, partially cached: // Serve the request from the cache, as long as it doesn't require @@ -691,7 +694,7 @@ // GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse* // -> CacheToggleUnusedSincePrefetch* -> CacheDispatchValidation -> // BeginPartialCacheValidation() -> BeginCacheValidation() -> -// SetupEntryForRead() +// SetupEntryForRead() -> FinishHeaders* // // Read(): // CacheReadData* @@ -705,8 +708,9 @@ DCHECK(!in_do_loop_); int rv = result; + State state = next_state_; do { - State state = next_state_; + state = next_state_; next_state_ = STATE_UNSET; base::AutoReset<bool> scoped_in_do_loop(&in_do_loop_, true); @@ -843,6 +847,15 @@ case STATE_CACHE_READ_METADATA_COMPLETE: rv = DoCacheReadMetadataComplete(rv); break; + case STATE_HEADERS_PHASE_CANNOT_PROCEED: + rv = DoHeadersPhaseCannotProceed(); + break; + case STATE_FINISH_HEADERS: + rv = DoFinishHeaders(rv); + break; + case STATE_FINISH_HEADERS_COMPLETE: + rv = DoFinishHeadersComplete(rv); + break; case STATE_NETWORK_READ: DCHECK_EQ(OK, rv); rv = DoNetworkRead(); @@ -879,8 +892,13 @@ } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); + // Assert Start() state machine's allowed last state in successful cases when + // caching is happening. + DCHECK(reading_ || rv != OK || !entry_ || + state == STATE_FINISH_HEADERS_COMPLETE); + if (rv != ERR_IO_PENDING && !callback_.is_null()) { - read_buf_ = NULL; // Release the buffer before invoking the callback. + read_buf_ = nullptr; // Release the buffer before invoking the callback. base::ResetAndReturn(&callback_).Run(rv); } @@ -907,7 +925,7 @@ if (effective_load_flags_ & LOAD_ONLY_FROM_CACHE) { if (effective_load_flags_ & LOAD_BYPASS_CACHE) { // The client has asked for nonsense. - TransitionToState(STATE_NONE); + TransitionToState(STATE_FINISH_HEADERS); return ERR_CACHE_MISS; } mode_ = READ; @@ -946,7 +964,7 @@ // If must use cache, then we must fail. This can happen for back/forward // navigations to a page generated via a form post. if (!(mode_ & READ) && effective_load_flags_ & LOAD_ONLY_FROM_CACHE) { - TransitionToState(STATE_NONE); + TransitionToState(STATE_FINISH_HEADERS); return ERR_CACHE_MISS; } @@ -963,6 +981,9 @@ // This is only set if we have something to do with the response. range_requested_ = (partial_.get() != NULL); + // mode_ may change later, save the initial mode in case we need to restart + // this request. + original_mode_ = mode_; return OK; } @@ -971,7 +992,7 @@ DCHECK(!new_entry_); if (!cache_.get()) { - TransitionToState(STATE_NONE); + TransitionToState(STATE_FINISH_HEADERS); return ERR_UNEXPECTED; } @@ -1008,7 +1029,7 @@ } if (result == ERR_CACHE_RACE) { - TransitionToState(STATE_INIT_ENTRY); + TransitionToState(STATE_HEADERS_PHASE_CANNOT_PROCEED); return OK; } @@ -1034,7 +1055,7 @@ // The entry does not exist, and we are not permitted to create a new entry, // so we must fail. - TransitionToState(STATE_NONE); + TransitionToState(STATE_FINISH_HEADERS); return ERR_CACHE_MISS; } @@ -1053,8 +1074,9 @@ net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_DOOM_ENTRY, result); cache_pending_ = false; - TransitionToState(result == ERR_CACHE_RACE ? STATE_INIT_ENTRY - : STATE_CREATE_ENTRY); + TransitionToState(result == ERR_CACHE_RACE + ? STATE_HEADERS_PHASE_CANNOT_PROCEED + : STATE_CREATE_ENTRY); return OK; } @@ -1081,7 +1103,7 @@ break; case ERR_CACHE_RACE: - TransitionToState(STATE_INIT_ENTRY); + TransitionToState(STATE_HEADERS_PHASE_CANNOT_PROCEED); break; default: @@ -1162,13 +1184,13 @@ new_entry_ = NULL; if (result == ERR_CACHE_RACE) { - TransitionToState(STATE_INIT_ENTRY); + TransitionToState(STATE_HEADERS_PHASE_CANNOT_PROCEED); return OK; } if (result == ERR_CACHE_LOCK_TIMEOUT) { if (mode_ == READ) { - TransitionToState(STATE_NONE); + TransitionToState(STATE_FINISH_HEADERS); return ERR_CACHE_MISS; } @@ -1182,12 +1204,16 @@ return OK; } - open_entry_last_used_ = entry_->disk_entry->GetLastUsed(); + // TODO(crbug.com/713354) Access timestamp for histograms only if entry is + // already written, to avoid data race since cache thread can also access + // this. + if (!cache_->IsWritingInProgress(entry_)) + open_entry_last_used_ = entry_->disk_entry->GetLastUsed(); // TODO(jkarlin): We should either handle the case or DCHECK. if (result != OK) { NOTREACHED(); - TransitionToState(STATE_NONE); + TransitionToState(STATE_FINISH_HEADERS); return result; } @@ -1226,29 +1252,37 @@ return OnCacheReadError(result, true); } - int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); - int64_t full_response_length = response_.headers->GetContentLength(); + // TODO(crbug.com/713354) Only get data size if there is no other transaction + // currently writing the response body due to the data race mentioned in the + // associated bug. + if (!cache_->IsWritingInProgress(entry_)) { + int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); + int64_t full_response_length = response_.headers->GetContentLength(); - // Some resources may have slipped in as truncated when they're not. - if (full_response_length == current_size) - truncated_ = false; + // Some resources may have slipped in as truncated when they're not. + if (full_response_length == current_size) + truncated_ = false; - // The state machine's handling of StopCaching unfortunately doesn't deal well - // with resources that are larger than 2GB when there is a truncated or sparse - // cache entry. While the state machine is reworked to resolve this, the - // following logic is put in place to defer such requests to the network. The - // cache should not be storing multi gigabyte resources. See - // http://crbug.com/89567. - if ((truncated_ || response_.headers->response_code() == 206) && - !range_requested_ && - full_response_length > std::numeric_limits<int32_t>::max()) { - // Does not release the cache entry. If another transaction wants to use - // this cache entry while this transaction is active, the second transaction - // will fall back to the network after the timeout. - DCHECK(!partial_); - mode_ = NONE; - TransitionToState(STATE_SEND_REQUEST); - return OK; + // The state machine's handling of StopCaching unfortunately doesn't deal + // well with resources that are larger than 2GB when there is a truncated or + // sparse cache entry. While the state machine is reworked to resolve this, + // the following logic is put in place to defer such requests to the + // network. The cache should not be storing multi gigabyte resources. See + // http://crbug.com/89567. + if ((truncated_ || response_.headers->response_code() == 206) && + !range_requested_ && + full_response_length > std::numeric_limits<int32_t>::max()) { + DCHECK(!partial_); + + // Doom the entry so that no other transaction gets added to this entry + // and avoid a race of not being able to check this condition because + // writing is in progress. + cache_->DoneWritingToEntry(entry_, false, this); + entry_ = nullptr; + mode_ = NONE; + TransitionToState(STATE_SEND_REQUEST); + return OK; + } } if (response_.unused_since_prefetch != @@ -1330,7 +1364,7 @@ int HttpCache::Transaction::DoCacheQueryDataComplete(int result) { DCHECK_EQ(OK, result); if (!cache_.get()) { - TransitionToState(STATE_NONE); + TransitionToState(STATE_FINISH_HEADERS); return ERR_UNEXPECTED; } @@ -1340,7 +1374,7 @@ // We may end up here multiple times for a given request. int HttpCache::Transaction::DoStartPartialCacheValidation() { if (mode_ == NONE) { - TransitionToState(STATE_NONE); + TransitionToState(STATE_FINISH_HEADERS); return OK; } @@ -1357,12 +1391,12 @@ cache_->DoneReadingFromEntry(entry_, this); entry_ = NULL; } - TransitionToState(STATE_NONE); + TransitionToState(STATE_FINISH_HEADERS); return result; } if (result < 0) { - TransitionToState(STATE_NONE); + TransitionToState(STATE_FINISH_HEADERS); return result; } @@ -1388,7 +1422,7 @@ int rv = cache_->network_layer_->CreateTransaction(priority_, &network_trans_); if (rv != OK) { - TransitionToState(STATE_NONE); + TransitionToState(STATE_FINISH_HEADERS); return rv; } network_trans_->SetBeforeNetworkStartCallback(before_network_start_callback_); @@ -1410,7 +1444,7 @@ int HttpCache::Transaction::DoSendRequestComplete(int result) { TRACE_EVENT0("io", "HttpCacheTransaction::DoSendRequestComplete"); if (!cache_.get()) { - TransitionToState(STATE_NONE); + TransitionToState(STATE_FINISH_HEADERS); return ERR_UNEXPECTED; } @@ -1441,7 +1475,7 @@ DoneWritingToEntry(true); } - TransitionToState(STATE_NONE); + TransitionToState(STATE_FINISH_HEADERS); return result; } @@ -1455,7 +1489,7 @@ new_response->headers->response_code() == 407) { SetAuthResponse(*new_response); if (!reading_) { - TransitionToState(STATE_NONE); + TransitionToState(STATE_FINISH_HEADERS); return OK; } @@ -1480,7 +1514,7 @@ mode_ = NONE; partial_.reset(); ResetNetworkTransaction(); - TransitionToState(STATE_NONE); + TransitionToState(STATE_FINISH_HEADERS); return ERR_CACHE_AUTH_FAILURE_AFTER_READ; } @@ -1518,7 +1552,7 @@ int ret = cache_->DoomEntry(cache_key_, NULL); DCHECK_EQ(OK, ret); } - cache_->DoneWritingToEntry(entry_, true); + cache_->DoneWritingToEntry(entry_, true, this); entry_ = NULL; mode_ = NONE; } @@ -1536,7 +1570,7 @@ (request_->method == "GET" || request_->method == "POST")) { // If there is an active entry it may be destroyed with this transaction. SetResponse(*new_response_); - TransitionToState(STATE_NONE); + TransitionToState(STATE_FINISH_HEADERS); return OK; } @@ -1624,7 +1658,6 @@ } else if (entry_ && !handling_206_) { DCHECK_EQ(READ_WRITE, mode_); if (!partial_ || partial_->IsLastRange()) { - cache_->ConvertWriterToReader(entry_); mode_ = READ; } // We no longer need the network transaction, so destroy it. @@ -1662,7 +1695,7 @@ DoneWritingToEntry(false); mode_ = NONE; new_response_ = NULL; - TransitionToState(STATE_NONE); + TransitionToState(STATE_FINISH_HEADERS); return OK; } @@ -1683,6 +1716,19 @@ int HttpCache::Transaction::DoCacheWriteResponse() { TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheWriteResponse"); TransitionToState(STATE_CACHE_WRITE_RESPONSE_COMPLETE); + + // Invalidate any current entry with a successful response if this transaction + // cannot write to this entry. This transaction then continues to read from + // the network without writing to the backend. + bool is_match = response_.headers->response_code() == 304; + if (entry_ && response_.headers && + !cache_->CanTransactionWriteResponseHeaders(entry_, this, is_match)) { + cache_->DoneWritingToEntry(entry_, false, this); + entry_ = nullptr; + mode_ = NONE; + return OK; + } + return WriteResponseInfoToEntry(truncated_); } @@ -1744,10 +1790,12 @@ new_response_ = NULL; if (!partial_) { - if (entry_ && entry_->disk_entry->GetDataSize(kMetadataIndex)) + if (entry_ && entry_->disk_entry->GetDataSize(kMetadataIndex)) { TransitionToState(STATE_CACHE_READ_METADATA); - else - TransitionToState(STATE_NONE); + } else { + DCHECK(!reading_); + TransitionToState(STATE_FINISH_HEADERS); + } return OK; } @@ -1761,13 +1809,63 @@ // We are about to return the headers for a byte-range request to the user, // so let's fix them. partial_->FixResponseHeaders(response_.headers.get(), true); - TransitionToState(STATE_NONE); + TransitionToState(STATE_FINISH_HEADERS); } else { - TransitionToState(STATE_NONE); + TransitionToState(STATE_FINISH_HEADERS); } return OK; } +int HttpCache::Transaction::DoHeadersPhaseCannotProceed() { + // If its the Start state machine and it cannot proceed due to a cache + // failure, restart this transaction. + DCHECK(!reading_); + TransitionToState(STATE_INIT_ENTRY); + cache_entry_status_ = CacheEntryStatus::ENTRY_UNDEFINED; + entry_ = nullptr; + mode_ = original_mode_; + if (network_trans_) + network_trans_.reset(); + return OK; +} + +int HttpCache::Transaction::DoFinishHeaders(int result) { + if (!entry_ || result != OK) { + TransitionToState(STATE_NONE); + return result; + } + + TransitionToState(STATE_FINISH_HEADERS_COMPLETE); + + // If it was an auth failure or 416, this transaction should continue to be + // headers_transaction till consumer takes an action, so no need to do + // anything now. + if (auth_response_.headers.get() || + (new_response_ && new_response_->headers && + new_response_->headers->response_code() == 416)) + return OK; + + // If there is no response body to be written or read, it does not need to + // wait. + if (request_->method == "HEAD") + return OK; + + // If the transaction needs to wait because another transaction is still + // writing the response body, it will return ERR_IO_PENDING now and the + // io_callback_ will be invoked when the wait is done. + return cache_->DoneWithResponseHeaders(entry_, this); +} + +int HttpCache::Transaction::DoFinishHeadersComplete(int rv) { + if (rv == ERR_CACHE_RACE) { + TransitionToState(STATE_HEADERS_PHASE_CANNOT_PROCEED); + return OK; + } + + TransitionToState(STATE_NONE); + return rv; +} + int HttpCache::Transaction::DoCacheReadMetadata() { TRACE_EVENT0("io", "HttpCacheTransaction::DoCacheReadMetadata"); DCHECK(entry_); @@ -1790,7 +1888,8 @@ result); if (result != response_.metadata->size()) return OnCacheReadError(result, false); - TransitionToState(STATE_NONE); + + TransitionToState(STATE_FINISH_HEADERS); return OK; } @@ -2087,18 +2186,18 @@ // TODO(jkarlin): Either handle this case or DCHECK. if (response_.headers->response_code() == 206 || partial_) { NOTREACHED(); - TransitionToState(STATE_NONE); + TransitionToState(STATE_FINISH_HEADERS); return ERR_CACHE_MISS; } // We don't have the whole resource. if (truncated_) { - TransitionToState(STATE_NONE); + TransitionToState(STATE_FINISH_HEADERS); return ERR_CACHE_MISS; } if (RequiresValidation()) { - TransitionToState(STATE_NONE); + TransitionToState(STATE_FINISH_HEADERS); return ERR_CACHE_MISS; } @@ -2108,7 +2207,7 @@ if (entry_->disk_entry->GetDataSize(kMetadataIndex)) TransitionToState(STATE_CACHE_READ_METADATA); else - TransitionToState(STATE_NONE); + TransitionToState(STATE_FINISH_HEADERS); return OK; } @@ -2568,7 +2667,7 @@ partial_.reset(); } } - cache_->ConvertWriterToReader(entry_); + mode_ = READ; if (request_->method == "HEAD") @@ -2577,7 +2676,7 @@ if (entry_->disk_entry->GetDataSize(kMetadataIndex)) TransitionToState(STATE_CACHE_READ_METADATA); else - TransitionToState(STATE_NONE); + TransitionToState(STATE_FINISH_HEADERS); return OK; } @@ -2656,7 +2755,7 @@ RecordHistograms(); - cache_->DoneWritingToEntry(entry_, success); + cache_->DoneWritingToEntry(entry_, success, this); entry_ = NULL; mode_ = NONE; // switch to 'pass through' mode } @@ -2867,10 +2966,14 @@ cache_entry_status_ == CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE); int64_t freshness_periods_since_last_used = 0; - if (stale_request) { + if (stale_request && !open_entry_last_used_.is_null()) { + // Note that we are not able to capture those transactions' histograms which + // when added to entry, the response was being written by another + // transaction because getting the last used timestamp might lead to a data + // race in that case. TODO(crbug.com/713354). + // For stale entries, record how many freshness periods have elapsed since // the entry was last used. - DCHECK(!open_entry_last_used_.is_null()); DCHECK(!stale_entry_freshness_.is_zero()); base::TimeDelta time_since_use = base::Time::Now() - open_entry_last_used_; freshness_periods_since_last_used =
diff --git a/net/http/http_cache_transaction.h b/net/http/http_cache_transaction.h index 51c0db7..6811dd4 100644 --- a/net/http/http_cache_transaction.h +++ b/net/http/http_cache_transaction.h
@@ -164,6 +164,10 @@ int ResumeNetworkStart() override; void GetConnectionAttempts(ConnectionAttempts* out) const override; + // Invoked when parallel validation cannot proceed due to response failure + // and this transaction needs to be restarted. + void SetValidatingCannotProceed(); + // Returns the estimate of dynamically allocated memory in bytes. size_t EstimateMemoryUsage() const; @@ -220,6 +224,9 @@ STATE_PARTIAL_HEADERS_RECEIVED, STATE_CACHE_READ_METADATA, STATE_CACHE_READ_METADATA_COMPLETE, + STATE_HEADERS_PHASE_CANNOT_PROCEED, + STATE_FINISH_HEADERS, + STATE_FINISH_HEADERS_COMPLETE, // These states are entered from Read/AddTruncatedFlag. STATE_NETWORK_READ, @@ -288,6 +295,9 @@ int DoPartialHeadersReceived(); int DoCacheReadMetadata(); int DoCacheReadMetadataComplete(int result); + int DoHeadersPhaseCannotProceed(); + int DoFinishHeaders(int result); + int DoFinishHeadersComplete(int result); int DoNetworkRead(); int DoNetworkReadComplete(int result); int DoCacheReadData(); @@ -430,7 +440,12 @@ void SyncCacheEntryStatusToResponse(); void RecordHistograms(); - // Called to signal completion of asynchronous IO. + // Called to signal completion of asynchronous IO. Note that this callback is + // used in the conventional sense where one layer calls the callback of the + // layer above it e.g. this callback gets called from the network transaction + // layer. In addition, it is also used for HttpCache layer to let this + // transaction know when it is out of a queued state in ActiveEntry and can + // continue its processing. void OnIOComplete(int result); // When in a DoLoop, use this to set the next state as it verifies that the @@ -456,6 +471,7 @@ const HttpResponseInfo* new_response_; std::string cache_key_; Mode mode_; + Mode original_mode_; // Used when restarting the transaction. bool reading_; // We are already reading. Never reverts to false once set. bool invalid_range_; // We may bypass the cache for this request. bool truncated_; // We don't have all the response data.
diff --git a/net/http/http_cache_unittest.cc b/net/http/http_cache_unittest.cc index ca9c5d9..626f46a 100644 --- a/net/http/http_cache_unittest.cc +++ b/net/http/http_cache_unittest.cc
@@ -147,6 +147,10 @@ EXPECT_TRUE(load_timing_info.receive_headers_end.is_null()); } +void DeferNetworkStart(bool* defer) { + *defer = true; +} + class DeleteCacheCompletionCallback : public TestCompletionCallbackBase { public: explicit DeleteCacheCompletionCallback(MockHttpCache* cache) @@ -1350,12 +1354,12 @@ MockHttpRequest request(kSimpleGET_Transaction); - std::vector<Context*> context_list; + std::vector<std::unique_ptr<Context>> context_list; const int kNumTransactions = 5; for (int i = 0; i < kNumTransactions; ++i) { - context_list.push_back(new Context()); - Context* c = context_list[i]; + context_list.push_back(base::MakeUnique<Context>()); + auto& c = context_list[i]; c->result = cache.CreateTransaction(&c->trans); ASSERT_THAT(c->result, IsOk()); @@ -1366,16 +1370,19 @@ } // All requests are waiting for the active entry. - for (int i = 0; i < kNumTransactions; ++i) { - Context* c = context_list[i]; - EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, c->trans->GetLoadState()); + for (auto& context : context_list) { + EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState()); } // Allow all requests to move from the Create queue to the active entry. base::RunLoop().RunUntilIdle(); // The first request should be a writer at this point, and the subsequent - // requests should be pending. + // requests should have passed the validation phase and waiting for the + // response to be written to the cache before they can read. + EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url)); + EXPECT_EQ(kNumTransactions - 1, + cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url)); EXPECT_EQ(1, cache.network_layer()->transaction_count()); EXPECT_EQ(0, cache.disk_cache()->open_count()); @@ -1383,15 +1390,21 @@ // All requests depend on the writer, and the writer is between Start and // Read, i.e. idle. - for (int i = 0; i < kNumTransactions; ++i) { - Context* c = context_list[i]; - EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); + for (auto& context : context_list) { + EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState()); } for (int i = 0; i < kNumTransactions; ++i) { - Context* c = context_list[i]; + auto& c = context_list[i]; if (c->result == ERR_IO_PENDING) c->result = c->callback.WaitForResult(); + + if (i > 0) { + EXPECT_FALSE(cache.IsWriterPresent(kSimpleGET_Transaction.url)); + EXPECT_EQ(kNumTransactions - i, + cache.GetCountReaders(kSimpleGET_Transaction.url)); + } + ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); } @@ -1400,11 +1413,479 @@ EXPECT_EQ(1, cache.network_layer()->transaction_count()); EXPECT_EQ(0, cache.disk_cache()->open_count()); EXPECT_EQ(1, cache.disk_cache()->create_count()); +} + +// Parallel validation results in 200. +TEST(HttpCache, SimpleGET_ParallelValidationNoMatch) { + MockHttpCache cache; + + MockHttpRequest request(kSimpleGET_Transaction); + request.load_flags |= LOAD_VALIDATE_CACHE; + + std::vector<std::unique_ptr<Context>> context_list; + const int kNumTransactions = 5; for (int i = 0; i < kNumTransactions; ++i) { - Context* c = context_list[i]; - delete c; + context_list.push_back(base::MakeUnique<Context>()); + auto& c = context_list[i]; + + c->result = cache.CreateTransaction(&c->trans); + ASSERT_THAT(c->result, IsOk()); + EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); + + c->result = + c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); } + + // All requests are waiting for the active entry. + for (auto& context : context_list) { + EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState()); + } + + // Allow all requests to move from the Create queue to the active entry. + base::RunLoop().RunUntilIdle(); + + // The first request should be a writer at this point, and the subsequent + // requests should have passed the validation phase and created their own + // entries since none of them matched the headers of the earlier one. + EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url)); + + // Note that there are only 3 entries created and not 5 since every other + // transaction would have gone to the network. + EXPECT_EQ(5, cache.network_layer()->transaction_count()); + EXPECT_EQ(0, cache.disk_cache()->open_count()); + EXPECT_EQ(3, cache.disk_cache()->create_count()); + + // All requests depend on the writer, and the writer is between Start and + // Read, i.e. idle. + for (auto& context : context_list) { + EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState()); + } + + for (auto& context : context_list) { + if (context->result == ERR_IO_PENDING) + context->result = context->callback.WaitForResult(); + ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction); + } + + EXPECT_EQ(5, cache.network_layer()->transaction_count()); + EXPECT_EQ(0, cache.disk_cache()->open_count()); + EXPECT_EQ(3, cache.disk_cache()->create_count()); +} + +// Tests that a GET followed by a DELETE results in DELETE immediately starting +// the headers phase and the entry is doomed. +TEST(HttpCache, SimpleGET_ParallelValidationDelete) { + MockHttpCache cache; + + MockHttpRequest request(kSimpleGET_Transaction); + request.load_flags |= LOAD_VALIDATE_CACHE; + + MockHttpRequest delete_request(kSimpleGET_Transaction); + delete_request.method = "DELETE"; + + std::vector<std::unique_ptr<Context>> context_list; + const int kNumTransactions = 2; + + for (int i = 0; i < kNumTransactions; ++i) { + context_list.push_back(base::MakeUnique<Context>()); + auto& c = context_list[i]; + + MockHttpRequest* this_request = &request; + if (i == 1) + this_request = &delete_request; + + c->result = cache.CreateTransaction(&c->trans); + ASSERT_THAT(c->result, IsOk()); + EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); + + c->result = c->trans->Start(this_request, c->callback.callback(), + NetLogWithSource()); + } + + // All requests are waiting for the active entry. + for (auto& context : context_list) { + EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState()); + } + + // Allow all requests to move from the Create queue to the active entry. + base::RunLoop().RunUntilIdle(); + + // The first request should be a writer at this point, and the subsequent + // request should have passed the validation phase and doomed the existing + // entry. + EXPECT_TRUE( + cache.disk_cache()->IsDiskEntryDoomed(kSimpleGET_Transaction.url)); + + EXPECT_EQ(2, cache.network_layer()->transaction_count()); + EXPECT_EQ(0, cache.disk_cache()->open_count()); + EXPECT_EQ(1, cache.disk_cache()->create_count()); + + // All requests depend on the writer, and the writer is between Start and + // Read, i.e. idle. + for (auto& context : context_list) { + EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState()); + } + + for (auto& context : context_list) { + if (context->result == ERR_IO_PENDING) + context->result = context->callback.WaitForResult(); + ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction); + } + + EXPECT_EQ(2, cache.network_layer()->transaction_count()); + EXPECT_EQ(0, cache.disk_cache()->open_count()); + EXPECT_EQ(1, cache.disk_cache()->create_count()); +} + +// Tests that a transaction which is in validated queue can be destroyed without +// any impact to other transactions. +TEST(HttpCache, SimpleGET_ParallelValidationCancelValidated) { + MockHttpCache cache; + + MockHttpRequest request(kSimpleGET_Transaction); + + std::vector<std::unique_ptr<Context>> context_list; + const int kNumTransactions = 2; + + for (int i = 0; i < kNumTransactions; ++i) { + context_list.push_back(base::MakeUnique<Context>()); + auto& c = context_list[i]; + + c->result = cache.CreateTransaction(&c->trans); + ASSERT_THAT(c->result, IsOk()); + + c->result = + c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); + } + + // Allow all requests to move from the Create queue to the active entry. + base::RunLoop().RunUntilIdle(); + + // The first request should be a writer at this point, and the subsequent + // requests should have completed validation. + + EXPECT_EQ(1, cache.network_layer()->transaction_count()); + EXPECT_EQ(0, cache.disk_cache()->open_count()); + EXPECT_EQ(1, cache.disk_cache()->create_count()); + + EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url)); + EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url)); + + context_list[1].reset(); + + EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url)); + + // Complete the rest of the transactions. + for (auto& context : context_list) { + if (!context) + continue; + ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction); + } + + EXPECT_EQ(1, cache.network_layer()->transaction_count()); + EXPECT_EQ(0, cache.disk_cache()->open_count()); + EXPECT_EQ(1, cache.disk_cache()->create_count()); +} + +// Tests that a transaction which is in readers can be destroyed without +// any impact to other transactions. +TEST(HttpCache, SimpleGET_ParallelValidationCancelReader) { + MockHttpCache cache; + + MockHttpRequest request(kSimpleGET_Transaction); + + MockTransaction transaction(kSimpleGET_Transaction); + transaction.load_flags |= LOAD_VALIDATE_CACHE; + MockHttpRequest validate_request(transaction); + + int kNumTransactions = 4; + std::vector<std::unique_ptr<Context>> context_list; + + for (int i = 0; i < kNumTransactions; ++i) { + context_list.push_back(base::MakeUnique<Context>()); + auto& c = context_list[i]; + + c->result = cache.CreateTransaction(&c->trans); + ASSERT_THAT(c->result, IsOk()); + + MockHttpRequest* this_request = &request; + if (i == 3) { + this_request = &validate_request; + c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferNetworkStart)); + } + + c->result = c->trans->Start(this_request, c->callback.callback(), + NetLogWithSource()); + } + + // Allow all requests to move from the Create queue to the active entry. + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ(2, cache.network_layer()->transaction_count()); + EXPECT_EQ(0, cache.disk_cache()->open_count()); + EXPECT_EQ(1, cache.disk_cache()->create_count()); + + EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url)); + EXPECT_EQ(2, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url)); + EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url)); + + // Complete the response body. + auto& c = context_list[0]; + ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); + + // Rest of the transactions should move to readers. + EXPECT_FALSE(cache.IsWriterPresent(kSimpleGET_Transaction.url)); + EXPECT_EQ(2, cache.GetCountReaders(kSimpleGET_Transaction.url)); + EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url)); + EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url)); + + // Add 2 new transactions. + kNumTransactions = 6; + + for (int i = 4; i < kNumTransactions; ++i) { + context_list.push_back(base::MakeUnique<Context>()); + auto& c = context_list[i]; + + c->result = cache.CreateTransaction(&c->trans); + ASSERT_THAT(c->result, IsOk()); + + c->result = + c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); + } + + EXPECT_EQ(2, cache.GetCountAddToEntryQueue(kSimpleGET_Transaction.url)); + + // Delete a reader. + context_list[1].reset(); + + // Deleting the reader did not impact any other transaction. + EXPECT_EQ(1, cache.GetCountReaders(kSimpleGET_Transaction.url)); + EXPECT_EQ(2, cache.GetCountAddToEntryQueue(kSimpleGET_Transaction.url)); + EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url)); + + // Resume network start for headers_transaction. It will doom the entry as it + // will be a 200 and will go to network for the response body. + auto& context = context_list[3]; + context->trans->ResumeNetworkStart(); + + // The pending transactions will be added to a new entry. + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url)); + EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url)); + + // Complete the rest of the transactions. + for (int i = 2; i < kNumTransactions; ++i) { + auto& c = context_list[i]; + ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); + } + + EXPECT_EQ(3, cache.network_layer()->transaction_count()); + EXPECT_EQ(0, cache.disk_cache()->open_count()); + EXPECT_EQ(2, cache.disk_cache()->create_count()); +} + +// Tests that a transaction is in validated queue and writer is destroyed +// leading to restarting the validated transaction. +TEST(HttpCache, SimpleGET_ParallelValidationCancelWriter) { + MockHttpCache cache; + + MockHttpRequest request(kSimpleGET_Transaction); + + MockTransaction transaction(kSimpleGET_Transaction); + transaction.load_flags |= LOAD_VALIDATE_CACHE; + MockHttpRequest validate_request(transaction); + + const int kNumTransactions = 3; + std::vector<std::unique_ptr<Context>> context_list; + + for (int i = 0; i < kNumTransactions; ++i) { + context_list.push_back(base::MakeUnique<Context>()); + auto& c = context_list[i]; + + c->result = cache.CreateTransaction(&c->trans); + ASSERT_THAT(c->result, IsOk()); + + MockHttpRequest* this_request = &request; + if (i == 2) { + this_request = &validate_request; + c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferNetworkStart)); + } + + c->result = c->trans->Start(this_request, c->callback.callback(), + NetLogWithSource()); + } + + // Allow all requests to move from the Create queue to the active entry. + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ(2, cache.network_layer()->transaction_count()); + EXPECT_EQ(0, cache.disk_cache()->open_count()); + EXPECT_EQ(1, cache.disk_cache()->create_count()); + + EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url)); + EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url)); + EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url)); + + // Deleting the writer at this point will lead to destroying the entry and + // restarting the remaining transactions which will then create a new entry. + context_list[0].reset(); + + // Resume network start for headers_transaction. It should be restarted due to + // writer cancellation. + auto& c = context_list[2]; + c->trans->ResumeNetworkStart(); + + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url)); + EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url)); + + // Resume network start for the transaction the second time. + c->trans->ResumeNetworkStart(); + base::RunLoop().RunUntilIdle(); + + // Headers transaction would have doomed the new entry created. + EXPECT_TRUE( + cache.disk_cache()->IsDiskEntryDoomed(kSimpleGET_Transaction.url)); + + // Complete the rest of the transactions. + for (auto& context : context_list) { + if (!context) + continue; + ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction); + } + + EXPECT_EQ(4, cache.network_layer()->transaction_count()); + EXPECT_EQ(0, cache.disk_cache()->open_count()); + EXPECT_EQ(2, cache.disk_cache()->create_count()); +} + +// Tests that a transaction is currently in headers phase and is destroyed +// leading to destroying the entry. +TEST(HttpCache, SimpleGET_ParallelValidationCancelHeaders) { + MockHttpCache cache; + + MockHttpRequest request(kSimpleGET_Transaction); + + const int kNumTransactions = 2; + std::vector<std::unique_ptr<Context>> context_list; + + for (int i = 0; i < kNumTransactions; ++i) { + context_list.push_back(base::MakeUnique<Context>()); + auto& c = context_list[i]; + + c->result = cache.CreateTransaction(&c->trans); + ASSERT_THAT(c->result, IsOk()); + + if (i == 0) + c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferNetworkStart)); + + c->result = + c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); + } + + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url)); + EXPECT_EQ(1, cache.GetCountAddToEntryQueue(kSimpleGET_Transaction.url)); + + EXPECT_EQ(1, cache.network_layer()->transaction_count()); + EXPECT_EQ(0, cache.disk_cache()->open_count()); + EXPECT_EQ(1, cache.disk_cache()->create_count()); + + // Delete the headers transaction. + context_list[0].reset(); + + base::RunLoop().RunUntilIdle(); + + // Complete the rest of the transactions. + for (auto& context : context_list) { + if (!context) + continue; + ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction); + } + + EXPECT_EQ(2, cache.network_layer()->transaction_count()); + EXPECT_EQ(0, cache.disk_cache()->open_count()); + EXPECT_EQ(2, cache.disk_cache()->create_count()); +} + +// Similar to the above test, except here cache write fails and the +// validated transactions should be restarted. +TEST(HttpCache, SimpleGET_ParallelValidationFailWrite) { + MockHttpCache cache; + + MockHttpRequest request(kSimpleGET_Transaction); + + const int kNumTransactions = 5; + std::vector<std::unique_ptr<Context>> context_list; + + for (int i = 0; i < kNumTransactions; ++i) { + context_list.push_back(base::MakeUnique<Context>()); + auto& c = context_list[i]; + + c->result = cache.CreateTransaction(&c->trans); + ASSERT_THAT(c->result, IsOk()); + EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); + + c->result = + c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); + } + + // All requests are waiting for the active entry. + for (auto& context : context_list) { + EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState()); + } + + // Allow all requests to move from the Create queue to the active entry. + base::RunLoop().RunUntilIdle(); + + // The first request should be a writer at this point, and the subsequent + // requests should have passed the validation phase and waiting for the + // response to be written to the cache before they can read. + EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url)); + EXPECT_EQ(4, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url)); + + // All requests depend on the writer, and the writer is between Start and + // Read, i.e. idle. + for (auto& context : context_list) { + EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState()); + } + + // The first request should be a writer at this point, and the subsequent + // requests should have passed the validation phase and waiting for the + // response to be written to the cache before they can read. + + EXPECT_EQ(1, cache.network_layer()->transaction_count()); + EXPECT_EQ(0, cache.disk_cache()->open_count()); + EXPECT_EQ(1, cache.disk_cache()->create_count()); + + // Fail the request. + cache.disk_cache()->set_soft_failures(true); + // We have to open the entry again to propagate the failure flag. + disk_cache::Entry* en; + cache.OpenBackendEntry(kSimpleGET_Transaction.url, &en); + en->Close(); + + for (int i = 0; i < kNumTransactions; ++i) { + auto& c = context_list[i]; + if (c->result == ERR_IO_PENDING) + c->result = c->callback.WaitForResult(); + if (i == 1) { + // The earlier entry must be destroyed and its disk entry doomed. + EXPECT_TRUE( + cache.disk_cache()->IsDiskEntryDoomed(kSimpleGET_Transaction.url)); + } + ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); + } + + // Since validated transactions were restarted and new entry read/write + // operations would also fail, all requests would have gone to the network. + EXPECT_EQ(5, cache.network_layer()->transaction_count()); + EXPECT_EQ(1, cache.disk_cache()->open_count()); + EXPECT_EQ(5, cache.disk_cache()->create_count()); } // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769. @@ -1451,11 +1932,12 @@ c->result = c->callback.WaitForResult(); ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); - // Now we have 2 active readers and two queued transactions. - + // Now all transactions should be waiting for read to be invoked. Two readers + // are because of the load flags and remaining two transactions were converted + // to readers after skipping validation. Note that the remaining two went on + // to process the headers in parallel with readers present on the entry. EXPECT_EQ(LOAD_STATE_IDLE, context_list[2]->trans->GetLoadState()); - EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, - context_list[3]->trans->GetLoadState()); + EXPECT_EQ(LOAD_STATE_IDLE, context_list[3]->trans->GetLoadState()); c = context_list[1]; ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); @@ -1520,12 +2002,16 @@ NetLogWithSource()); } + base::RunLoop().RunUntilIdle(); + // The first request should be a writer at this point, and the two subsequent // requests should be pending. The last request doomed the first entry. EXPECT_EQ(2, cache.network_layer()->transaction_count()); - // Cancel the first queued transaction. + // Cancel the second transaction. Note that this and the 3rd transactions + // would have completed their headers phase and would be waiting in the + // done_headers_queue when the 2nd transaction is cancelled. context_list[1].reset(); for (int i = 0; i < kNumTransactions; ++i) { @@ -1567,11 +2053,12 @@ base::RunLoop().RunUntilIdle(); // The first request should be a writer at this point, and the subsequent - // requests should be pending. + // requests should have completed validation. Since the validation does not + // result in a match, a new entry would be created. - EXPECT_EQ(1, cache.network_layer()->transaction_count()); + EXPECT_EQ(3, cache.network_layer()->transaction_count()); EXPECT_EQ(0, cache.disk_cache()->open_count()); - EXPECT_EQ(1, cache.disk_cache()->create_count()); + EXPECT_EQ(2, cache.disk_cache()->create_count()); // Now, make sure that the second request asks for the entry not to be stored. request_handler.set_no_store(true); @@ -1625,6 +2112,9 @@ if (c->result == ERR_IO_PENDING) c->result = c->callback.WaitForResult(); // Destroy only the first transaction. + // This should lead to all transactions to restart, even those that have + // validated themselves and were waiting for the writer transaction to + // complete writing to the cache. if (i == 0) { delete c; context_list[i] = NULL; @@ -2540,6 +3030,8 @@ // be returned. // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be // returned. +// The entry will be created once and will be opened for the 3 subsequent +// requests. static void ConditionalizedRequestUpdatesCacheHelper( const Response& net_response_1, const Response& net_response_2, @@ -6115,12 +6607,14 @@ EXPECT_EQ(5, c->callback.GetResult(rv)); // Cancel the requests. + // Since |pending| is currently validating the already written headers + // it will be restarted as well. delete c; delete pending; EXPECT_EQ(1, cache.network_layer()->transaction_count()); EXPECT_EQ(1, cache.disk_cache()->open_count()); - EXPECT_EQ(2, cache.disk_cache()->create_count()); + EXPECT_EQ(1, cache.disk_cache()->create_count()); base::RunLoop().RunUntilIdle(); RemoveMockTransaction(&transaction); @@ -6845,46 +7339,6 @@ EXPECT_EQ(1, cache.disk_cache()->create_count()); } -// Tests that if a metadata writer transaction hits cache lock timeout, it will -// error out. -TEST(HttpCache, WriteMetadata_CacheLockTimeout) { - MockHttpCache cache; - - // Write to the cache - HttpResponseInfo response; - RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction, - &response); - EXPECT_FALSE(response.metadata.get()); - - MockHttpRequest request(kSimpleGET_Transaction); - Context c1; - ASSERT_THAT(cache.CreateTransaction(&c1.trans), IsOk()); - ASSERT_EQ(ERR_IO_PENDING, c1.trans->Start(&request, c1.callback.callback(), - NetLogWithSource())); - - cache.SimulateCacheLockTimeout(); - - // Write meta data to the same entry. - scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(50)); - memset(buf->data(), 0, buf->size()); - base::strlcpy(buf->data(), "Hi there", buf->size()); - cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url), - DEFAULT_PRIORITY, response.response_time, - buf.get(), buf->size()); - - // Release the buffer before the operation takes place. - buf = NULL; - - // Makes sure we finish pending operations. - base::RunLoop().RunUntilIdle(); - - RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction, - &response); - - // The writer transaction should fail due to cache lock timeout. - ASSERT_FALSE(response.metadata.get()); -} - // Tests that we ignore VARY checks when writing metadata since the request // headers for the WriteMetadata transaction are made up. TEST(HttpCache, WriteMetadata_IgnoreVary) { @@ -7212,10 +7666,6 @@ EXPECT_THAT(callback.GetResult(rv), IsOk()); trans->StopCaching(); - - scoped_refptr<IOBuffer> buf(new IOBuffer(256)); - rv = trans->Read(buf.get(), 10, callback.callback()); - EXPECT_EQ(callback.GetResult(rv), 10); } RemoveMockTransaction(&mock_transaction);
diff --git a/net/http/http_transaction_test_util.cc b/net/http/http_transaction_test_util.cc index a5b5746..fa42dd7 100644 --- a/net/http/http_transaction_test_util.cc +++ b/net/http/http_transaction_test_util.cc
@@ -409,13 +409,6 @@ if (!t) return ERR_FAILED; - if (!before_network_start_callback_.is_null()) { - bool defer = false; - before_network_start_callback_.Run(&defer); - if (defer) - return net::ERR_IO_PENDING; - } - test_mode_ = t->test_mode; // Return immediately if we're returning an error. @@ -466,6 +459,16 @@ if (request_->load_flags & LOAD_PREFETCH) response_.unused_since_prefetch = true; + // Pause and resume. + if (!before_network_start_callback_.is_null()) { + bool defer = false; + before_network_start_callback_.Run(&defer); + if (defer) { + callback_ = callback; + return net::ERR_IO_PENDING; + } + } + if (test_mode_ & TEST_MODE_SYNC_NET_START) return OK; @@ -482,8 +485,9 @@ const BeforeHeadersSentCallback& callback) {} int MockNetworkTransaction::ResumeNetworkStart() { - // Should not get here. - return ERR_FAILED; + DCHECK(!callback_.is_null()); + CallbackLater(callback_, OK); + return ERR_IO_PENDING; } void MockNetworkTransaction::GetConnectionAttempts(
diff --git a/net/http/http_transaction_test_util.h b/net/http/http_transaction_test_util.h index e936ac9d..dbd2670 100644 --- a/net/http/http_transaction_test_util.h +++ b/net/http/http_transaction_test_util.h
@@ -280,6 +280,8 @@ bool done_reading_called_; + CompletionCallback callback_; // used for pause and restart. + base::WeakPtrFactory<MockNetworkTransaction> weak_factory_; };
diff --git a/net/http/mock_http_cache.cc b/net/http/mock_http_cache.cc index 47125a30..e676122 100644 --- a/net/http/mock_http_cache.cc +++ b/net/http/mock_http_cache.cc
@@ -534,6 +534,13 @@ FROM_HERE, base::Bind(&CallbackForwader, callback, result)); } +bool MockDiskCache::IsDiskEntryDoomed(const std::string& key) { + auto it = entries_.find(key); + if (it == entries_.end()) + return false; + return it->second->is_doomed(); +} + //----------------------------------------------------------------------------- int MockBackendFactory::CreateBackend( @@ -647,6 +654,41 @@ g_test_mode = test_mode; } +bool MockHttpCache::IsWriterPresent(const std::string& key) { + HttpCache::ActiveEntry* entry = http_cache_.FindActiveEntry(key); + if (entry) + return entry->writer; + return false; +} + +bool MockHttpCache::IsHeadersTransactionPresent(const std::string& key) { + HttpCache::ActiveEntry* entry = http_cache_.FindActiveEntry(key); + if (entry) + return entry->headers_transaction; + return false; +} + +int MockHttpCache::GetCountReaders(const std::string& key) { + HttpCache::ActiveEntry* entry = http_cache_.FindActiveEntry(key); + if (entry) + return entry->readers.size(); + return false; +} + +int MockHttpCache::GetCountAddToEntryQueue(const std::string& key) { + HttpCache::ActiveEntry* entry = http_cache_.FindActiveEntry(key); + if (entry) + return entry->add_to_entry_queue.size(); + return false; +} + +int MockHttpCache::GetCountDoneHeadersQueue(const std::string& key) { + HttpCache::ActiveEntry* entry = http_cache_.FindActiveEntry(key); + if (entry) + return entry->done_headers_queue.size(); + return false; +} + //----------------------------------------------------------------------------- int MockDiskCacheNoCB::CreateEntry(const std::string& key,
diff --git a/net/http/mock_http_cache.h b/net/http/mock_http_cache.h index a24200b..7718f351 100644 --- a/net/http/mock_http_cache.h +++ b/net/http/mock_http_cache.h
@@ -158,6 +158,8 @@ void ReleaseAll(); + bool IsDiskEntryDoomed(const std::string& key); + private: using EntryMap = std::unordered_map<std::string, MockDiskEntry*>; class NotImplementedIterator; @@ -234,6 +236,14 @@ // the test! (by setting test_mode to zero). static void SetTestMode(int test_mode); + // Functions to test the state of ActiveEntry. + + bool IsWriterPresent(const std::string& key); + bool IsHeadersTransactionPresent(const std::string& key); + int GetCountReaders(const std::string& key); + int GetCountAddToEntryQueue(const std::string& key); + int GetCountDoneHeadersQueue(const std::string& key); + private: HttpCache http_cache_; };
diff --git a/net/test/cert_test_util.cc b/net/test/cert_test_util.cc index 8da3aecf..2c22d84f 100644 --- a/net/test/cert_test_util.cc +++ b/net/test/cert_test_util.cc
@@ -6,6 +6,7 @@ #include "base/files/file_path.h" #include "base/files/file_util.h" +#include "base/threading/thread_restrictions.h" #include "net/cert/ev_root_ca_metadata.h" #include "net/cert/x509_certificate.h" #include "net/test/test_data_directory.h" @@ -63,6 +64,7 @@ scoped_refptr<X509Certificate> ImportCertFromFile( const base::FilePath& certs_dir, const std::string& cert_file) { + base::ThreadRestrictions::ScopedAllowIO allow_io; base::FilePath cert_path = certs_dir.AppendASCII(cert_file); std::string cert_data; if (!base::ReadFileToString(cert_path, &cert_data))
diff --git a/net/url_request/url_request_quic_unittest.cc b/net/url_request/url_request_quic_unittest.cc index ff887060..8c3f560 100644 --- a/net/url_request/url_request_quic_unittest.cc +++ b/net/url_request/url_request_quic_unittest.cc
@@ -305,15 +305,14 @@ EXPECT_TRUE(entries[0].GetStringValue("push_url", &value)); EXPECT_EQ(value, push_url_1); - // No net error code for this lookup transaction, the push is found. - EXPECT_FALSE(entries[1].GetIntegerValue("net_error", &net_error)); - - EXPECT_TRUE(entries[2].GetStringValue("push_url", &value)); + EXPECT_TRUE(entries[1].GetStringValue("push_url", &value)); EXPECT_EQ(value, push_url_2); // Net error code -400 is found for this lookup transaction, the push is not // found in the cache. - EXPECT_TRUE(entries[3].GetIntegerValue("net_error", &net_error)); + EXPECT_TRUE(entries[2].GetIntegerValue("net_error", &net_error)); EXPECT_EQ(net_error, -400); + // No net error code for this lookup transaction, the push is found. + EXPECT_FALSE(entries[3].GetIntegerValue("net_error", &net_error)); // Verify the reset error count received on the server side. EXPECT_LE(1u, GetRstErrorCountReceivedByServer(QUIC_STREAM_CANCELLED)); @@ -392,11 +391,13 @@ EXPECT_TRUE(entries[0].GetStringValue("push_url", &value)); EXPECT_EQ(value, push_url_1); - // No net error code for this lookup transaction, the push is found. - EXPECT_FALSE(entries[1].GetIntegerValue("net_error", &net_error)); - EXPECT_TRUE(entries[2].GetStringValue("push_url", &value)); + EXPECT_TRUE(entries[1].GetStringValue("push_url", &value)); EXPECT_EQ(value, push_url_2); + + // No net error code for this lookup transaction, the push is found. + EXPECT_FALSE(entries[2].GetIntegerValue("net_error", &net_error)); + // No net error code for this lookup transaction, the push is found. EXPECT_FALSE(entries[3].GetIntegerValue("net_error", &net_error));
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc index 7282a0e5..341f870 100644 --- a/net/url_request/url_request_unittest.cc +++ b/net/url_request/url_request_unittest.cc
@@ -4138,14 +4138,14 @@ context.CreateRequest(url, DEFAULT_PRIORITY, &d)); r->Start(); + base::RunLoop().Run(); + { HttpRequestHeaders headers; EXPECT_TRUE(r->GetFullRequestHeaders(&headers)); - EXPECT_FALSE(headers.HasHeader("Authorization")); + EXPECT_TRUE(headers.HasHeader("Authorization")); } - base::RunLoop().Run(); - EXPECT_EQ(OK, d.request_status()); EXPECT_EQ(200, r->GetResponseCode()); EXPECT_TRUE(d.auth_required_called());
diff --git a/services/service_manager/embedder/main.cc b/services/service_manager/embedder/main.cc index 86a6a62..24b9d66 100644 --- a/services/service_manager/embedder/main.cc +++ b/services/service_manager/embedder/main.cc
@@ -266,7 +266,6 @@ } void InitializeResources() { - ui::RegisterPathProvider(); const std::string locale = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( ::switches::kLang); @@ -392,6 +391,8 @@ mojo::edk::SetMaxMessageSize(kMaximumMojoMessageSize); mojo::edk::Init(); + ui::RegisterPathProvider(); + base::debug::GlobalActivityTracker* tracker = base::debug::GlobalActivityTracker::Get(); int exit_code = delegate->Initialize(init_params);
diff --git a/services/service_manager/public/cpp/connector.h b/services/service_manager/public/cpp/connector.h index ae15116..9f232287 100644 --- a/services/service_manager/public/cpp/connector.h +++ b/services/service_manager/public/cpp/connector.h
@@ -113,6 +113,11 @@ // to pass again. virtual std::unique_ptr<Connector> Clone() = 0; + virtual void FilterInterfaces(const std::string& spec, + const Identity& source_identity, + mojom::InterfaceProviderRequest request, + mojom::InterfaceProviderPtr target) = 0; + // Binds a Connector request to the other end of this Connector. virtual void BindConnectorRequest(mojom::ConnectorRequest request) = 0;
diff --git a/services/service_manager/public/cpp/lib/connector_impl.cc b/services/service_manager/public/cpp/lib/connector_impl.cc index 0040a32..bd6e7a54 100644 --- a/services/service_manager/public/cpp/lib/connector_impl.cc +++ b/services/service_manager/public/cpp/lib/connector_impl.cc
@@ -84,6 +84,14 @@ return base::MakeUnique<ConnectorImpl>(connector.PassInterface()); } +void ConnectorImpl::FilterInterfaces(const std::string& spec, + const Identity& source_identity, + mojom::InterfaceProviderRequest request, + mojom::InterfaceProviderPtr target) { + connector_->FilterInterfaces(spec, source_identity, std::move(request), + std::move(target)); +} + void ConnectorImpl::BindConnectorRequest(mojom::ConnectorRequest request) { if (!BindConnectorIfNecessary()) return;
diff --git a/services/service_manager/public/cpp/lib/connector_impl.h b/services/service_manager/public/cpp/lib/connector_impl.h index b07fb2b..68728c8 100644 --- a/services/service_manager/public/cpp/lib/connector_impl.h +++ b/services/service_manager/public/cpp/lib/connector_impl.h
@@ -34,6 +34,10 @@ const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) override; std::unique_ptr<Connector> Clone() override; + void FilterInterfaces(const std::string& spec, + const Identity& source_identity, + mojom::InterfaceProviderRequest request, + mojom::InterfaceProviderPtr target) override; void BindConnectorRequest(mojom::ConnectorRequest request) override; base::WeakPtr<Connector> GetWeakPtr() override; void OverrideBinderForTesting(const std::string& service_name,
diff --git a/services/service_manager/public/interfaces/connector.mojom b/services/service_manager/public/interfaces/connector.mojom index 63168e4a..d403bd5a 100644 --- a/services/service_manager/public/interfaces/connector.mojom +++ b/services/service_manager/public/interfaces/connector.mojom
@@ -164,4 +164,20 @@ // Clones this Connector so it can be passed to another thread. Clone(Connector& request); + + // Filter interface requests received from |source| according to the policy + // specified in this service's manifest in an InterfaceProviderSpec named + // |spec|. + // + // The flow is basically - remote service wishes to (generically) request + // interfaces from this service, and so sends us an InterfaceProvider request + // (|source_request|) which it would like us to bind. We forward this request + // to the Service Manager, passing our actual InterfaceProvider implementation + // in |target|. The Service Manager will only forward interface requests that + // were permitted by intersecting |source|'s manifest requirements with the + // contents of |spec|. + FilterInterfaces(string spec, + Identity source, + InterfaceProvider& source_request, + InterfaceProvider target); };
diff --git a/services/service_manager/service_manager.cc b/services/service_manager/service_manager.cc index 6e492932..c2259d4 100644 --- a/services/service_manager/service_manager.cc +++ b/services/service_manager/service_manager.cc
@@ -22,6 +22,7 @@ #include "mojo/public/cpp/bindings/associated_binding.h" #include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding_set.h" +#include "mojo/public/cpp/bindings/strong_binding.h" #include "services/catalog/public/interfaces/constants.mojom.h" #include "services/service_manager/connect_util.h" #include "services/service_manager/public/cpp/connector.h" @@ -77,6 +78,25 @@ return it->second.find(capability) != it->second.end(); } +bool AllowsInterface(const Identity& source, + const InterfaceProviderSpec& source_spec, + const Identity& target, + const InterfaceProviderSpec& target_spec, + const std::string& interface_name) { + InterfaceSet exposed = + GetInterfacesToExpose(source_spec, target, target_spec); + bool allowed = (exposed.size() == 1 && exposed.count("*") == 1) || + exposed.count(interface_name) > 0; + if (!allowed) { + std::stringstream ss; + ss << "Connection InterfaceProviderSpec prevented service: " + << source.name() << " from binding interface: " << interface_name + << " exposed by: " << target.name(); + LOG(ERROR) << ss.str(); + } + return allowed; +} + // Encapsulates a connection to an instance of a service, tracked by the // Service Manager. class ServiceManager::Instance @@ -145,17 +165,8 @@ source_connection_spec = source->GetConnectionSpec(); } - InterfaceSet exposed = GetInterfacesToExpose(source_connection_spec, - identity_, - GetConnectionSpec()); - bool allowed = (exposed.size() == 1 && exposed.count("*") == 1) || - exposed.count(params->interface_name()) > 0; - if (!allowed) { - std::stringstream ss; - ss << "Connection InterfaceProviderSpec prevented service: " - << params->source().name() << " from binding interface: " - << params->interface_name() << " exposed by: " << identity_.name(); - LOG(ERROR) << ss.str(); + if (!AllowsInterface(params->source(), source_connection_spec, identity_, + GetConnectionSpec(), params->interface_name())) { params->set_response_data(mojom::ConnectResult::ACCESS_DENIED, identity_); return false; } @@ -215,10 +226,17 @@ } const InterfaceProviderSpec& GetConnectionSpec() const { - auto it = interface_provider_specs_.find( - mojom::kServiceManager_ConnectorSpec); + return GetSpec(mojom::kServiceManager_ConnectorSpec); + } + bool HasSpec(const std::string& spec) const { + auto it = interface_provider_specs_.find(spec); + return it != interface_provider_specs_.end(); + } + const InterfaceProviderSpec& GetSpec(const std::string& spec) const { + auto it = interface_provider_specs_.find(spec); return it != interface_provider_specs_.end() ? it->second : empty_spec_; } + const Identity& identity() const { return identity_; } void set_identity(const Identity& identity) { identity_ = identity; } uint32_t id() const { return id_; } @@ -252,6 +270,62 @@ STARTED }; + class InterfaceProviderImpl : public mojom::InterfaceProvider { + public: + InterfaceProviderImpl(const std::string& spec, + const Identity& source_identity, + const Identity& target_identity, + service_manager::ServiceManager* service_manager, + mojom::InterfaceProviderPtr target, + mojom::InterfaceProviderRequest source_request) + : spec_(spec), + source_identity_(source_identity), + target_identity_(target_identity), + service_manager_(service_manager), + target_(std::move(target)), + source_binding_(this, std::move(source_request)) {} + ~InterfaceProviderImpl() override {} + + private: + // mojom::InterfaceProvider: + void GetInterface(const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) override { + Instance* source = + service_manager_->GetExistingInstance(source_identity_); + Instance* target = + service_manager_->GetExistingInstance(target_identity_); + if (!source || !target) + return; + if (!ValidateSpec(source) || !ValidateSpec(target)) + return; + + if (AllowsInterface(source_identity_, source->GetSpec(spec_), + target_identity_, target->GetSpec(spec_), + interface_name)) { + target_->GetInterface(interface_name, std::move(interface_pipe)); + } + } + + bool ValidateSpec(Instance* instance) const { + if (!instance->HasSpec(spec_)) { + LOG(ERROR) << "Instance for: " << instance->identity().name() + << " did not have spec named: " << spec_; + return false; + } + return true; + } + + const std::string spec_; + const Identity source_identity_; + const Identity target_identity_; + const service_manager::ServiceManager* service_manager_; + + mojom::InterfaceProviderPtr target_; + mojo::Binding<mojom::InterfaceProvider> source_binding_; + + DISALLOW_COPY_AND_ASSIGN(InterfaceProviderImpl); + }; + // mojom::Connector implementation: void BindInterface(const service_manager::Identity& in_target, const std::string& interface_name, @@ -320,6 +394,15 @@ connectors_.AddBinding(this, std::move(request)); } + void FilterInterfaces(const std::string& spec, + const Identity& source, + mojom::InterfaceProviderRequest source_request, + mojom::InterfaceProviderPtr target) override { + filters_.push_back(base::MakeUnique<InterfaceProviderImpl>( + spec, source, identity_, service_manager_, std::move(target), + std::move(source_request))); + } + // mojom::PIDReceiver: void SetPID(uint32_t pid) override { PIDAvailable(pid); @@ -500,6 +583,8 @@ base::ProcessId pid_ = base::kNullProcessId; State state_; + std::vector<std::unique_ptr<InterfaceProviderImpl>> filters_; + // The number of outstanding OnBindInterface requests which are in flight. int pending_service_connections_ = 0;
diff --git a/services/service_manager/standalone/BUILD.gn b/services/service_manager/standalone/BUILD.gn index 63d18d8..4c8ba4f3 100644 --- a/services/service_manager/standalone/BUILD.gn +++ b/services/service_manager/standalone/BUILD.gn
@@ -30,8 +30,4 @@ "//services/tracing/public/interfaces", "//url", ] - - data_deps = [ - "//services/tracing", - ] }
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h index 2038d0d1..6d08ac4 100644 --- a/skia/config/SkUserConfig.h +++ b/skia/config/SkUserConfig.h
@@ -202,10 +202,6 @@ # define SK_IGNORE_ETC1_SUPPORT #endif -#ifndef SK_SUPPORT_GPU_REF_ENCODED_DATA -# define SK_SUPPORT_GPU_REF_ENCODED_DATA -#endif - #ifndef SK_IGNORE_GPU_DITHER # define SK_IGNORE_GPU_DITHER #endif
diff --git a/sql/test/test_helpers.cc b/sql/test/test_helpers.cc index 0e32164..20e2316 100644 --- a/sql/test/test_helpers.cc +++ b/sql/test/test_helpers.cc
@@ -12,6 +12,7 @@ #include "base/files/file_util.h" #include "base/files/scoped_file.h" +#include "base/threading/thread_restrictions.h" #include "sql/connection.h" #include "sql/statement.h" #include "testing/gtest/include/gtest/gtest.h" @@ -100,6 +101,7 @@ } bool CorruptSizeInHeaderWithLock(const base::FilePath& db_path) { + base::ThreadRestrictions::ScopedAllowIO allow_io; sql::Connection db; if (!db.Open(db_path)) return false;
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 5527629..661fa50 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -953,21 +953,6 @@ ] } ], - "EnableWelcomeWin10": [ - { - "platforms": [ - "win" - ], - "experiments": [ - { - "name": "Inline", - "enable_features": [ - "EnableWelcomeWin10" - ] - } - ] - } - ], "ExpectCTReporting": [ { "platforms": [
diff --git a/third_party/.gitignore b/third_party/.gitignore index 5ad1c8d..7d5d9a22 100644 --- a/third_party/.gitignore +++ b/third_party/.gitignore
@@ -67,6 +67,7 @@ /google_toolbox_for_mac/src /googlemac /gvr-android-sdk/common_library.aar +/gvr-android-sdk/test-libraries/controller_test_api.aar /gvr-android-sdk/libgvr_shim_static_arm.a /gvr-android-sdk/libgvr_shim_static_arm64.a /gvr-android-sdk/src
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 2b1b4374..20216d4 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -3236,8 +3236,6 @@ crbug.com/669473 external/wpt/css/css-ui-3/outline-014.html [ Failure ] crbug.com/669473 external/wpt/css/css-ui-3/outline-015.html [ Failure ] crbug.com/669473 external/wpt/css/css-ui-3/outline-016.html [ Failure ] -crbug.com/669473 external/wpt/css/css-ui-3/text-overflow-002.html [ Failure ] -crbug.com/669473 external/wpt/css/css-ui-3/text-overflow-004.html [ Failure ] crbug.com/670024 external/wpt/webmessaging/broadcastchannel/sandbox.html [ Failure ] crbug.com/660384 external/wpt/webmessaging/with-ports/001.html [ Failure ] @@ -3424,6 +3422,8 @@ # Sheriff failures 2017-04-19 crbug.com/713094 [ Win ] virtual/sharedarraybuffer/fast/css/fontfaceset-check-platform-fonts.html [ Failure Pass ] +# Sheriff failure 2017-04-26 +crbug.com/713094 [ Win ] fast/css/fontfaceset-check-platform-fonts.html [ Failure Pass ] # Sheriff failures 2017-04-24 crbug.com/714862 [ Android ] tables/mozilla/collapsing_borders/bug41262-3.html [ Failure ] @@ -3441,3 +3441,12 @@ crbug.com/713685 [ Linux ] virtual/sharedarraybuffer/fast/workers/termination-early.html [ Crash Pass ] crbug.com/715405 [ Win Mac ] virtual/mojo-loading/http/tests/inspector/network/waterfall-images.html [ Failure Pass ] + +crbug.com/715718 external/wpt/media-source/mediasource-activesourcebuffers.html [ Failure Pass ] +crbug.com/715718 external/wpt/media-source/mediasource-remove.html [ Failure Pass ] +crbug.com/715718 [ Win ] external/wpt/XMLHttpRequest/FormData-append.html [ Failure Pass ] +crbug.com/715718 [ Win ] external/wpt/XMLHttpRequest/timeout-multiple-fetches.html [ Failure Pass ] +crbug.com/715718 [ Win ] external/wpt/css/css-flexbox-1/align-items-004.htm [ Failure Pass ] +crbug.com/715718 [ Win ] external/wpt/css/css-flexbox-1/flex-minimum-width-flex-items-001.xht [ Failure Pass ] +crbug.com/715718 [ Win ] external/wpt/css/css-flexbox-1/flex-minimum-width-flex-items-003.xht [ Failure Pass ] +crbug.com/715718 [ Win ] external/wpt/css/css-flexbox-1/flexbox_flex-natural-mixed-basis-auto.html [ Failure Pass ]
diff --git a/third_party/WebKit/LayoutTests/crypto/subtle/hkdf/deriveBits-expected.txt b/third_party/WebKit/LayoutTests/crypto/subtle/hkdf/deriveBits-expected.txt index cbcf052..81b8870 100644 --- a/third_party/WebKit/LayoutTests/crypto/subtle/hkdf/deriveBits-expected.txt +++ b/third_party/WebKit/LayoutTests/crypto/subtle/hkdf/deriveBits-expected.txt
@@ -5,9 +5,9 @@ Derive 0 bits from the HKDF key PASS derivedBits.byteLength is 0 -Derive 4 bits from the HKDF key +Derive 8 bits from the HKDF key PASS derivedBits.byteLength is 1 -PASS derivedBits.getUint8(0) is 0x80 +PASS derivedBits.getUint8(0) is 141 PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/crypto/subtle/hkdf/deriveBits-failures-expected.txt b/third_party/WebKit/LayoutTests/crypto/subtle/hkdf/deriveBits-failures-expected.txt index f2be32a..d405e3c2 100644 --- a/third_party/WebKit/LayoutTests/crypto/subtle/hkdf/deriveBits-failures-expected.txt +++ b/third_party/WebKit/LayoutTests/crypto/subtle/hkdf/deriveBits-failures-expected.txt
@@ -12,6 +12,9 @@ deriveBits() with length of 65281... error is: OperationError: The length provided for HKDF is too large. + +deriveBits() with length of 15... +error is: OperationError: The length provided for HKDF is not a multiple of 8 bits. PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/crypto/subtle/hkdf/deriveBits-failures.html b/third_party/WebKit/LayoutTests/crypto/subtle/hkdf/deriveBits-failures.html index 55ae7f4..a661f4e 100644 --- a/third_party/WebKit/LayoutTests/crypto/subtle/hkdf/deriveBits-failures.html +++ b/third_party/WebKit/LayoutTests/crypto/subtle/hkdf/deriveBits-failures.html
@@ -47,9 +47,15 @@ // The maximum length (in bytes) of output material for HKDF is 255 times // the digest length. In this case, the digest length (in bytes) of // SHA-256 is 32; 32*255 = 8160. deriveBits expects the length to be in - // bits, so 8160*8=65280 and add 1 to exceed the maximum length. + // bits, so 8160*8=65280 and add 8 to exceed the maximum length. debug("\nderiveBits() with length of 65281..."); - return crypto.subtle.deriveBits({name: "HKDF", hash: "SHA-256", salt: new Uint8Array(), info: new Uint8Array()}, hkdfKey, 65281); + return crypto.subtle.deriveBits({name: "HKDF", hash: "SHA-256", salt: new Uint8Array(), info: new Uint8Array()}, hkdfKey, 65288); +}).then(failAndFinishJSTest, function(result) { + logError(result); + + // Use a bit length that is not a multiple of 8. + debug("\nderiveBits() with length of 15..."); + return crypto.subtle.deriveBits({name: "HKDF", hash: "SHA-256", salt: new Uint8Array(), info: new Uint8Array()}, hkdfKey, 15); }).then(failAndFinishJSTest, function(result) { logError(result); }).then(finishJSTest, failAndFinishJSTest);
diff --git a/third_party/WebKit/LayoutTests/crypto/subtle/hkdf/deriveBits.html b/third_party/WebKit/LayoutTests/crypto/subtle/hkdf/deriveBits.html index a6d11fa..d4afc51 100644 --- a/third_party/WebKit/LayoutTests/crypto/subtle/hkdf/deriveBits.html +++ b/third_party/WebKit/LayoutTests/crypto/subtle/hkdf/deriveBits.html
@@ -36,15 +36,13 @@ shouldBe("derivedBits.byteLength", "0"); - debug("Derive 4 bits from the HKDF key"); - return crypto.subtle.deriveBits(kHkdfAlgorithm, baseKey, 4); + debug("Derive 8 bits from the HKDF key"); + return crypto.subtle.deriveBits(kHkdfAlgorithm, baseKey, 8); }).then(function(result) { derivedBits = new DataView(result); shouldBe("derivedBits.byteLength", "1"); - // The last 4 bits should be zeroes. - shouldBe("derivedBits.getUint8(0)", "0x80"); - + shouldBe("derivedBits.getUint8(0)", "141"); }).then(finishJSTest, failAndFinishJSTest); </script>
diff --git a/third_party/WebKit/LayoutTests/fast/css/deprecated-zoom-properties-expected.txt b/third_party/WebKit/LayoutTests/fast/css/deprecated-zoom-properties-expected.txt deleted file mode 100644 index ae000bf..0000000 --- a/third_party/WebKit/LayoutTests/fast/css/deprecated-zoom-properties-expected.txt +++ /dev/null
@@ -1,3 +0,0 @@ -CONSOLE WARNING: "zoom: reset" is deprecated and will be removed in M59, around June 2017. See https://www.chromestatus.com/features/4997605029314560 for more details. -CONSOLE WARNING: "zoom: document" is deprecated and will be removed in M59, around June 2017. See https://www.chromestatus.com/features/4997605029314560 for more details. -
diff --git a/third_party/WebKit/LayoutTests/fast/css/deprecated-zoom-properties.html b/third_party/WebKit/LayoutTests/fast/css/deprecated-zoom-properties.html deleted file mode 100644 index 9f52d01a..0000000 --- a/third_party/WebKit/LayoutTests/fast/css/deprecated-zoom-properties.html +++ /dev/null
@@ -1,11 +0,0 @@ -<!DOCTYPE html> -<head> -<script> -if (window.testRunner) - testRunner.dumpAsText(); -</script> -</head> -<body> -<div style="zoom:reset"></div> -<div style="zoom:document"></div> -</body>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/Element/getBoundingClientRect-vertical-child.html b/third_party/WebKit/LayoutTests/fast/dom/Element/getBoundingClientRect-vertical-child.html new file mode 100644 index 0000000..1c38ddca --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/dom/Element/getBoundingClientRect-vertical-child.html
@@ -0,0 +1,63 @@ +<style> + td { padding: 10px } +</style> +<div style="-webkit-writing-mode: vertical-rl; writing-mode: vertical-rl"> + <table> + <tr id="tr1"> + <td id="td1a"><span id="s1a">1-A</span></td> + <td id="td1b"><span id="s1b">1-B</span></td> + </tr> + <tr id="tr2"> + <td id="td2a"><span id="s2a">2-A</span></td> + <td id="td2b"><span id="s2b">2-B</span></td> + </tr> + </table> + <script src="../../../resources/testharness.js"></script> + <script src="../../../resources/testharnessreport.js"></script> + <script> + function doesRectContainRect(parent, child) { + if (child.top < parent.top) { + return false; + } + if (child.bottom > parent.bottom) { + return false; + } + if (child.left < parent.left) { + return false; + } + if (child.right > parent.right) { + return false; + } + return true; + } + + function rectToString(rect) { + return "(" + rect.left + " " + rect.top + " - " + rect.right + " " + rect.bottom + ")" + } + + function assert_contains(parent, child, description) { + assert_true(doesRectContainRect(parent, child), + description + " " + rectToString(parent) + " should contain " + rectToString(child)); + } + + function checkRowColumn(row, column) { + var columnName = ["a", "b", "c", "d", "e"]; + var trId = "tr" + (row + 1); + var tr = document.getElementById(trId); + var trRect = tr.getBoundingClientRect(); + var name = (row + 1).toString() + "-" + columnName[column].toUpperCase(); + var spanId = "s" + (row + 1) + columnName[column]; + var span = document.getElementById(spanId); + var spanRect = span.getBoundingClientRect(); + assert_contains(trRect, spanRect, name); + } + + test(function() { + for (var row = 0; row < 2; row++) { + for (var column = 0; column < 2; column++) { + checkRowColumn(row, column); + } + } + }, "The child of td should be inside of tr in vertical table"); + </script> +</div>
diff --git a/third_party/WebKit/LayoutTests/mojo/associated_interface_ptr.html b/third_party/WebKit/LayoutTests/mojo/associated_interface_ptr.html index 361cff3..ecccfec3 100644 --- a/third_party/WebKit/LayoutTests/mojo/associated_interface_ptr.html +++ b/third_party/WebKit/LayoutTests/mojo/associated_interface_ptr.html
@@ -13,20 +13,23 @@ "mojo/public/js/bindings", ], function(testAssociatedInterfaces, associatedBindings, bindings) { - function IntegerSenderImpl(callback) { + function SenderImpl(callback) { this.callback = callback; } - IntegerSenderImpl.prototype.echo = function(value) { + SenderImpl.prototype.echo = function(value) { return Promise.resolve({value: value}); }; - IntegerSenderImpl.prototype.send = function(value) { + SenderImpl.prototype.send = function(value) { if (this.callback) { this.callback(value); } }; + var IntegerSenderImpl = SenderImpl; + var StringSenderImpl = SenderImpl; + function IntegerSenderConnectionImpl() { this.integerSenderBinding_ = null; } @@ -58,8 +61,8 @@ IntegerSenderConnectionAtBothEndsImpl.prototype.setSender = function( integerSenderPtrInfo) { this.integerSender_ = new - testAssociatedInterfaces.AssociatedIntegerSenderPtr(); - this.integerSender_.ptr.bind(integerSenderPtrInfo); + testAssociatedInterfaces.AssociatedIntegerSenderPtr( + integerSenderPtrInfo); return this.integerSender_.echo(456); }; @@ -77,6 +80,56 @@ {custom_reason: 42, description: 'hey'}); }; + function SenderConnectionBindLaterImpl({getIntegerSenderCallback, + getStringSenderCallback} = {}) { + this.getIntegerSenderCallback = getIntegerSenderCallback; + this.getStringSenderCallback = getStringSenderCallback; + this.integerSenderBinding_ = null; + this.stringSenderBinding_ = null; + } + + SenderConnectionBindLaterImpl.prototype.getIntegerSender = + function(integerSenderRequest) { + setTimeout(() => { + this.integerSenderBinding_ = new associatedBindings.AssociatedBinding( + testAssociatedInterfaces.IntegerSender, + new IntegerSenderImpl(this.getIntegerSenderCallback), + integerSenderRequest); + }, 0); + }; + + SenderConnectionBindLaterImpl.prototype.getStringSender = + function(stringSenderRequest) { + this.stringSenderBinding_ = new associatedBindings.AssociatedBinding( + testAssociatedInterfaces.StringSender, + new StringSenderImpl(this.getStringSenderCallback), + stringSenderRequest); + }; + + function SenderConnectionImpl({getIntegerSenderCallback, + getStringSenderCallback} = {}) { + this.getIntegerSenderCallback = getIntegerSenderCallback; + this.getStringSenderCallback = getStringSenderCallback; + this.integerSenderBinding_ = null; + this.stringSenderBinding_ = null; + } + + SenderConnectionImpl.prototype.getIntegerSender = + function(integerSenderRequest) { + this.integerSenderBinding_ = new associatedBindings.AssociatedBinding( + testAssociatedInterfaces.IntegerSender, + new IntegerSenderImpl(this.getIntegerSenderCallback), + integerSenderRequest); + }; + + SenderConnectionImpl.prototype.getStringSender = + function(stringSenderRequest) { + this.stringSenderBinding_ = new associatedBindings.AssociatedBinding( + testAssociatedInterfaces.StringSender, + new StringSenderImpl(this.getStringSenderCallback), + stringSenderRequest); + }; + promise_test(async () => { var integerSenderConnection = new testAssociatedInterfaces.IntegerSenderConnectionPtr(); @@ -92,8 +145,8 @@ integerSenderPtrInfo0); var integerSender0 = new - testAssociatedInterfaces.AssociatedIntegerSenderPtr(); - integerSender0.ptr.bind(integerSenderPtrInfo0); + testAssociatedInterfaces.AssociatedIntegerSenderPtr( + integerSenderPtrInfo0); integerSenderConnection.getSender(integerSenderRequest0); assert_equals((await integerSender0.echo(123)).value, 123); @@ -102,8 +155,8 @@ var integerSenderPtrInfo1 = (await integerSenderConnection.asyncGetSender()).sender; var integerSender1 = new - testAssociatedInterfaces.AssociatedIntegerSenderPtr(); - integerSender1.ptr.bind(integerSenderPtrInfo1); + testAssociatedInterfaces.AssociatedIntegerSenderPtr( + integerSenderPtrInfo1); assert_equals((await integerSender1.echo(456)).value, 456); }, 'pass associated interfaces'); @@ -125,8 +178,8 @@ integerSenderPtrInfo0); var integerSender0 = new - testAssociatedInterfaces.AssociatedIntegerSenderPtr(); - integerSender0.ptr.bind(integerSenderPtrInfo0); + testAssociatedInterfaces.AssociatedIntegerSenderPtr( + integerSenderPtrInfo0); integerSenderConnectionAtBothEnds.getSender(integerSenderRequest0); assert_equals((await integerSender0.echo(123)).value, 123); @@ -162,8 +215,8 @@ integerSenderPtrInfo0); var integerSender0 = new - testAssociatedInterfaces.AssociatedIntegerSenderPtr(); - integerSender0.ptr.bind(integerSenderPtrInfo0); + testAssociatedInterfaces.AssociatedIntegerSenderPtr( + integerSenderPtrInfo0); integerSenderConnection.getSender(integerSenderRequest0); await new Promise((resolve, reject) => { @@ -190,16 +243,16 @@ var integerSenderRequest0 = associatedBindings.makeRequest( integerSenderPtrInfo0); var integerSender0 = new - testAssociatedInterfaces.AssociatedIntegerSenderPtr(); - integerSender0.ptr.bind(integerSenderPtrInfo0); + testAssociatedInterfaces.AssociatedIntegerSenderPtr( + integerSenderPtrInfo0); integerSenderConnection.getSender(integerSenderRequest0); // Recieving AssociatedInterfacePtrInfo. var integerSenderPtrInfo1 = (await integerSenderConnection.asyncGetSender()).sender; var integerSender1 = new - testAssociatedInterfaces.AssociatedIntegerSenderPtr(); - integerSender1.ptr.bind(integerSenderPtrInfo1); + testAssociatedInterfaces.AssociatedIntegerSenderPtr( + integerSenderPtrInfo1); // Master InterfacePtrController reset triggers connection error handler on // interface endpoint clients for all associated endpoints. @@ -220,6 +273,103 @@ await Promise.all([connectionErrorHandler0, connectionErrorHandler1]); }, 'all endpoints connectionErrorHandler called on master interface reset'); + // Cache the current message and pause processing incoming messages if + // endpoint does not have client attached yet to ensure fifo message arrival. + promise_test(async () => { + var senderConnection = new + testAssociatedInterfaces.SenderConnectionPtr(); + var senderConnectionBindLaterImpl = new SenderConnectionBindLaterImpl(); + var senderConnectionBinding = new bindings.Binding( + testAssociatedInterfaces.SenderConnection, + senderConnectionBindLaterImpl, + bindings.makeRequest(senderConnection)); + + // AssociatedInterfaceRequest for stringSender. + var stringSenderPtrInfo = new + associatedBindings.AssociatedInterfacePtrInfo(); + var stringSenderRequest = associatedBindings.makeRequest( + stringSenderPtrInfo); + var stringSender = + new testAssociatedInterfaces.AssociatedStringSenderPtr( + stringSenderPtrInfo); + + // AssociatedInterfaceRequest for integerSender. + var integerSenderPtrInfo = new + associatedBindings.AssociatedInterfacePtrInfo(); + var integerSenderRequest = associatedBindings.makeRequest( + integerSenderPtrInfo); + var integerSender = new + testAssociatedInterfaces.AssociatedIntegerSenderPtr( + integerSenderPtrInfo); + + var value = await new Promise(function(resolve, reject) { + senderConnectionBindLaterImpl.getIntegerSenderCallback = resolve; + senderConnectionBindLaterImpl.getStringSenderCallback= reject; + senderConnection.getStringSender(stringSenderRequest); + senderConnection.getIntegerSender(integerSenderRequest); + // Test FIFO arrival order of message. + integerSender.send(456); // This message should arrive first. + stringSender.send('goodbye'); + }); + + assert_equals(value, 456); + }, 'fifo order should be preserved for messages'); + + promise_test(async () => { + var senderConnection = new + testAssociatedInterfaces.SenderConnectionPtr(); + var senderConnectionImpl = new SenderConnectionImpl(); + var senderConnectionBinding = new bindings.Binding( + testAssociatedInterfaces.SenderConnection, + senderConnectionImpl, + bindings.makeRequest(senderConnection)); + + // AssociatedInterfaceRequest for stringSender. + var stringSenderPtrInfo = new + associatedBindings.AssociatedInterfacePtrInfo(); + var stringSenderRequest = associatedBindings.makeRequest( + stringSenderPtrInfo); + var stringSender = + new testAssociatedInterfaces.AssociatedStringSenderPtr( + stringSenderPtrInfo); + + // AssociatedInterfaceRequest for integerSender. + var integerSenderPtrInfo = new + associatedBindings.AssociatedInterfacePtrInfo(); + var integerSenderRequest = associatedBindings.makeRequest( + integerSenderPtrInfo); + var integerSender = new + testAssociatedInterfaces.AssociatedIntegerSenderPtr( + integerSenderPtrInfo); + + var value = await new Promise(function(resolve, reject) { + senderConnectionImpl.getIntegerSenderCallback = reject; + senderConnectionImpl.getStringSenderCallback= resolve; + senderConnection.getStringSender(stringSenderRequest); + senderConnection.getIntegerSender(integerSenderRequest); + + // Wait for integerSenderBinding to be created. + integerSender.echo(100).then(function(result) { + assert_equals(result.value, 100); + + // This causes this endpoint handle's endpoint client to be detached. + var handle = senderConnectionImpl.integerSenderBinding_. + interfaceEndpointClient_.passHandle(); + + // Cache message. Connector will pause processing incoming messages. + integerSender.send(456); + stringSender.send('goodbye'); + + // Closing the target endpoint handle of the cached message will cause + // the cached message to be discarded and the connector to resume + // processing incoming messages. + setTimeout(handle.reset.bind(handle), 0); + }); + }); + + assert_equals(value, 'goodbye'); + }, 'discard cached message if target endpoint closed'); + done(); });
diff --git a/third_party/WebKit/LayoutTests/webaudio/decodeAudioData/decode-audio-data-neuter.html b/third_party/WebKit/LayoutTests/webaudio/decodeAudioData/decode-audio-data-neuter.html index 0374bef..e112223ea 100644 --- a/third_party/WebKit/LayoutTests/webaudio/decodeAudioData/decode-audio-data-neuter.html +++ b/third_party/WebKit/LayoutTests/webaudio/decodeAudioData/decode-audio-data-neuter.html
@@ -62,6 +62,19 @@ .then(() => task.done()); }); + audit.define('decode neuters buffer and view', (task, should) => { + // The ArrayBuffer and any views of the ArrayBuffer must be neutered. + let buffer = new ArrayBuffer(1000); + let view = new Uint32Array(buffer); + + context.decodeAudioData(buffer); + + // Now buffer and view should be neutered. + should(buffer.byteLength, 'buffer.byteLength').beEqualTo(0); + should(view.length, 'view.length').beEqualTo(0); + task.done(); + }); + audit.run(); </script> </body>
diff --git a/third_party/WebKit/PerformanceTests/TestData/append-child-measure-time.html b/third_party/WebKit/PerformanceTests/TestData/append-child-measure-time.html new file mode 100644 index 0000000..99491ef --- /dev/null +++ b/third_party/WebKit/PerformanceTests/TestData/append-child-measure-time.html
@@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html> +<body> + <div id="holder"> + </div> +<script src="../resources/runner.js"></script> +</script> +<script> +var holderElement = document.getElementById("holder"); + +PerfTestRunner.measureTime({ + description: "Measures performance of layout when adding many child elements.", + + setup: function() { + while (holderElement.firstChild) { + holderElement.removeChild(holderElement.firstChild); + } + }, + + run: function() { + for (var i = 0; i < 50; ++i) { + var element = document.createElement("div"); + element.title = 'dummy'; + element.innerText = "FOO"; + holderElement.appendChild(element); + PerfTestRunner.forceLayout(); + } + }, + warmUpCount: 3, + iterationCount: 10, + tracingCategories: 'blink', + traceEventsToMeasure: ['FrameView::layout', 'UpdateLayoutTree'] +}); +</script> +</body> +</html>
diff --git a/third_party/WebKit/PerformanceTests/TestData/color-changes-measure-frame-time.html b/third_party/WebKit/PerformanceTests/TestData/color-changes-measure-frame-time.html new file mode 100644 index 0000000..a55b247 --- /dev/null +++ b/third_party/WebKit/PerformanceTests/TestData/color-changes-measure-frame-time.html
@@ -0,0 +1,84 @@ +<!DOCTYPE html> +<body> +<script src="../resources/runner.js"></script> +<style> + span { + padding: 1px; + } + .changeColor { + background-color: green; + } +</style> +<script> +// This test measures the lifecycle update performance of changing background +// colors in large trees. + +function buildTree(parent, depth, arity, tagNameCallback, createElementCallback) { + for (var child = 0; child < arity; child++) { + var element = document.createElement(tagNameCallback(depth)); + parent.appendChild(element); + createElementCallback(element, depth); + if (depth > 1) + buildTree(element, depth - 1, arity, tagNameCallback, createElementCallback); + } +} + +// Build a tall tree that is skinny. A middle layer of +// the tree should have the changeColor class. +buildTree(document.body, 15, 2, + function(depth) { + // Use divs at upper levels to avoid too much layout time. + return depth > 9 ? 'div' : 'span'; + }, + function(element, depth) { + element.style.backgroundColor = 'green'; + if (depth == 5) + element.setAttribute('class', 'changeColor'); + } +); + +// Build a short tree that is fat. A middle layer of +// the tree should have the changeColor class. +buildTree(document.body, 6, 7, + function(depth) { + // Use divs at upper levels to avoid too much layout time. + return depth > 4 ? 'div' : 'span'; + }, + function(element, depth) { + element.style.backgroundColor = 'orange'; + if (depth == 3) + element.setAttribute('class', 'changeColor'); + } +); + +var runCount = 0; +var elementsToChange = document.getElementsByClassName('changeColor'); +var colors = [ + "rgb(128, 18, 237)", + "rgb(191, 1, 191)", + "rgb(237, 18, 128)", + "rgb(255, 64, 64)", + "rgb(237, 127, 18)", + "rgb(191, 191, 1)", + "rgb(128, 237, 18)", + "rgb(64, 255, 64)", + "rgb(18, 237, 127)", + "rgb(1, 191, 191)", + "rgb(18, 128, 237)", + "rgb(64, 64, 255)" +]; + +PerfTestRunner.measureFrameTime({ + run: function() { + runCount++; + var newColor = colors[runCount % colors.length]; + for (var index = 0; index < elementsToChange.length; index++) + elementsToChange[index].style.backgroundColor = newColor; + }, + warmUpCount: 3, + iterationCount: 10, + tracingCategories: 'blink', + traceEventsToMeasure: ['FrameView::prePaint', 'FrameView::paintTree'] +}); +</script> +</body>
diff --git a/third_party/WebKit/PerformanceTests/resources/runner.js b/third_party/WebKit/PerformanceTests/resources/runner.js index 22a5e8e..7ce98b7 100644 --- a/third_party/WebKit/PerformanceTests/resources/runner.js +++ b/third_party/WebKit/PerformanceTests/resources/runner.js
@@ -157,8 +157,16 @@ PerfTestRunner.log("Running " + iterationCount + " times"); if (test.doNotIgnoreInitialRun) completedIterations++; - if (runner) + + if (runner && test.tracingCategories && window.testRunner && + window.testRunner.supportTracing) { + window.testRunner.traceEventsToMeasure = test.traceEventsToMeasure; + window.testRunner.startTracing(test.tracingCategories, function() { + scheduleNextRun(scheduler, runner); + }); + } else if (runner) { scheduleNextRun(scheduler, runner); + } } function scheduleNextRun(scheduler, runner) { @@ -225,8 +233,17 @@ logInDocument("Got an exception while finalizing the test with name=" + exception.name + ", message=" + exception.message); } - if (window.testRunner) - testRunner.notifyDone(); + if (window.testRunner) { + if (currentTest.traceEventsToMeasure && + testRunner.supportTracing) { + testRunner.stopTracingAndMeasure( + currentTest.traceEventsToMeasure, function() { + testRunner.notifyDone(); + }); + } else { + testRunner.notifyDone(); + } + } } PerfTestRunner.prepareToMeasureValuesAsync = function (test) { @@ -248,6 +265,25 @@ finish(); } + function addRunTestStartMarker() { + if (!window.testRunner || !window.testRunner.supportTracing) + return; + if (completedIterations < 0) + console.time('blink_perf.runTest.warmup'); + else + console.time('blink_perf.runTest'); + } + + function addRunTestEndMarker() { + if (!window.testRunner || !window.testRunner.supportTracing) + return; + if (completedIterations < 0) + console.timeEnd('blink_perf.runTest.warmup'); + else + console.timeEnd('blink_perf.runTest'); + } + + PerfTestRunner.measureFrameTime = function (test) { PerfTestRunner.unit = "ms"; PerfTestRunner.bufferedLog = true; @@ -261,9 +297,12 @@ var lastFrameTime = -1; function measureFrameTimeOnce() { + if (lastFrameTime != -1) + addRunTestEndMarker(); var now = PerfTestRunner.now(); var result = lastFrameTime == -1 ? -1 : now - lastFrameTime; lastFrameTime = now; + addRunTestStartMarker(); var returnValue = currentTest.run(); if (returnValue - 0 === returnValue) { @@ -290,7 +329,9 @@ PerfTestRunner.gc(); var start = PerfTestRunner.now(); + addRunTestStartMarker(); var returnValue = currentTest.run(); + addRunTestEndMarker(); var end = PerfTestRunner.now(); if (returnValue - 0 === returnValue) {
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptController.h b/third_party/WebKit/Source/bindings/core/v8/ScriptController.h index 72950f0..94203c3 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptController.h +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptController.h
@@ -56,7 +56,9 @@ typedef WTF::Vector<v8::Extension*> V8Extensions; - +// This class exposes methods to run script in a frame (in the main world and +// in isolated worlds). An instance can be obtained by using +// LocalFrame::GetScriptController(). class CORE_EXPORT ScriptController final : public GarbageCollected<ScriptController> { WTF_MAKE_NONCOPYABLE(ScriptController);
diff --git a/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.cpp b/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.cpp index d060856..6ad7cfd 100644 --- a/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValue.cpp
@@ -272,19 +272,6 @@ } } -static void AccumulateArrayBuffersForAllWorlds( - v8::Isolate* isolate, - DOMArrayBuffer* object, - Vector<v8::Local<v8::ArrayBuffer>, 4>& buffers) { - Vector<RefPtr<DOMWrapperWorld>> worlds; - DOMWrapperWorld::AllWorldsInCurrentThread(worlds); - for (const auto& world : worlds) { - v8::Local<v8::Object> wrapper = world->DomDataStore().Get(object, isolate); - if (!wrapper.IsEmpty()) - buffers.push_back(v8::Local<v8::ArrayBuffer>::Cast(wrapper)); - } -} - std::unique_ptr<SerializedScriptValue::ImageBitmapContentsArray> SerializedScriptValue::TransferImageBitmapContents( v8::Isolate* isolate, @@ -480,14 +467,16 @@ HeapHashSet<Member<DOMArrayBufferBase>> visited; for (auto it = array_buffers.begin(); it != array_buffers.end(); ++it) { - DOMArrayBufferBase* array_buffer = *it; - if (visited.Contains(array_buffer)) + DOMArrayBufferBase* array_buffer_base = *it; + if (visited.Contains(array_buffer_base)) continue; - visited.insert(array_buffer); + visited.insert(array_buffer_base); size_t index = std::distance(array_buffers.begin(), it); - if (array_buffer->IsShared()) { - if (!array_buffer->ShareContentsWith(contents->at(index))) { + if (array_buffer_base->IsShared()) { + DOMSharedArrayBuffer* shared_array_buffer = + static_cast<DOMSharedArrayBuffer*>(array_buffer_base); + if (!shared_array_buffer->ShareContentsWith(contents->at(index))) { exception_state.ThrowDOMException(kDataCloneError, "SharedArrayBuffer at index " + String::Number(index) + @@ -495,31 +484,15 @@ return nullptr; } } else { - Vector<v8::Local<v8::ArrayBuffer>, 4> buffer_handles; - v8::HandleScope handle_scope(isolate); - AccumulateArrayBuffersForAllWorlds( - isolate, static_cast<DOMArrayBuffer*>(it->Get()), buffer_handles); - bool is_neuterable = true; - for (const auto& buffer_handle : buffer_handles) - is_neuterable &= buffer_handle->IsNeuterable(); + DOMArrayBuffer* array_buffer = + static_cast<DOMArrayBuffer*>(array_buffer_base); - DOMArrayBufferBase* to_transfer = array_buffer; - if (!is_neuterable) { - to_transfer = - DOMArrayBuffer::Create(array_buffer->Buffer()->Data(), - array_buffer->Buffer()->ByteLength()); - } - if (!to_transfer->Transfer(contents->at(index))) { + if (!array_buffer->Transfer(isolate, contents->at(index))) { exception_state.ThrowDOMException( kDataCloneError, "ArrayBuffer at index " + String::Number(index) + " could not be transferred."); return nullptr; } - - if (is_neuterable) { - for (const auto& buffer_handle : buffer_handles) - buffer_handle->Neuter(); - } } } return contents;
diff --git a/third_party/WebKit/Source/bindings/modules/v8/V8BindingForModulesTest.cpp b/third_party/WebKit/Source/bindings/modules/v8/V8BindingForModulesTest.cpp index c2979fc..3eee75d 100644 --- a/third_party/WebKit/Source/bindings/modules/v8/V8BindingForModulesTest.cpp +++ b/third_party/WebKit/Source/bindings/modules/v8/V8BindingForModulesTest.cpp
@@ -135,7 +135,7 @@ constexpr static size_t kSSVHeaderBlinkVersionTagOffset = 0; constexpr static size_t kSSVHeaderBlinkVersionOffset = 1; constexpr static size_t kSSVHeaderV8VersionTagOffset = 2; -constexpr static size_t kSSVHeaderV8VersionOffset = 3; +// constexpr static size_t kSSVHeaderV8VersionOffset = 3; // Follows the same steps as the IndexedDB value serialization code. void SerializeV8Value(v8::Local<v8::Value> value, @@ -165,8 +165,9 @@ ASSERT_EQ(static_cast<unsigned char>(kVersionTag), wire_data[kSSVHeaderV8VersionTagOffset]); - ASSERT_EQ(v8::ValueSerializer::GetCurrentDataFormatVersion(), - wire_data[kSSVHeaderV8VersionOffset]); + // TODO(jbroman): Use the compile-time constant for V8 data format version. + // ASSERT_EQ(v8::ValueSerializer::GetCurrentDataFormatVersion(), + // wire_data[kSSVHeaderV8VersionOffset]); } PassRefPtr<IDBValue> CreateIDBValue(v8::Isolate* isolate,
diff --git a/third_party/WebKit/Source/bindings/templates/callback_interface.cpp.tmpl b/third_party/WebKit/Source/bindings/templates/callback_interface.cpp.tmpl index c417aaa..e308643 100644 --- a/third_party/WebKit/Source/bindings/templates/callback_interface.cpp.tmpl +++ b/third_party/WebKit/Source/bindings/templates/callback_interface.cpp.tmpl
@@ -26,8 +26,8 @@ if method.idl_type == 'boolean' else 'return' %}{# void #} ExecutionContext* executionContext = ExecutionContext::From(m_scriptState.Get()); - if (!executionContext || executionContext->IsContextSuspended() || - executionContext->IsContextDestroyed()) + DCHECK(!executionContext->IsContextSuspended()); + if (!executionContext || executionContext->IsContextDestroyed()) {{return_default}}; if (!m_scriptState->ContextIsValid()) {{return_default}};
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestCallbackInterface.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestCallbackInterface.cpp index de0cb82..adcf84e 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestCallbackInterface.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestCallbackInterface.cpp
@@ -37,8 +37,8 @@ void V8TestCallbackInterface::voidMethod() { ExecutionContext* executionContext = ExecutionContext::From(m_scriptState.Get()); - if (!executionContext || executionContext->IsContextSuspended() || - executionContext->IsContextDestroyed()) + DCHECK(!executionContext->IsContextSuspended()); + if (!executionContext || executionContext->IsContextDestroyed()) return; if (!m_scriptState->ContextIsValid()) return; @@ -59,8 +59,8 @@ bool V8TestCallbackInterface::booleanMethod() { ExecutionContext* executionContext = ExecutionContext::From(m_scriptState.Get()); - if (!executionContext || executionContext->IsContextSuspended() || - executionContext->IsContextDestroyed()) + DCHECK(!executionContext->IsContextSuspended()); + if (!executionContext || executionContext->IsContextDestroyed()) return true; if (!m_scriptState->ContextIsValid()) return true; @@ -84,8 +84,8 @@ void V8TestCallbackInterface::voidMethodBooleanArg(bool boolArg) { ExecutionContext* executionContext = ExecutionContext::From(m_scriptState.Get()); - if (!executionContext || executionContext->IsContextSuspended() || - executionContext->IsContextDestroyed()) + DCHECK(!executionContext->IsContextSuspended()); + if (!executionContext || executionContext->IsContextDestroyed()) return; if (!m_scriptState->ContextIsValid()) return; @@ -107,8 +107,8 @@ void V8TestCallbackInterface::voidMethodSequenceArg(const HeapVector<Member<TestInterfaceEmpty>>& sequenceArg) { ExecutionContext* executionContext = ExecutionContext::From(m_scriptState.Get()); - if (!executionContext || executionContext->IsContextSuspended() || - executionContext->IsContextDestroyed()) + DCHECK(!executionContext->IsContextSuspended()); + if (!executionContext || executionContext->IsContextDestroyed()) return; if (!m_scriptState->ContextIsValid()) return; @@ -130,8 +130,8 @@ void V8TestCallbackInterface::voidMethodFloatArg(float floatArg) { ExecutionContext* executionContext = ExecutionContext::From(m_scriptState.Get()); - if (!executionContext || executionContext->IsContextSuspended() || - executionContext->IsContextDestroyed()) + DCHECK(!executionContext->IsContextSuspended()); + if (!executionContext || executionContext->IsContextDestroyed()) return; if (!m_scriptState->ContextIsValid()) return; @@ -153,8 +153,8 @@ void V8TestCallbackInterface::voidMethodTestInterfaceEmptyArg(TestInterfaceEmpty* testInterfaceEmptyArg) { ExecutionContext* executionContext = ExecutionContext::From(m_scriptState.Get()); - if (!executionContext || executionContext->IsContextSuspended() || - executionContext->IsContextDestroyed()) + DCHECK(!executionContext->IsContextSuspended()); + if (!executionContext || executionContext->IsContextDestroyed()) return; if (!m_scriptState->ContextIsValid()) return; @@ -176,8 +176,8 @@ void V8TestCallbackInterface::voidMethodTestInterfaceEmptyStringArg(TestInterfaceEmpty* testInterfaceEmptyArg, const String& stringArg) { ExecutionContext* executionContext = ExecutionContext::From(m_scriptState.Get()); - if (!executionContext || executionContext->IsContextSuspended() || - executionContext->IsContextDestroyed()) + DCHECK(!executionContext->IsContextSuspended()); + if (!executionContext || executionContext->IsContextDestroyed()) return; if (!m_scriptState->ContextIsValid()) return; @@ -200,8 +200,8 @@ void V8TestCallbackInterface::callbackWithThisValueVoidMethodStringArg(ScriptValue thisValue, const String& stringArg) { ExecutionContext* executionContext = ExecutionContext::From(m_scriptState.Get()); - if (!executionContext || executionContext->IsContextSuspended() || - executionContext->IsContextDestroyed()) + DCHECK(!executionContext->IsContextSuspended()); + if (!executionContext || executionContext->IsContextDestroyed()) return; if (!m_scriptState->ContextIsValid()) return;
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIZoom.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIZoom.cpp index a1abb7e..2d94b6fb 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIZoom.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIZoom.cpp
@@ -17,8 +17,7 @@ const CSSParserToken& token = range.Peek(); CSSValue* zoom = nullptr; if (token.GetType() == kIdentToken) { - zoom = CSSPropertyParserHelpers::ConsumeIdent<CSSValueNormal, CSSValueReset, - CSSValueDocument>(range); + zoom = CSSPropertyParserHelpers::ConsumeIdent<CSSValueNormal>(range); } else { zoom = CSSPropertyParserHelpers::ConsumePercent(range, kValueRangeNonNegative); @@ -34,10 +33,6 @@ (token.GetType() == kPercentageToken && ToCSSPrimitiveValue(zoom)->GetDoubleValue() == 100))) context.Count(UseCounter::kCSSZoomNotEqualToOne); - if (token.Id() == CSSValueReset) - context.CountDeprecation(UseCounter::kCSSZoomReset); - if (token.Id() == CSSValueDocument) - context.CountDeprecation(UseCounter::kCSSZoomDocument); } return zoom; }
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp b/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp index b44925b..d9a49cbf 100644 --- a/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp +++ b/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp
@@ -552,15 +552,6 @@ if (identifier_value.GetValueID() == CSSValueNormal) { ResetEffectiveZoom(state); state.SetZoom(ComputedStyle::InitialZoom()); - } else if (identifier_value.GetValueID() == CSSValueReset) { - state.SetEffectiveZoom(ComputedStyle::InitialZoom()); - state.SetZoom(ComputedStyle::InitialZoom()); - } else if (identifier_value.GetValueID() == CSSValueDocument) { - float doc_zoom = state.RootElementStyle() - ? state.RootElementStyle()->Zoom() - : ComputedStyle::InitialZoom(); - state.SetEffectiveZoom(doc_zoom); - state.SetZoom(doc_zoom); } } else if (value.IsPrimitiveValue()) { const CSSPrimitiveValue& primitive_value = ToCSSPrimitiveValue(value);
diff --git a/third_party/WebKit/Source/core/dom/DOMArrayBuffer.cpp b/third_party/WebKit/Source/core/dom/DOMArrayBuffer.cpp index 3b7c5bc..0887f6b 100644 --- a/third_party/WebKit/Source/core/dom/DOMArrayBuffer.cpp +++ b/third_party/WebKit/Source/core/dom/DOMArrayBuffer.cpp
@@ -5,10 +5,58 @@ #include "core/dom/DOMArrayBuffer.h" #include "bindings/core/v8/DOMDataStore.h" +#include "bindings/core/v8/DOMWrapperWorld.h" #include "platform/wtf/RefPtr.h" +#include "platform/wtf/Vector.h" namespace blink { +static void AccumulateArrayBuffersForAllWorlds( + v8::Isolate* isolate, + DOMArrayBuffer* object, + Vector<v8::Local<v8::ArrayBuffer>, 4>& buffers) { + Vector<RefPtr<DOMWrapperWorld>> worlds; + DOMWrapperWorld::AllWorldsInCurrentThread(worlds); + for (const auto& world : worlds) { + v8::Local<v8::Object> wrapper = world->DomDataStore().Get(object, isolate); + if (!wrapper.IsEmpty()) + buffers.push_back(v8::Local<v8::ArrayBuffer>::Cast(wrapper)); + } +} + +bool DOMArrayBuffer::IsNeuterable(v8::Isolate* isolate) { + Vector<v8::Local<v8::ArrayBuffer>, 4> buffer_handles; + v8::HandleScope handle_scope(isolate); + AccumulateArrayBuffersForAllWorlds(isolate, this, buffer_handles); + + bool is_neuterable = true; + for (const auto& buffer_handle : buffer_handles) + is_neuterable &= buffer_handle->IsNeuterable(); + + return is_neuterable; +} + +bool DOMArrayBuffer::Transfer(v8::Isolate* isolate, + WTF::ArrayBufferContents& result) { + DOMArrayBuffer* to_transfer = this; + if (!IsNeuterable(isolate)) { + to_transfer = + DOMArrayBuffer::Create(Buffer()->Data(), Buffer()->ByteLength()); + } + + if (!to_transfer->Buffer()->Transfer(result)) + return false; + + Vector<v8::Local<v8::ArrayBuffer>, 4> buffer_handles; + v8::HandleScope handle_scope(isolate); + AccumulateArrayBuffersForAllWorlds(isolate, to_transfer, buffer_handles); + + for (const auto& buffer_handle : buffer_handles) + buffer_handle->Neuter(); + + return true; +} + DOMArrayBuffer* DOMArrayBuffer::CreateUninitializedOrNull( unsigned num_elements, unsigned element_byte_size) {
diff --git a/third_party/WebKit/Source/core/dom/DOMArrayBuffer.h b/third_party/WebKit/Source/core/dom/DOMArrayBuffer.h index 584eca4..7da02346 100644 --- a/third_party/WebKit/Source/core/dom/DOMArrayBuffer.h +++ b/third_party/WebKit/Source/core/dom/DOMArrayBuffer.h
@@ -41,6 +41,12 @@ return Create(Buffer()->Slice(begin)); } + bool IsNeuterable(v8::Isolate*); + + // Transfer the ArrayBuffer if it is neuterable, otherwise make a copy and + // transfer that. + bool Transfer(v8::Isolate*, WTF::ArrayBufferContents& result); + v8::Local<v8::Object> Wrap(v8::Isolate*, v8::Local<v8::Object> creation_context) override;
diff --git a/third_party/WebKit/Source/core/dom/DOMArrayBufferBase.h b/third_party/WebKit/Source/core/dom/DOMArrayBufferBase.h index 57dbc97..9f060718 100644 --- a/third_party/WebKit/Source/core/dom/DOMArrayBufferBase.h +++ b/third_party/WebKit/Source/core/dom/DOMArrayBufferBase.h
@@ -24,12 +24,6 @@ const void* Data() const { return Buffer()->Data(); } void* Data() { return Buffer()->Data(); } unsigned ByteLength() const { return Buffer()->ByteLength(); } - bool Transfer(WTF::ArrayBufferContents& result) { - return Buffer()->Transfer(result); - } - bool ShareContentsWith(WTF::ArrayBufferContents& result) { - return Buffer()->ShareContentsWith(result); - } bool IsNeutered() const { return Buffer()->IsNeutered(); } bool IsShared() const { return Buffer()->IsShared(); }
diff --git a/third_party/WebKit/Source/core/dom/DOMSharedArrayBuffer.h b/third_party/WebKit/Source/core/dom/DOMSharedArrayBuffer.h index 5c09421..96ce8db 100644 --- a/third_party/WebKit/Source/core/dom/DOMSharedArrayBuffer.h +++ b/third_party/WebKit/Source/core/dom/DOMSharedArrayBuffer.h
@@ -33,6 +33,10 @@ return Create(WTF::ArrayBuffer::Create(contents)); } + bool ShareContentsWith(WTF::ArrayBufferContents& result) { + return Buffer()->ShareContentsWith(result); + } + v8::Local<v8::Object> Wrap(v8::Isolate*, v8::Local<v8::Object> creation_context) override;
diff --git a/third_party/WebKit/Source/core/editing/EditingUtilities.cpp b/third_party/WebKit/Source/core/editing/EditingUtilities.cpp index ef91e363..860f87fe 100644 --- a/third_party/WebKit/Source/core/editing/EditingUtilities.cpp +++ b/third_party/WebKit/Source/core/editing/EditingUtilities.cpp
@@ -1935,8 +1935,10 @@ EphemeralRange range(Position::FirstPositionInNode(scope), p.ParentAnchoredEquivalent()); - return TextIterator::RangeLength(range.StartPosition(), range.EndPosition(), - true); + + return TextIterator::RangeLength( + range.StartPosition(), range.EndPosition(), + TextIteratorBehavior::AllVisiblePositionsRangeLengthBehavior()); } EphemeralRange MakeRange(const VisiblePosition& start,
diff --git a/third_party/WebKit/Source/core/editing/SelectionController.cpp b/third_party/WebKit/Source/core/editing/SelectionController.cpp index d5e93c8..ac77e75a 100644 --- a/third_party/WebKit/Source/core/editing/SelectionController.cpp +++ b/third_party/WebKit/Source/core/editing/SelectionController.cpp
@@ -97,7 +97,9 @@ static int TextDistance(const PositionInFlatTree& start, const PositionInFlatTree& end) { - return TextIteratorInFlatTree::RangeLength(start, end, true); + return TextIteratorInFlatTree::RangeLength( + start, end, + TextIteratorBehavior::AllVisiblePositionsRangeLengthBehavior()); } bool CanMouseDownStartSelect(Node* node) {
diff --git a/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp b/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp index e319cee6..a328886 100644 --- a/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp
@@ -266,10 +266,14 @@ Range* end_range = Range::Create(GetDocument(), Position::FirstPositionInNode(&scope), visible_end.DeepEquivalent().ParentAnchoredEquivalent()); - int start_index = TextIterator::RangeLength(start_range->StartPosition(), - start_range->EndPosition(), true); + + const TextIteratorBehavior behavior = + TextIteratorBehavior::AllVisiblePositionsRangeLengthBehavior(); + + int start_index = TextIterator::RangeLength( + start_range->StartPosition(), start_range->EndPosition(), behavior); int end_index = TextIterator::RangeLength(end_range->StartPosition(), - end_range->EndPosition(), true); + end_range->EndPosition(), behavior); VisiblePosition paragraph_start(StartOfParagraph(visible_start)); VisiblePosition next_paragraph_start(
diff --git a/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp b/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp index 2e7e9656..285363d 100644 --- a/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp
@@ -1394,17 +1394,22 @@ bool end_in_paragraph = ComparePositions(visible_end, end_of_paragraph_to_move) <= 0; + const TextIteratorBehavior behavior = + TextIteratorBehavior::AllVisiblePositionsRangeLengthBehavior(); + start_index = 0; - if (start_in_paragraph) + if (start_in_paragraph) { start_index = TextIterator::RangeLength( start_of_paragraph_to_move.ToParentAnchoredPosition(), - visible_start.ToParentAnchoredPosition(), true); + visible_start.ToParentAnchoredPosition(), behavior); + } end_index = 0; - if (end_in_paragraph) + if (end_in_paragraph) { end_index = TextIterator::RangeLength( start_of_paragraph_to_move.ToParentAnchoredPosition(), - visible_end.ToParentAnchoredPosition(), true); + visible_end.ToParentAnchoredPosition(), behavior); + } } } @@ -1504,7 +1509,8 @@ destination_index = TextIterator::RangeLength( Position::FirstPositionInNode(GetDocument().documentElement()), - destination.ToParentAnchoredPosition(), true); + destination.ToParentAnchoredPosition(), + TextIteratorBehavior::AllVisiblePositionsRangeLengthBehavior()); const SelectionInDOMTree& destination_selection = SelectionInDOMTree::Builder()
diff --git a/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp b/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp index d3bcf4e..b569a1f 100644 --- a/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp +++ b/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp
@@ -1341,18 +1341,12 @@ int TextIteratorAlgorithm<Strategy>::RangeLength( const PositionTemplate<Strategy>& start, const PositionTemplate<Strategy>& end, - bool for_selection_preservation) { + const TextIteratorBehavior& behavior) { DCHECK(start.GetDocument()); DocumentLifecycle::DisallowTransitionScope disallow_transition( start.GetDocument()->Lifecycle()); int length = 0; - const TextIteratorBehavior& behavior = - TextIteratorBehavior::Builder() - .SetEmitsObjectReplacementCharacter(true) - .SetEmitsCharactersBetweenAllVisiblePositions( - for_selection_preservation) - .Build(); for (TextIteratorAlgorithm<Strategy> it(start, end, behavior); !it.AtEnd(); it.Advance()) length += it.length();
diff --git a/third_party/WebKit/Source/core/editing/iterators/TextIterator.h b/third_party/WebKit/Source/core/editing/iterators/TextIterator.h index efd5e98..4438f9e5 100644 --- a/third_party/WebKit/Source/core/editing/iterators/TextIterator.h +++ b/third_party/WebKit/Source/core/editing/iterators/TextIterator.h
@@ -100,14 +100,14 @@ // TODO(xiaochengh): Avoid default parameters. int CopyTextTo(ForwardsTextBuffer* output, int position = 0) const; - // Computes the length of the given range using a text iterator. The default - // iteration behavior is to always emit object replacement characters for - // replaced elements. When |forSelectionPreservation| is set to true, it - // also emits spaces for other non-text nodes using the - // |TextIteratorEmitsCharactersBetweenAllVisiblePosition| mode. - static int RangeLength(const PositionTemplate<Strategy>& start, - const PositionTemplate<Strategy>& end, - bool for_selection_preservation = false); + // Computes the length of the given range using a text iterator according to + // the specified iteration behavior. The default iteration behavior is to + // always emit object replacement characters for replaced elements. + static int RangeLength( + const PositionTemplate<Strategy>& start, + const PositionTemplate<Strategy>& end, + const TextIteratorBehavior& = + TextIteratorBehavior::DefaultRangeLengthBehavior()); static bool ShouldEmitTabBeforeNode(Node*); static bool ShouldEmitNewlineBeforeNode(Node&);
diff --git a/third_party/WebKit/Source/core/editing/iterators/TextIteratorBehavior.cpp b/third_party/WebKit/Source/core/editing/iterators/TextIteratorBehavior.cpp index 7f6cd321..41909e90 100644 --- a/third_party/WebKit/Source/core/editing/iterators/TextIteratorBehavior.cpp +++ b/third_party/WebKit/Source/core/editing/iterators/TextIteratorBehavior.cpp
@@ -170,4 +170,20 @@ .Build(); } +// static +TextIteratorBehavior TextIteratorBehavior::DefaultRangeLengthBehavior() { + return TextIteratorBehavior::Builder() + .SetEmitsObjectReplacementCharacter(true) + .Build(); +} + +// static +TextIteratorBehavior +TextIteratorBehavior::AllVisiblePositionsRangeLengthBehavior() { + return TextIteratorBehavior::Builder() + .SetEmitsObjectReplacementCharacter(true) + .SetEmitsCharactersBetweenAllVisiblePositions(true) + .Build(); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/iterators/TextIteratorBehavior.h b/third_party/WebKit/Source/core/editing/iterators/TextIteratorBehavior.h index 28e58c4..fe4a712 100644 --- a/third_party/WebKit/Source/core/editing/iterators/TextIteratorBehavior.h +++ b/third_party/WebKit/Source/core/editing/iterators/TextIteratorBehavior.h
@@ -45,6 +45,8 @@ static TextIteratorBehavior EmitsObjectReplacementCharacterBehavior(); static TextIteratorBehavior IgnoresStyleVisibilityBehavior(); + static TextIteratorBehavior DefaultRangeLengthBehavior(); + static TextIteratorBehavior AllVisiblePositionsRangeLengthBehavior(); private: bool collapse_trailing_space_ : 1;
diff --git a/third_party/WebKit/Source/core/frame/Deprecation.cpp b/third_party/WebKit/Source/core/frame/Deprecation.cpp index ab4370b6..2eb92b60e 100644 --- a/third_party/WebKit/Source/core/frame/Deprecation.cpp +++ b/third_party/WebKit/Source/core/frame/Deprecation.cpp
@@ -383,12 +383,6 @@ "-internal-media-controls-overlay-cast-button selector", M61, "5714245488476160"); - case UseCounter::kCSSZoomReset: - return willBeRemoved("\"zoom: reset\"", M59, "4997605029314560"); - - case UseCounter::kCSSZoomDocument: - return willBeRemoved("\"zoom: document\"", M59, "4997605029314560"); - case UseCounter::kSelectionAddRangeIntersect: return "The behavior that Selection.addRange() merges existing Range and " "the specified Range was removed. See "
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.h b/third_party/WebKit/Source/core/frame/UseCounter.h index 7ed3ec6e..c022b034 100644 --- a/third_party/WebKit/Source/core/frame/UseCounter.h +++ b/third_party/WebKit/Source/core/frame/UseCounter.h
@@ -1198,8 +1198,6 @@ kPresentationConnectionListConnectionAvailableEventListener = 1555, kWebAudioAutoplayCrossOriginIframe = 1556, kVRGetDisplays = 1558, - kCSSZoomReset = 1578, - kCSSZoomDocument = 1579, kXSSAuditorBlockedScript = 1581, kXSSAuditorBlockedEntirePage = 1582, kXSSAuditorDisabled = 1583,
diff --git a/third_party/WebKit/Source/core/input/EventHandler.cpp b/third_party/WebKit/Source/core/input/EventHandler.cpp index e8eb453d7..da142b1 100644 --- a/third_party/WebKit/Source/core/input/EventHandler.cpp +++ b/third_party/WebKit/Source/core/input/EventHandler.cpp
@@ -1548,7 +1548,7 @@ // Insert the ancestors of the frame having the new target node to the entered // frame chain. - HeapVector<Member<LocalFrame>> entered_frame_chain; + HeapVector<Member<LocalFrame>, 2> entered_frame_chain; LocalFrame* entered_frame_in_document = targeted_event.GetHitTestResult().InnerNodeFrame(); while (entered_frame_in_document) { @@ -1561,7 +1561,7 @@ size_t index_entered_frame_chain = entered_frame_chain.size(); LocalFrame* exited_frame_in_document = frame_; - HeapVector<Member<LocalFrame>> exited_frame_chain; + HeapVector<Member<LocalFrame>, 2> exited_frame_chain; // Insert the frame from the disagreement between last frames and entered // frames. while (exited_frame_in_document) {
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp b/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp index 14dc866..de326cd 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp
@@ -401,7 +401,7 @@ LayoutSize offset = LayoutBlockFlow::OffsetFromContainer(o); if (Parent()) - offset -= ParentBox()->LocationOffset(); + offset -= ParentBox()->PhysicalLocationOffset(); return offset; }
diff --git a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp index c0329ed..d7ba41c 100644 --- a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp +++ b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
@@ -798,8 +798,14 @@ if (!frame_) return false; - // The Document has now been created. - frame_->GetDocument()->EnforceSandboxFlags(kSandboxAll); + // The MHTML page is loaded in full sandboxing mode with the only + // exception to open new top-level windows. Since the MHTML page stays in a + // unquie origin with script execution disabled, the risk to navigate to + // 'blob:'' and 'filesystem:'' URLs that allow code execution in the page's + // "real" origin is mitigated. + frame_->GetDocument()->EnforceSandboxFlags( + kSandboxAll & + ~(kSandboxPopups | kSandboxPropagatesToAuxiliaryBrowsingContexts)); CommitData(main_resource->Data()->Data(), main_resource->Data()->size()); return true;
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeElement.js b/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeElement.js index 25853dbe..51268fd 100644 --- a/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeElement.js +++ b/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeElement.js
@@ -53,6 +53,7 @@ this._canAddAttributes = true; this._searchQuery = null; this._expandedChildrenLimit = Elements.ElementsTreeElement.InitialChildrenLimit; + this._decorationsThrottler = new Common.Throttler(100); } /** @@ -1086,10 +1087,21 @@ if (this.isClosingTag()) return; - var node = this._node; - if (node.nodeType() !== Node.ELEMENT_NODE) + if (this._node.nodeType() !== Node.ELEMENT_NODE) return; + this._decorationsThrottler.schedule(this._updateDecorationsInternal.bind(this)); + } + + /** + * @return {!Promise} + */ + _updateDecorationsInternal() { + if (!this.treeOutline) + return Promise.resolve(); + + var node = this._node; + if (!this.treeOutline._decoratorExtensions) /** @type {!Array.<!Runtime.Extension>} */ this.treeOutline._decoratorExtensions = runtime.extensions(Components.DOMPresentationUtils.MarkerDecorator); @@ -1127,7 +1139,7 @@ (n === node ? decorations : descendantDecorations).push(decoration); } - Promise.all(promises).then(updateDecorationsUI.bind(this)); + return Promise.all(promises).then(updateDecorationsUI.bind(this)); /** * @this {Elements.ElementsTreeElement}
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/DOMDebuggerModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/DOMDebuggerModel.js index 069e2c861..fc3010b 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/DOMDebuggerModel.js +++ b/third_party/WebKit/Source/devtools/front_end/sdk/DOMDebuggerModel.js
@@ -182,18 +182,24 @@ var currentURL = this._currentURL(); for (var breakpoint of this._domBreakpointsSetting.get()) { - if (breakpoint.url !== currentURL) - continue; - this._domModel.pushNodeByPathToFrontend(breakpoint.path, nodeId => { - var node = nodeId ? this._domModel.nodeForId(nodeId) : null; - if (!node) - return; - var domBreakpoint = new SDK.DOMDebuggerModel.DOMBreakpoint(this, node, breakpoint.type, breakpoint.enabled); - this._domBreakpoints.push(domBreakpoint); - if (breakpoint.enabled) - this._enableDOMBreakpoint(domBreakpoint); - this.dispatchEventToListeners(SDK.DOMDebuggerModel.Events.DOMBreakpointAdded, domBreakpoint); - }); + if (breakpoint.url === currentURL) + this._domModel.pushNodeByPathToFrontend(breakpoint.path, appendBreakpoint.bind(this, breakpoint)); + } + + /** + * @param {!{type: !SDK.DOMDebuggerModel.DOMBreakpoint.Type, enabled: boolean}} breakpoint + * @param {?number} nodeId + * @this {SDK.DOMDebuggerModel} + */ + function appendBreakpoint(breakpoint, nodeId) { + var node = nodeId ? this._domModel.nodeForId(nodeId) : null; + if (!node) + return; + var domBreakpoint = new SDK.DOMDebuggerModel.DOMBreakpoint(this, node, breakpoint.type, breakpoint.enabled); + this._domBreakpoints.push(domBreakpoint); + if (breakpoint.enabled) + this._enableDOMBreakpoint(domBreakpoint); + this.dispatchEventToListeners(SDK.DOMDebuggerModel.Events.DOMBreakpointAdded, domBreakpoint); } }
diff --git a/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.cpp b/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.cpp index 3b44d912..1a40a205 100644 --- a/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.cpp +++ b/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.cpp
@@ -303,8 +303,19 @@ DCHECK_GT(rate, 0); - if (audio_data->IsNeutered()) { - // If audioData is detached (neutered) we need to reject the + v8::Isolate* isolate = script_state->GetIsolate(); + WTF::ArrayBufferContents buffer_contents; + // Detach the audio array buffer from the main thread and start + // async decoding of the data. + if (audio_data->IsNeuterable(isolate) && + audio_data->Transfer(isolate, buffer_contents)) { + DOMArrayBuffer* audio = DOMArrayBuffer::Create(buffer_contents); + + decode_audio_resolvers_.insert(resolver); + audio_decoder_.DecodeAsync(audio, rate, success_callback, error_callback, + resolver, this); + } else { + // If audioData is already detached (neutered) we need to reject the // promise with an error. DOMException* error = DOMException::Create( kDataCloneError, "Cannot decode detached ArrayBuffer"); @@ -312,16 +323,6 @@ if (error_callback) { error_callback->call(this, error); } - } else { - // Detach the audio array buffer from the main thread and start - // async decoding of the data. - WTF::ArrayBufferContents buffer_contents; - audio_data->Transfer(buffer_contents); - DOMArrayBuffer* audio = DOMArrayBuffer::Create(buffer_contents); - - decode_audio_resolvers_.insert(resolver); - audio_decoder_.DecodeAsync(audio, rate, success_callback, error_callback, - resolver, this); } return promise;
diff --git a/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.cpp b/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.cpp index b208f25..a50faac2 100644 --- a/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.cpp +++ b/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.cpp
@@ -52,21 +52,13 @@ DecodingImageGenerator::~DecodingImageGenerator() {} -SkData* DecodingImageGenerator::onRefEncodedData(GrContext* ctx) { +SkData* DecodingImageGenerator::onRefEncodedData() { TRACE_EVENT0("blink", "DecodingImageGenerator::refEncodedData"); - // The GPU only wants the data if it has all been received, since the GPU - // only wants a complete texture. getAsSkData() may require copying, so - // skip it and just return nullptr to avoid a slowdown. (See - // crbug.com/568016 for details about such a slowdown.) - // TODO (scroggo): Stop relying on the internal knowledge of how Skia uses - // this. skbug.com/5485 - if (ctx && !all_data_received_) - return nullptr; - - // Other clients are serializers, which want the data even if it requires - // copying, and even if the data is incomplete. (Otherwise they would - // potentially need to decode the partial image in order to re-encode it.) + // getAsSkData() may require copying, but the clients of this function are + // serializers, which want the data even if it requires copying, and even + // if the data is incomplete. (Otherwise they would potentially need to + // decode the partial image in order to re-encode it.) return data_->GetAsSkData().release(); }
diff --git a/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.h b/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.h index 408fd74..5c5f703 100644 --- a/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.h +++ b/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.h
@@ -65,7 +65,7 @@ void SetCanYUVDecode(bool yes) { can_yuv_decode_ = yes; } protected: - SkData* onRefEncodedData(GrContext* ctx) override; + SkData* onRefEncodedData() override; bool onGetPixels(const SkImageInfo&, void* pixels,
diff --git a/third_party/WebKit/Source/web/tests/MHTMLTest.cpp b/third_party/WebKit/Source/web/tests/MHTMLTest.cpp index e303756..33f9e9ed 100644 --- a/third_party/WebKit/Source/web/tests/MHTMLTest.cpp +++ b/third_party/WebKit/Source/web/tests/MHTMLTest.cpp
@@ -289,8 +289,11 @@ Document* document = frame->GetDocument(); ASSERT_TRUE(document); - // Full sandboxing should be turned on. - EXPECT_TRUE(document->IsSandboxed(kSandboxAll)); + // Full sandboxing with the exception to new top-level windows should be + // turned on. + EXPECT_EQ(kSandboxAll & ~(kSandboxPopups | + kSandboxPropagatesToAuxiliaryBrowsingContexts), + document->GetSandboxFlags()); // MHTML document should be loaded into unique origin. EXPECT_TRUE(document->GetSecurityOrigin()->IsUnique());
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/linux.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/linux.py index ed15115..d0c6bbd 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/linux.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/linux.py
@@ -188,6 +188,7 @@ _log.warn('xdpyinfo check failed with exit code %s while starting Xvfb on "%s".', exit_code, display) self.host.sleep(0.1) _log.fatal('Failed to start Xvfb on display "%s" (xdpyinfo check failed).', display) + self._stop_xvfb() def _find_display(self): """Tries to find a free X display, looping if necessary.""" @@ -219,8 +220,7 @@ for line in self.host.filesystem.read_text_file(self._xvfb_stderr.name).splitlines(): _log.warn('Xvfb stderr: %s', line) self.host.filesystem.remove(self._xvfb_stderr.name) - - + self._xvfb_stdout = self._xvfb_stderr = self._xvfb_process = None def _path_to_driver(self, target=None): binary_name = self.driver_name()
diff --git a/third_party/boringssl/BUILD.generated.gni b/third_party/boringssl/BUILD.generated.gni index 982aa13..000a3be 100644 --- a/third_party/boringssl/BUILD.generated.gni +++ b/third_party/boringssl/BUILD.generated.gni
@@ -158,17 +158,12 @@ "src/crypto/fipsmodule/digest/internal.h", "src/crypto/fipsmodule/digest/md32_common.h", "src/crypto/fipsmodule/is_fips.c", + "src/crypto/fipsmodule/modes/internal.h", + "src/crypto/fipsmodule/rand/internal.h", "src/crypto/hkdf/hkdf.c", "src/crypto/internal.h", "src/crypto/lhash/lhash.c", "src/crypto/mem.c", - "src/crypto/modes/cbc.c", - "src/crypto/modes/cfb.c", - "src/crypto/modes/ctr.c", - "src/crypto/modes/gcm.c", - "src/crypto/modes/internal.h", - "src/crypto/modes/ofb.c", - "src/crypto/modes/polyval.c", "src/crypto/obj/obj.c", "src/crypto/obj/obj_dat.h", "src/crypto/obj/obj_xref.c", @@ -193,14 +188,11 @@ "src/crypto/poly1305/poly1305_vec.c", "src/crypto/pool/internal.h", "src/crypto/pool/pool.c", - "src/crypto/rand/ctrdrbg.c", - "src/crypto/rand/deterministic.c", - "src/crypto/rand/forkunsafe.c", - "src/crypto/rand/fuchsia.c", - "src/crypto/rand/internal.h", - "src/crypto/rand/rand.c", - "src/crypto/rand/urandom.c", - "src/crypto/rand/windows.c", + "src/crypto/rand_extra/deterministic.c", + "src/crypto/rand_extra/forkunsafe.c", + "src/crypto/rand_extra/fuchsia.c", + "src/crypto/rand_extra/rand_extra.c", + "src/crypto/rand_extra/windows.c", "src/crypto/rc4/rc4.c", "src/crypto/refcount_c11.c", "src/crypto/refcount_lock.c", @@ -420,10 +412,10 @@ "linux-aarch64/crypto/bn/armv8-mont.S", "linux-aarch64/crypto/chacha/chacha-armv8.S", "linux-aarch64/crypto/fipsmodule/aesv8-armx64.S", + "linux-aarch64/crypto/fipsmodule/ghashv8-armx64.S", "linux-aarch64/crypto/fipsmodule/sha1-armv8.S", "linux-aarch64/crypto/fipsmodule/sha256-armv8.S", "linux-aarch64/crypto/fipsmodule/sha512-armv8.S", - "linux-aarch64/crypto/modes/ghashv8-armx64.S", ] crypto_sources_linux_arm = [ @@ -432,18 +424,18 @@ "linux-arm/crypto/fipsmodule/aes-armv4.S", "linux-arm/crypto/fipsmodule/aesv8-armx32.S", "linux-arm/crypto/fipsmodule/bsaes-armv7.S", + "linux-arm/crypto/fipsmodule/ghash-armv4.S", + "linux-arm/crypto/fipsmodule/ghashv8-armx32.S", "linux-arm/crypto/fipsmodule/sha1-armv4-large.S", "linux-arm/crypto/fipsmodule/sha256-armv4.S", "linux-arm/crypto/fipsmodule/sha512-armv4.S", - "linux-arm/crypto/modes/ghash-armv4.S", - "linux-arm/crypto/modes/ghashv8-armx32.S", "src/crypto/curve25519/asm/x25519-asm-arm.S", "src/crypto/poly1305/poly1305_arm_asm.S", ] crypto_sources_linux_ppc64le = [ "linux-ppc64le/crypto/fipsmodule/aesp8-ppc.S", - "linux-ppc64le/crypto/modes/ghashp8-ppc.S", + "linux-ppc64le/crypto/fipsmodule/ghashp8-ppc.S", ] crypto_sources_linux_x86 = [ @@ -453,12 +445,12 @@ "linux-x86/crypto/chacha/chacha-x86.S", "linux-x86/crypto/fipsmodule/aes-586.S", "linux-x86/crypto/fipsmodule/aesni-x86.S", + "linux-x86/crypto/fipsmodule/ghash-x86.S", "linux-x86/crypto/fipsmodule/md5-586.S", "linux-x86/crypto/fipsmodule/sha1-586.S", "linux-x86/crypto/fipsmodule/sha256-586.S", "linux-x86/crypto/fipsmodule/sha512-586.S", "linux-x86/crypto/fipsmodule/vpaes-x86.S", - "linux-x86/crypto/modes/ghash-x86.S", ] crypto_sources_linux_x86_64 = [ @@ -469,16 +461,16 @@ "linux-x86_64/crypto/cipher/chacha20_poly1305_x86_64.S", "linux-x86_64/crypto/ec/p256-x86_64-asm.S", "linux-x86_64/crypto/fipsmodule/aes-x86_64.S", + "linux-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S", "linux-x86_64/crypto/fipsmodule/aesni-x86_64.S", "linux-x86_64/crypto/fipsmodule/bsaes-x86_64.S", + "linux-x86_64/crypto/fipsmodule/ghash-x86_64.S", "linux-x86_64/crypto/fipsmodule/md5-x86_64.S", + "linux-x86_64/crypto/fipsmodule/rdrand-x86_64.S", "linux-x86_64/crypto/fipsmodule/sha1-x86_64.S", "linux-x86_64/crypto/fipsmodule/sha256-x86_64.S", "linux-x86_64/crypto/fipsmodule/sha512-x86_64.S", "linux-x86_64/crypto/fipsmodule/vpaes-x86_64.S", - "linux-x86_64/crypto/modes/aesni-gcm-x86_64.S", - "linux-x86_64/crypto/modes/ghash-x86_64.S", - "linux-x86_64/crypto/rand/rdrand-x86_64.S", "src/crypto/curve25519/asm/x25519-asm-x86_64.S", ] @@ -489,12 +481,12 @@ "mac-x86/crypto/chacha/chacha-x86.S", "mac-x86/crypto/fipsmodule/aes-586.S", "mac-x86/crypto/fipsmodule/aesni-x86.S", + "mac-x86/crypto/fipsmodule/ghash-x86.S", "mac-x86/crypto/fipsmodule/md5-586.S", "mac-x86/crypto/fipsmodule/sha1-586.S", "mac-x86/crypto/fipsmodule/sha256-586.S", "mac-x86/crypto/fipsmodule/sha512-586.S", "mac-x86/crypto/fipsmodule/vpaes-x86.S", - "mac-x86/crypto/modes/ghash-x86.S", ] crypto_sources_mac_x86_64 = [ @@ -505,16 +497,16 @@ "mac-x86_64/crypto/cipher/chacha20_poly1305_x86_64.S", "mac-x86_64/crypto/ec/p256-x86_64-asm.S", "mac-x86_64/crypto/fipsmodule/aes-x86_64.S", + "mac-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S", "mac-x86_64/crypto/fipsmodule/aesni-x86_64.S", "mac-x86_64/crypto/fipsmodule/bsaes-x86_64.S", + "mac-x86_64/crypto/fipsmodule/ghash-x86_64.S", "mac-x86_64/crypto/fipsmodule/md5-x86_64.S", + "mac-x86_64/crypto/fipsmodule/rdrand-x86_64.S", "mac-x86_64/crypto/fipsmodule/sha1-x86_64.S", "mac-x86_64/crypto/fipsmodule/sha256-x86_64.S", "mac-x86_64/crypto/fipsmodule/sha512-x86_64.S", "mac-x86_64/crypto/fipsmodule/vpaes-x86_64.S", - "mac-x86_64/crypto/modes/aesni-gcm-x86_64.S", - "mac-x86_64/crypto/modes/ghash-x86_64.S", - "mac-x86_64/crypto/rand/rdrand-x86_64.S", "src/crypto/curve25519/asm/x25519-asm-x86_64.S", ] @@ -525,12 +517,12 @@ "win-x86/crypto/chacha/chacha-x86.asm", "win-x86/crypto/fipsmodule/aes-586.asm", "win-x86/crypto/fipsmodule/aesni-x86.asm", + "win-x86/crypto/fipsmodule/ghash-x86.asm", "win-x86/crypto/fipsmodule/md5-586.asm", "win-x86/crypto/fipsmodule/sha1-586.asm", "win-x86/crypto/fipsmodule/sha256-586.asm", "win-x86/crypto/fipsmodule/sha512-586.asm", "win-x86/crypto/fipsmodule/vpaes-x86.asm", - "win-x86/crypto/modes/ghash-x86.asm", ] crypto_sources_win_x86_64 = [ @@ -541,16 +533,16 @@ "win-x86_64/crypto/cipher/chacha20_poly1305_x86_64.asm", "win-x86_64/crypto/ec/p256-x86_64-asm.asm", "win-x86_64/crypto/fipsmodule/aes-x86_64.asm", + "win-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.asm", "win-x86_64/crypto/fipsmodule/aesni-x86_64.asm", "win-x86_64/crypto/fipsmodule/bsaes-x86_64.asm", + "win-x86_64/crypto/fipsmodule/ghash-x86_64.asm", "win-x86_64/crypto/fipsmodule/md5-x86_64.asm", + "win-x86_64/crypto/fipsmodule/rdrand-x86_64.asm", "win-x86_64/crypto/fipsmodule/sha1-x86_64.asm", "win-x86_64/crypto/fipsmodule/sha256-x86_64.asm", "win-x86_64/crypto/fipsmodule/sha512-x86_64.asm", "win-x86_64/crypto/fipsmodule/vpaes-x86_64.asm", - "win-x86_64/crypto/modes/aesni-gcm-x86_64.asm", - "win-x86_64/crypto/modes/ghash-x86_64.asm", - "win-x86_64/crypto/rand/rdrand-x86_64.asm", ] fuzzers = [
diff --git a/third_party/boringssl/BUILD.generated_tests.gni b/third_party/boringssl/BUILD.generated_tests.gni index 4197e37..6602508 100644 --- a/third_party/boringssl/BUILD.generated_tests.gni +++ b/third_party/boringssl/BUILD.generated_tests.gni
@@ -7,6 +7,7 @@ test_support_sources = [ "src/crypto/test/file_test.cc", "src/crypto/test/file_test.h", + "src/crypto/test/gtest_main.h", "src/crypto/test/malloc.cc", "src/crypto/test/test_util.cc", "src/crypto/test/test_util.h", @@ -21,14 +22,17 @@ "src/crypto/bio/bio_test.cc", "src/crypto/bytestring/bytestring_test.cc", "src/crypto/chacha/chacha_test.cc", + "src/crypto/cmac/cmac_test.cc", + "src/crypto/compiler_test.cc", "src/crypto/constant_time_test.cc", + "src/crypto/curve25519/spake25519_test.cc", "src/crypto/curve25519/x25519_test.cc", "src/crypto/dh/dh_test.cc", "src/crypto/dsa/dsa_test.cc", "src/crypto/ec/ec_test.cc", "src/crypto/err/err_test.cc", "src/crypto/evp/evp_extra_test.cc", - "src/crypto/rand/ctrdrbg_test.cc", + "src/crypto/fipsmodule/rand/ctrdrbg_test.cc", "src/crypto/rsa/rsa_test.cc", "src/crypto/test/gtest_main.cc", ] @@ -75,18 +79,6 @@ deps = invoker.deps } - executable("boringssl_cmac_test") { - sources = [ - "src/crypto/cmac/cmac_test.cc", - ] - sources += test_support_sources - if (defined(invoker.configs_exclude)) { - configs -= invoker.configs_exclude - } - configs += invoker.configs - deps = invoker.deps - } - executable("boringssl_ed25519_test") { sources = [ "src/crypto/curve25519/ed25519_test.cc", @@ -99,18 +91,6 @@ deps = invoker.deps } - executable("boringssl_spake25519_test") { - sources = [ - "src/crypto/curve25519/spake25519_test.cc", - ] - sources += test_support_sources - if (defined(invoker.configs_exclude)) { - configs -= invoker.configs_exclude - } - configs += invoker.configs - deps = invoker.deps - } - executable("boringssl_digest_test") { sources = [ "src/crypto/digest_extra/digest_test.cc", @@ -231,6 +211,30 @@ deps = invoker.deps } + executable("boringssl_gcm_test") { + sources = [ + "src/crypto/fipsmodule/modes/gcm_test.cc", + ] + sources += test_support_sources + if (defined(invoker.configs_exclude)) { + configs -= invoker.configs_exclude + } + configs += invoker.configs + deps = invoker.deps + } + + executable("boringssl_ctrdrbg_vector_test") { + sources = [ + "src/crypto/fipsmodule/rand/ctrdrbg_vector_test.cc", + ] + sources += test_support_sources + if (defined(invoker.configs_exclude)) { + configs -= invoker.configs_exclude + } + configs += invoker.configs + deps = invoker.deps + } + executable("boringssl_hkdf_test") { sources = [ "src/crypto/hkdf/hkdf_test.cc", @@ -267,18 +271,6 @@ deps = invoker.deps } - executable("boringssl_gcm_test") { - sources = [ - "src/crypto/modes/gcm_test.cc", - ] - sources += test_support_sources - if (defined(invoker.configs_exclude)) { - configs -= invoker.configs_exclude - } - configs += invoker.configs - deps = invoker.deps - } - executable("boringssl_obj_test") { sources = [ "src/crypto/obj/obj_test.cc", @@ -351,18 +343,6 @@ deps = invoker.deps } - executable("boringssl_ctrdrbg_vector_test") { - sources = [ - "src/crypto/rand/ctrdrbg_vector_test.cc", - ] - sources += test_support_sources - if (defined(invoker.configs_exclude)) { - configs -= invoker.configs_exclude - } - configs += invoker.configs - deps = invoker.deps - } - executable("boringssl_refcount_test") { sources = [ "src/crypto/refcount_test.cc", @@ -429,7 +409,6 @@ ":boringssl_aes_test", ":boringssl_bn_test", ":boringssl_cipher_test", - ":boringssl_cmac_test", ":boringssl_ctrdrbg_vector_test", ":boringssl_digest_test", ":boringssl_ecdh_test", @@ -452,7 +431,6 @@ ":boringssl_poly1305_test", ":boringssl_pool_test", ":boringssl_refcount_test", - ":boringssl_spake25519_test", ":boringssl_tab_test", ":boringssl_thread_test", ":boringssl_v3name_test",
diff --git a/third_party/boringssl/BUILD.gn b/third_party/boringssl/BUILD.gn index abe39b2..ef900bc 100644 --- a/third_party/boringssl/BUILD.gn +++ b/third_party/boringssl/BUILD.gn
@@ -139,6 +139,18 @@ ":internal_config", "//build/config/compiler:no_chromium_code", ] + + # Chromium infrastructure does not support GTest, only the //base wrapper. + if (build_with_chromium) { + sources -= [ + "src/crypto/test/gtest_main.cc", + + # //base includes its own conflicting malloc shim. + "src/crypto/test/malloc.cc", + ] + sources += [ "gtest_main_chromium.cc" ] + deps += [ "//base/test:test_support" ] + } } test("boringssl_ssl_tests") { @@ -153,6 +165,18 @@ ":internal_config", "//build/config/compiler:no_chromium_code", ] + + # Chromium infrastructure does not support GTest, only the //base wrapper. + if (build_with_chromium) { + sources -= [ + "src/crypto/test/gtest_main.cc", + + # //base includes its own conflicting malloc shim. + "src/crypto/test/malloc.cc", + ] + sources += [ "gtest_main_chromium.cc" ] + deps += [ "//base/test:test_support" ] + } } if (build_with_chromium) {
diff --git a/third_party/boringssl/DEPS b/third_party/boringssl/DEPS index dda2d7c..d2e250f 100644 --- a/third_party/boringssl/DEPS +++ b/third_party/boringssl/DEPS
@@ -3,4 +3,8 @@ "+base", "+testing", ], + "gtest_main_chromium\.cc": [ + "+base", + "+testing", + ], }
diff --git a/third_party/boringssl/err_data.c b/third_party/boringssl/err_data.c index a420f72..af0895401 100644 --- a/third_party/boringssl/err_data.c +++ b/third_party/boringssl/err_data.c
@@ -62,162 +62,163 @@ 0xc348899, 0xc3508a5, 0xc3588c2, - 0xc3608d4, - 0xc3688e2, - 0xc3708f2, - 0xc3788ff, - 0xc38090f, - 0xc38891a, - 0xc390930, - 0xc39893f, - 0xc3a0953, + 0xc3608e2, + 0xc3688f0, + 0xc370900, + 0xc37890d, + 0xc38091d, + 0xc388928, + 0xc39093e, + 0xc39894d, + 0xc3a0961, 0xc3a8845, 0xc3b00ea, + 0xc3b88d4, 0x10320845, - 0x103294ce, - 0x103314da, - 0x103394f3, - 0x10341506, - 0x10348ed1, - 0x10350c42, - 0x10359519, - 0x1036152e, - 0x10369541, - 0x10371560, - 0x10379579, - 0x1038158e, - 0x103895ac, - 0x103915bb, - 0x103995d7, - 0x103a15f2, - 0x103a9601, - 0x103b161d, - 0x103b9638, - 0x103c164f, + 0x103294dc, + 0x103314e8, + 0x10339501, + 0x10341514, + 0x10348edf, + 0x10350c50, + 0x10359527, + 0x1036153c, + 0x1036954f, + 0x1037156e, + 0x10379587, + 0x1038159c, + 0x103895ba, + 0x103915c9, + 0x103995e5, + 0x103a1600, + 0x103a960f, + 0x103b162b, + 0x103b9646, + 0x103c165d, 0x103c80ea, - 0x103d1660, - 0x103d9674, - 0x103e1693, - 0x103e96a2, - 0x103f16b9, - 0x103f96cc, - 0x10400c06, - 0x104096df, - 0x104116fd, - 0x10419710, - 0x1042172a, - 0x1042973a, - 0x1043174e, - 0x10439764, - 0x1044177c, - 0x10449791, - 0x104517a5, - 0x104597b7, + 0x103d166e, + 0x103d9682, + 0x103e16a1, + 0x103e96b0, + 0x103f16c7, + 0x103f96da, + 0x10400c14, + 0x104096ed, + 0x1041170b, + 0x1041971e, + 0x10421738, + 0x10429748, + 0x1043175c, + 0x10439772, + 0x1044178a, + 0x1044979f, + 0x104517b3, + 0x104597c5, 0x104605fb, - 0x1046893f, - 0x104717cc, - 0x104797e3, - 0x104817f8, - 0x10489806, - 0x10490e33, - 0x14320be9, - 0x14328bf7, - 0x14330c06, - 0x14338c18, + 0x1046894d, + 0x104717da, + 0x104797f1, + 0x10481806, + 0x10489814, + 0x10490e41, + 0x14320bf7, + 0x14328c05, + 0x14330c14, + 0x14338c26, 0x143400ac, 0x143480ea, 0x18320083, - 0x18328f27, + 0x18328f35, 0x183300ac, - 0x18338f3d, - 0x18340f51, + 0x18338f4b, + 0x18340f5f, 0x183480ea, - 0x18350f66, - 0x18358f7e, - 0x18360f93, - 0x18368fa7, - 0x18370fcb, - 0x18378fe1, - 0x18380ff5, - 0x18389005, - 0x18390a57, - 0x18399015, - 0x183a102a, - 0x183a9050, - 0x183b0c4e, - 0x183b906f, - 0x183c1081, - 0x183c908c, - 0x183d109c, - 0x183d90ad, - 0x183e10be, - 0x183e90d0, - 0x183f10f9, - 0x183f9112, - 0x1840112a, + 0x18350f74, + 0x18358f8c, + 0x18360fa1, + 0x18368fb5, + 0x18370fd9, + 0x18378fef, + 0x18381003, + 0x18389013, + 0x18390a65, + 0x18399023, + 0x183a1038, + 0x183a905e, + 0x183b0c5c, + 0x183b907d, + 0x183c108f, + 0x183c909a, + 0x183d10aa, + 0x183d90bb, + 0x183e10cc, + 0x183e90de, + 0x183f1107, + 0x183f9120, + 0x18401138, 0x184086d3, - 0x1841105d, - 0x1841903e, - 0x20321151, - 0x2432115d, - 0x24328985, - 0x2433116f, - 0x2433917c, - 0x24341189, - 0x2434919b, - 0x243511aa, - 0x243591c7, - 0x243611d4, - 0x243691e2, - 0x243711f0, - 0x243791fe, - 0x24381207, - 0x24389214, - 0x24391227, - 0x28320c36, - 0x28328c4e, - 0x28330c06, - 0x28338c61, - 0x28340c42, + 0x1841106b, + 0x1841904c, + 0x2032115f, + 0x2432116b, + 0x24328993, + 0x2433117d, + 0x2433918a, + 0x24341197, + 0x243491a9, + 0x243511b8, + 0x243591d5, + 0x243611e2, + 0x243691f0, + 0x243711fe, + 0x2437920c, + 0x24381215, + 0x24389222, + 0x24391235, + 0x28320c44, + 0x28328c5c, + 0x28330c14, + 0x28338c6f, + 0x28340c50, 0x283480ac, 0x283500ea, - 0x2c322bbb, - 0x2c32923e, - 0x2c332bc9, - 0x2c33abdb, - 0x2c342bef, - 0x2c34ac01, - 0x2c352c1c, - 0x2c35ac2e, - 0x2c362c41, + 0x2c322bc9, + 0x2c32924c, + 0x2c332bd7, + 0x2c33abe9, + 0x2c342bfd, + 0x2c34ac0f, + 0x2c352c2a, + 0x2c35ac3c, + 0x2c362c4f, 0x2c36832d, - 0x2c372c4e, - 0x2c37ac60, - 0x2c382c85, - 0x2c38ac9c, - 0x2c392caa, - 0x2c39acba, - 0x2c3a2ccc, - 0x2c3aace0, - 0x2c3b2cf1, - 0x2c3bad10, - 0x2c3c1250, - 0x2c3c9266, - 0x2c3d2d24, - 0x2c3d927f, - 0x2c3e2d41, - 0x2c3ead4f, - 0x2c3f2d67, - 0x2c3fad7f, - 0x2c402d8c, - 0x2c409151, - 0x2c412d9d, - 0x2c41adb0, - 0x2c42112a, - 0x2c42adc1, + 0x2c372c5c, + 0x2c37ac6e, + 0x2c382c93, + 0x2c38acaa, + 0x2c392cb8, + 0x2c39acc8, + 0x2c3a2cda, + 0x2c3aacee, + 0x2c3b2cff, + 0x2c3bad1e, + 0x2c3c125e, + 0x2c3c9274, + 0x2c3d2d32, + 0x2c3d928d, + 0x2c3e2d4f, + 0x2c3ead5d, + 0x2c3f2d75, + 0x2c3fad8d, + 0x2c402d9a, + 0x2c40915f, + 0x2c412dab, + 0x2c41adbe, + 0x2c421138, + 0x2c42adcf, 0x2c430720, - 0x2c43ad02, - 0x2c442c73, + 0x2c43ad10, + 0x2c442c81, 0x30320000, 0x30328015, 0x3033001f, @@ -310,259 +311,259 @@ 0x305e8700, 0x305f0716, 0x305f8720, - 0x34320b47, - 0x34328b5b, - 0x34330b78, - 0x34338b8b, - 0x34340b9a, - 0x34348bd3, - 0x34350bb7, + 0x34320b55, + 0x34328b69, + 0x34330b86, + 0x34338b99, + 0x34340ba8, + 0x34348be1, + 0x34350bc5, 0x3c320083, - 0x3c328c8b, - 0x3c330ca4, - 0x3c338cbf, - 0x3c340cdc, - 0x3c348d06, - 0x3c350d21, - 0x3c358d47, - 0x3c360d60, - 0x3c368d78, - 0x3c370d89, - 0x3c378d97, - 0x3c380da4, - 0x3c388db8, - 0x3c390c4e, - 0x3c398dcc, - 0x3c3a0de0, - 0x3c3a88ff, - 0x3c3b0df0, - 0x3c3b8e0b, - 0x3c3c0e1d, - 0x3c3c8e50, - 0x3c3d0e5a, - 0x3c3d8e6e, - 0x3c3e0e7c, - 0x3c3e8ea1, - 0x3c3f0c77, - 0x3c3f8e8a, + 0x3c328c99, + 0x3c330cb2, + 0x3c338ccd, + 0x3c340cea, + 0x3c348d14, + 0x3c350d2f, + 0x3c358d55, + 0x3c360d6e, + 0x3c368d86, + 0x3c370d97, + 0x3c378da5, + 0x3c380db2, + 0x3c388dc6, + 0x3c390c5c, + 0x3c398dda, + 0x3c3a0dee, + 0x3c3a890d, + 0x3c3b0dfe, + 0x3c3b8e19, + 0x3c3c0e2b, + 0x3c3c8e5e, + 0x3c3d0e68, + 0x3c3d8e7c, + 0x3c3e0e8a, + 0x3c3e8eaf, + 0x3c3f0c85, + 0x3c3f8e98, 0x3c4000ac, 0x3c4080ea, - 0x3c410cf7, - 0x3c418d36, - 0x3c420e33, - 0x40321839, - 0x4032984f, - 0x4033187d, - 0x40339887, - 0x4034189e, - 0x403498bc, - 0x403518cc, - 0x403598de, - 0x403618eb, - 0x403698f7, - 0x4037190c, - 0x4037991e, - 0x40381929, - 0x4038993b, - 0x40390ed1, - 0x4039994b, - 0x403a195e, - 0x403a997f, - 0x403b1990, - 0x403b99a0, + 0x3c410d05, + 0x3c418d44, + 0x3c420e41, + 0x40321847, + 0x4032985d, + 0x4033188b, + 0x40339895, + 0x403418ac, + 0x403498ca, + 0x403518da, + 0x403598ec, + 0x403618f9, + 0x40369905, + 0x4037191a, + 0x4037992c, + 0x40381937, + 0x40389949, + 0x40390edf, + 0x40399959, + 0x403a196c, + 0x403a998d, + 0x403b199e, + 0x403b99ae, 0x403c0064, 0x403c8083, - 0x403d1a24, - 0x403d9a3a, - 0x403e1a49, - 0x403e9a81, - 0x403f1a9b, - 0x403f9aa9, - 0x40401abe, - 0x40409aeb, - 0x40411b08, - 0x40419b23, - 0x40421b3c, - 0x40429b4f, - 0x40431b63, - 0x40439b7b, - 0x40441b92, + 0x403d1a32, + 0x403d9a48, + 0x403e1a57, + 0x403e9a8f, + 0x403f1aa9, + 0x403f9ab7, + 0x40401acc, + 0x40409af9, + 0x40411b16, + 0x40419b31, + 0x40421b4a, + 0x40429b5d, + 0x40431b71, + 0x40439b89, + 0x40441ba0, 0x404480ac, - 0x40451ba7, - 0x40459bb9, - 0x40461bdd, - 0x40469bfd, - 0x40471c0b, - 0x40479c32, - 0x40481c6f, - 0x40489c88, - 0x40491c9f, - 0x40499cb9, - 0x404a1cd0, - 0x404a9cee, - 0x404b1d06, - 0x404b9d1d, - 0x404c1d33, - 0x404c9d45, - 0x404d1d66, - 0x404d9d88, - 0x404e1d9c, - 0x404e9da9, - 0x404f1dd6, - 0x404f9dff, - 0x40501e3a, - 0x40509e4e, - 0x40511e69, - 0x40521e79, - 0x40529e9d, - 0x40531eb5, - 0x40539ec8, - 0x40541edd, - 0x40549f00, - 0x40551f0e, - 0x40559f2b, - 0x40561f38, - 0x40569f51, - 0x40571f69, - 0x40579f7c, - 0x40581f91, - 0x40589fb8, - 0x40591fe7, - 0x4059a014, - 0x405a2028, - 0x405aa038, - 0x405b2050, - 0x405ba061, - 0x405c2074, - 0x405ca0b3, - 0x405d20c0, - 0x405da0d7, - 0x405e2115, - 0x405e8a95, - 0x405f2136, - 0x405fa143, - 0x40602151, - 0x4060a173, - 0x406121b7, - 0x4061a1ef, - 0x40622206, - 0x4062a217, - 0x40632228, - 0x4063a23d, - 0x40642254, - 0x4064a280, - 0x4065229b, - 0x4065a2b2, - 0x406622ca, - 0x4066a2f4, - 0x4067231f, - 0x4067a340, - 0x40682367, - 0x4068a388, - 0x406923ba, - 0x4069a3e8, - 0x406a2409, - 0x406aa429, - 0x406b25b1, - 0x406ba5d4, - 0x406c25ea, - 0x406ca865, - 0x406d2894, - 0x406da8bc, - 0x406e28ea, - 0x406ea91e, - 0x406f293d, - 0x406fa952, - 0x40702965, - 0x4070a982, + 0x40451bb5, + 0x40459bc7, + 0x40461beb, + 0x40469c0b, + 0x40471c19, + 0x40479c40, + 0x40481c7d, + 0x40489c96, + 0x40491cad, + 0x40499cc7, + 0x404a1cde, + 0x404a9cfc, + 0x404b1d14, + 0x404b9d2b, + 0x404c1d41, + 0x404c9d53, + 0x404d1d74, + 0x404d9d96, + 0x404e1daa, + 0x404e9db7, + 0x404f1de4, + 0x404f9e0d, + 0x40501e48, + 0x40509e5c, + 0x40511e77, + 0x40521e87, + 0x40529eab, + 0x40531ec3, + 0x40539ed6, + 0x40541eeb, + 0x40549f0e, + 0x40551f1c, + 0x40559f39, + 0x40561f46, + 0x40569f5f, + 0x40571f77, + 0x40579f8a, + 0x40581f9f, + 0x40589fc6, + 0x40591ff5, + 0x4059a022, + 0x405a2036, + 0x405aa046, + 0x405b205e, + 0x405ba06f, + 0x405c2082, + 0x405ca0c1, + 0x405d20ce, + 0x405da0e5, + 0x405e2123, + 0x405e8aa3, + 0x405f2144, + 0x405fa151, + 0x4060215f, + 0x4060a181, + 0x406121c5, + 0x4061a1fd, + 0x40622214, + 0x4062a225, + 0x40632236, + 0x4063a24b, + 0x40642262, + 0x4064a28e, + 0x406522a9, + 0x4065a2c0, + 0x406622d8, + 0x4066a302, + 0x4067232d, + 0x4067a34e, + 0x40682375, + 0x4068a396, + 0x406923c8, + 0x4069a3f6, + 0x406a2417, + 0x406aa437, + 0x406b25bf, + 0x406ba5e2, + 0x406c25f8, + 0x406ca873, + 0x406d28a2, + 0x406da8ca, + 0x406e28f8, + 0x406ea92c, + 0x406f294b, + 0x406fa960, + 0x40702973, + 0x4070a990, 0x40710800, - 0x4071a994, - 0x407229a7, - 0x4072a9c0, - 0x407329d8, - 0x4073943d, - 0x407429ec, - 0x4074aa06, - 0x40752a17, - 0x4075aa2b, - 0x40762a39, - 0x40769214, - 0x40772a5e, - 0x4077aa80, - 0x40782a9b, - 0x4078aad4, - 0x40792aeb, - 0x4079ab01, - 0x407a2b0d, - 0x407aab20, - 0x407b2b35, - 0x407bab47, - 0x407c2b78, - 0x407cab81, - 0x407d23a3, - 0x407d9e0f, - 0x407e2ab0, - 0x407e9fc8, - 0x407f1c1f, - 0x407f99c6, - 0x40801de6, - 0x40809c47, - 0x40811e8b, - 0x40819dc0, - 0x408228d5, - 0x408299ac, - 0x40831fa3, - 0x4083a265, - 0x40841c5b, - 0x4084a000, - 0x40852085, - 0x4085a19b, - 0x408620f7, - 0x40869e29, - 0x40872902, - 0x4087a1cc, - 0x40881a0d, - 0x4088a353, - 0x40891a5c, - 0x408999e9, - 0x408a260a, - 0x408a981d, - 0x408b2b5c, - 0x408b9ad2, - 0x408c2095, - 0x41f424dc, - 0x41f9256e, - 0x41fe2461, - 0x41fea656, - 0x41ff2747, - 0x420324f5, - 0x42082517, - 0x4208a553, - 0x42092445, - 0x4209a58d, - 0x420a249c, - 0x420aa47c, - 0x420b24bc, - 0x420ba535, - 0x420c2763, - 0x420ca623, - 0x420d263d, - 0x420da674, - 0x4212268e, - 0x4217272a, - 0x4217a6d0, - 0x421c26f2, - 0x421f26ad, - 0x4221277a, - 0x4226270d, - 0x422b2849, - 0x422ba7f7, - 0x422c2831, - 0x422ca7b6, - 0x422d2795, - 0x422da816, - 0x422e27dc, - 0x422eaba2, + 0x4071a9a2, + 0x407229b5, + 0x4072a9ce, + 0x407329e6, + 0x4073944b, + 0x407429fa, + 0x4074aa14, + 0x40752a25, + 0x4075aa39, + 0x40762a47, + 0x40769222, + 0x40772a6c, + 0x4077aa8e, + 0x40782aa9, + 0x4078aae2, + 0x40792af9, + 0x4079ab0f, + 0x407a2b1b, + 0x407aab2e, + 0x407b2b43, + 0x407bab55, + 0x407c2b86, + 0x407cab8f, + 0x407d23b1, + 0x407d9e1d, + 0x407e2abe, + 0x407e9fd6, + 0x407f1c2d, + 0x407f99d4, + 0x40801df4, + 0x40809c55, + 0x40811e99, + 0x40819dce, + 0x408228e3, + 0x408299ba, + 0x40831fb1, + 0x4083a273, + 0x40841c69, + 0x4084a00e, + 0x40852093, + 0x4085a1a9, + 0x40862105, + 0x40869e37, + 0x40872910, + 0x4087a1da, + 0x40881a1b, + 0x4088a361, + 0x40891a6a, + 0x408999f7, + 0x408a2618, + 0x408a982b, + 0x408b2b6a, + 0x408b9ae0, + 0x408c20a3, + 0x41f424ea, + 0x41f9257c, + 0x41fe246f, + 0x41fea664, + 0x41ff2755, + 0x42032503, + 0x42082525, + 0x4208a561, + 0x42092453, + 0x4209a59b, + 0x420a24aa, + 0x420aa48a, + 0x420b24ca, + 0x420ba543, + 0x420c2771, + 0x420ca631, + 0x420d264b, + 0x420da682, + 0x4212269c, + 0x42172738, + 0x4217a6de, + 0x421c2700, + 0x421f26bb, + 0x42212788, + 0x4226271b, + 0x422b2857, + 0x422ba805, + 0x422c283f, + 0x422ca7c4, + 0x422d27a3, + 0x422da824, + 0x422e27ea, + 0x422eabb0, 0x4432072b, 0x4432873a, 0x44330746, @@ -580,143 +581,143 @@ 0x44390800, 0x4439880e, 0x443a0821, - 0x4832123e, - 0x48329250, - 0x48331266, - 0x4833927f, - 0x4c3212a4, - 0x4c3292b4, - 0x4c3312c7, - 0x4c3392e7, + 0x4832124c, + 0x4832925e, + 0x48331274, + 0x4833928d, + 0x4c3212b2, + 0x4c3292c2, + 0x4c3312d5, + 0x4c3392f5, 0x4c3400ac, 0x4c3480ea, - 0x4c3512f3, - 0x4c359301, - 0x4c36131d, - 0x4c369330, - 0x4c37133f, - 0x4c37934d, - 0x4c381362, - 0x4c38936e, - 0x4c39138e, - 0x4c3993b8, - 0x4c3a13d1, - 0x4c3a93ea, + 0x4c351301, + 0x4c35930f, + 0x4c36132b, + 0x4c36933e, + 0x4c37134d, + 0x4c37935b, + 0x4c381370, + 0x4c38937c, + 0x4c39139c, + 0x4c3993c6, + 0x4c3a13df, + 0x4c3a93f8, 0x4c3b05fb, - 0x4c3b9403, - 0x4c3c1415, - 0x4c3c9424, - 0x4c3d143d, - 0x4c3d8c29, - 0x4c3e1496, - 0x4c3e944c, - 0x4c3f14b8, - 0x4c3f9214, - 0x4c401462, - 0x4c409290, - 0x4c411486, - 0x50322dd3, - 0x5032ade2, - 0x50332ded, - 0x5033adfd, - 0x50342e16, - 0x5034ae30, - 0x50352e3e, - 0x5035ae54, - 0x50362e66, - 0x5036ae7c, - 0x50372e95, - 0x5037aea8, - 0x50382ec0, - 0x5038aed1, - 0x50392ee6, - 0x5039aefa, - 0x503a2f1a, - 0x503aaf30, - 0x503b2f48, - 0x503baf5a, - 0x503c2f76, - 0x503caf8d, - 0x503d2fa6, - 0x503dafbc, - 0x503e2fc9, - 0x503eafdf, - 0x503f2ff1, + 0x4c3b9411, + 0x4c3c1423, + 0x4c3c9432, + 0x4c3d144b, + 0x4c3d8c37, + 0x4c3e14a4, + 0x4c3e945a, + 0x4c3f14c6, + 0x4c3f9222, + 0x4c401470, + 0x4c40929e, + 0x4c411494, + 0x50322de1, + 0x5032adf0, + 0x50332dfb, + 0x5033ae0b, + 0x50342e24, + 0x5034ae3e, + 0x50352e4c, + 0x5035ae62, + 0x50362e74, + 0x5036ae8a, + 0x50372ea3, + 0x5037aeb6, + 0x50382ece, + 0x5038aedf, + 0x50392ef4, + 0x5039af08, + 0x503a2f28, + 0x503aaf3e, + 0x503b2f56, + 0x503baf68, + 0x503c2f84, + 0x503caf9b, + 0x503d2fb4, + 0x503dafca, + 0x503e2fd7, + 0x503eafed, + 0x503f2fff, 0x503f8382, - 0x50403004, - 0x5040b014, - 0x5041302e, - 0x5041b03d, - 0x50423057, - 0x5042b074, - 0x50433084, - 0x5043b094, - 0x504430a3, + 0x50403012, + 0x5040b022, + 0x5041303c, + 0x5041b04b, + 0x50423065, + 0x5042b082, + 0x50433092, + 0x5043b0a2, + 0x504430b1, 0x5044843f, - 0x504530b7, - 0x5045b0d5, - 0x504630e8, - 0x5046b0fe, - 0x50473110, - 0x5047b125, - 0x5048314b, - 0x5048b159, - 0x5049316c, - 0x5049b181, - 0x504a3197, - 0x504ab1a7, - 0x504b31c7, - 0x504bb1da, - 0x504c31fd, - 0x504cb22b, - 0x504d323d, - 0x504db25a, - 0x504e3275, - 0x504eb291, - 0x504f32a3, - 0x504fb2ba, - 0x505032c9, + 0x504530c5, + 0x5045b0e3, + 0x504630f6, + 0x5046b10c, + 0x5047311e, + 0x5047b133, + 0x50483159, + 0x5048b167, + 0x5049317a, + 0x5049b18f, + 0x504a31a5, + 0x504ab1b5, + 0x504b31d5, + 0x504bb1e8, + 0x504c320b, + 0x504cb239, + 0x504d324b, + 0x504db268, + 0x504e3283, + 0x504eb29f, + 0x504f32b1, + 0x504fb2c8, + 0x505032d7, 0x505086ef, - 0x505132dc, - 0x58320f0f, - 0x68320ed1, - 0x68328c4e, - 0x68330c61, - 0x68338edf, - 0x68340eef, + 0x505132ea, + 0x58320f1d, + 0x68320edf, + 0x68328c5c, + 0x68330c6f, + 0x68338eed, + 0x68340efd, 0x683480ea, - 0x6c320ead, - 0x6c328c18, - 0x6c330eb8, - 0x74320a0b, + 0x6c320ebb, + 0x6c328c26, + 0x6c330ec6, + 0x74320a19, 0x743280ac, - 0x74330c29, - 0x78320970, - 0x78328985, - 0x78330991, + 0x74330c37, + 0x7832097e, + 0x78328993, + 0x7833099f, 0x78338083, - 0x783409a0, - 0x783489b5, - 0x783509d4, - 0x783589f6, - 0x78360a0b, - 0x78368a21, - 0x78370a31, - 0x78378a44, - 0x78380a57, - 0x78388a69, - 0x78390a76, - 0x78398a95, - 0x783a0aaa, - 0x783a8ab8, - 0x783b0ac2, - 0x783b8ad6, - 0x783c0aed, - 0x783c8b02, - 0x783d0b19, - 0x783d8b2e, - 0x783e0a84, - 0x7c321140, + 0x783409ae, + 0x783489c3, + 0x783509e2, + 0x78358a04, + 0x78360a19, + 0x78368a2f, + 0x78370a3f, + 0x78378a52, + 0x78380a65, + 0x78388a77, + 0x78390a84, + 0x78398aa3, + 0x783a0ab8, + 0x783a8ac6, + 0x783b0ad0, + 0x783b8ae4, + 0x783c0afb, + 0x783c8b10, + 0x783d0b27, + 0x783d8b3c, + 0x783e0a92, + 0x7c32114e, }; const size_t kOpenSSLReasonValuesLen = sizeof(kOpenSSLReasonValues) / sizeof(kOpenSSLReasonValues[0]); @@ -840,6 +841,7 @@ "DIV_BY_ZERO\0" "EXPAND_ON_STATIC_BIGNUM_DATA\0" "INPUT_NOT_REDUCED\0" + "INVALID_INPUT\0" "INVALID_RANGE\0" "NEGATIVE_NUMBER\0" "NOT_A_SQUARE\0"
diff --git a/third_party/boringssl/gtest_main_chromium.cc b/third_party/boringssl/gtest_main_chromium.cc new file mode 100644 index 0000000..128c9be --- /dev/null +++ b/third_party/boringssl/gtest_main_chromium.cc
@@ -0,0 +1,30 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/bind.h" +#include "base/test/launcher/unit_test_launcher.h" +#include "base/test/test_suite.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/boringssl/src/crypto/test/gtest_main.h" + +namespace { + +class BoringSSLTestSuite : public base::TestSuite { + public: + BoringSSLTestSuite(int argc, char** argv) : TestSuite(argc, argv) {} + + void Initialize() override { + TestSuite::Initialize(); + bssl::SetupGoogleTest(); + } +}; + +} // namespace + +int main(int argc, char** argv) { + BoringSSLTestSuite test_suite(argc, argv); + return base::LaunchUnitTests( + argc, argv, + base::Bind(&BoringSSLTestSuite::Run, base::Unretained(&test_suite))); +}
diff --git a/third_party/boringssl/linux-aarch64/crypto/modes/ghashv8-armx64.S b/third_party/boringssl/linux-aarch64/crypto/fipsmodule/ghashv8-armx64.S similarity index 100% rename from third_party/boringssl/linux-aarch64/crypto/modes/ghashv8-armx64.S rename to third_party/boringssl/linux-aarch64/crypto/fipsmodule/ghashv8-armx64.S
diff --git a/third_party/boringssl/linux-arm/crypto/modes/ghash-armv4.S b/third_party/boringssl/linux-arm/crypto/fipsmodule/ghash-armv4.S similarity index 100% rename from third_party/boringssl/linux-arm/crypto/modes/ghash-armv4.S rename to third_party/boringssl/linux-arm/crypto/fipsmodule/ghash-armv4.S
diff --git a/third_party/boringssl/linux-arm/crypto/modes/ghashv8-armx32.S b/third_party/boringssl/linux-arm/crypto/fipsmodule/ghashv8-armx32.S similarity index 100% rename from third_party/boringssl/linux-arm/crypto/modes/ghashv8-armx32.S rename to third_party/boringssl/linux-arm/crypto/fipsmodule/ghashv8-armx32.S
diff --git a/third_party/boringssl/linux-ppc64le/crypto/modes/ghashp8-ppc.S b/third_party/boringssl/linux-ppc64le/crypto/fipsmodule/ghashp8-ppc.S similarity index 100% rename from third_party/boringssl/linux-ppc64le/crypto/modes/ghashp8-ppc.S rename to third_party/boringssl/linux-ppc64le/crypto/fipsmodule/ghashp8-ppc.S
diff --git a/third_party/boringssl/linux-x86/crypto/modes/ghash-x86.S b/third_party/boringssl/linux-x86/crypto/fipsmodule/ghash-x86.S similarity index 100% rename from third_party/boringssl/linux-x86/crypto/modes/ghash-x86.S rename to third_party/boringssl/linux-x86/crypto/fipsmodule/ghash-x86.S
diff --git a/third_party/boringssl/linux-x86_64/crypto/modes/aesni-gcm-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S similarity index 100% rename from third_party/boringssl/linux-x86_64/crypto/modes/aesni-gcm-x86_64.S rename to third_party/boringssl/linux-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S
diff --git a/third_party/boringssl/linux-x86_64/crypto/modes/ghash-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/ghash-x86_64.S similarity index 99% rename from third_party/boringssl/linux-x86_64/crypto/modes/ghash-x86_64.S rename to third_party/boringssl/linux-x86_64/crypto/fipsmodule/ghash-x86_64.S index 4afbc52f8b..7b563e1 100644 --- a/third_party/boringssl/linux-x86_64/crypto/modes/ghash-x86_64.S +++ b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/ghash-x86_64.S
@@ -1,7 +1,7 @@ #if defined(__x86_64__) && !defined(OPENSSL_NO_ASM) .text -.extern OPENSSL_ia32cap_P -.hidden OPENSSL_ia32cap_P +.extern OPENSSL_ia32cap_addr +.hidden OPENSSL_ia32cap_addr .globl gcm_gmult_4bit .hidden gcm_gmult_4bit @@ -890,7 +890,8 @@ jz .Lodd_tail movdqu 16(%rsi),%xmm6 - movl OPENSSL_ia32cap_P+4(%rip),%eax + movq OPENSSL_ia32cap_addr(%rip),%rax + movl 4(%rax),%eax cmpq $0x30,%rcx jb .Lskip4x
diff --git a/third_party/boringssl/linux-x86_64/crypto/rand/rdrand-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/fipsmodule/rdrand-x86_64.S similarity index 100% rename from third_party/boringssl/linux-x86_64/crypto/rand/rdrand-x86_64.S rename to third_party/boringssl/linux-x86_64/crypto/fipsmodule/rdrand-x86_64.S
diff --git a/third_party/boringssl/mac-x86/crypto/modes/ghash-x86.S b/third_party/boringssl/mac-x86/crypto/fipsmodule/ghash-x86.S similarity index 100% rename from third_party/boringssl/mac-x86/crypto/modes/ghash-x86.S rename to third_party/boringssl/mac-x86/crypto/fipsmodule/ghash-x86.S
diff --git a/third_party/boringssl/mac-x86_64/crypto/modes/aesni-gcm-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S similarity index 100% rename from third_party/boringssl/mac-x86_64/crypto/modes/aesni-gcm-x86_64.S rename to third_party/boringssl/mac-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S
diff --git a/third_party/boringssl/mac-x86_64/crypto/modes/ghash-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/ghash-x86_64.S similarity index 99% rename from third_party/boringssl/mac-x86_64/crypto/modes/ghash-x86_64.S rename to third_party/boringssl/mac-x86_64/crypto/fipsmodule/ghash-x86_64.S index 4c98a93..d47f061 100644 --- a/third_party/boringssl/mac-x86_64/crypto/modes/ghash-x86_64.S +++ b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/ghash-x86_64.S
@@ -889,7 +889,8 @@ jz L$odd_tail movdqu 16(%rsi),%xmm6 - movl _OPENSSL_ia32cap_P+4(%rip),%eax + movq _OPENSSL_ia32cap_addr(%rip),%rax + movl 4(%rax),%eax cmpq $0x30,%rcx jb L$skip4x
diff --git a/third_party/boringssl/mac-x86_64/crypto/rand/rdrand-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/fipsmodule/rdrand-x86_64.S similarity index 100% rename from third_party/boringssl/mac-x86_64/crypto/rand/rdrand-x86_64.S rename to third_party/boringssl/mac-x86_64/crypto/fipsmodule/rdrand-x86_64.S
diff --git a/third_party/boringssl/win-x86/crypto/modes/ghash-x86.asm b/third_party/boringssl/win-x86/crypto/fipsmodule/ghash-x86.asm similarity index 100% rename from third_party/boringssl/win-x86/crypto/modes/ghash-x86.asm rename to third_party/boringssl/win-x86/crypto/fipsmodule/ghash-x86.asm
diff --git a/third_party/boringssl/win-x86_64/crypto/modes/aesni-gcm-x86_64.asm b/third_party/boringssl/win-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.asm similarity index 100% rename from third_party/boringssl/win-x86_64/crypto/modes/aesni-gcm-x86_64.asm rename to third_party/boringssl/win-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.asm
diff --git a/third_party/boringssl/win-x86_64/crypto/modes/ghash-x86_64.asm b/third_party/boringssl/win-x86_64/crypto/fipsmodule/ghash-x86_64.asm similarity index 99% rename from third_party/boringssl/win-x86_64/crypto/modes/ghash-x86_64.asm rename to third_party/boringssl/win-x86_64/crypto/fipsmodule/ghash-x86_64.asm index b01f98c..cfccae5b 100644 --- a/third_party/boringssl/win-x86_64/crypto/modes/ghash-x86_64.asm +++ b/third_party/boringssl/win-x86_64/crypto/fipsmodule/ghash-x86_64.asm
@@ -4,7 +4,7 @@ %define ZMMWORD section .text code align=64 -EXTERN OPENSSL_ia32cap_P +EXTERN OPENSSL_ia32cap_addr global gcm_gmult_4bit @@ -931,7 +931,8 @@ jz NEAR $L$odd_tail movdqu xmm6,XMMWORD[16+rdx] - mov eax,DWORD[((OPENSSL_ia32cap_P+4))] + mov rax,QWORD[OPENSSL_ia32cap_addr] + mov eax,DWORD[4+rax] cmp r9,0x30 jb NEAR $L$skip4x
diff --git a/third_party/boringssl/win-x86_64/crypto/rand/rdrand-x86_64.asm b/third_party/boringssl/win-x86_64/crypto/fipsmodule/rdrand-x86_64.asm similarity index 100% rename from third_party/boringssl/win-x86_64/crypto/rand/rdrand-x86_64.asm rename to third_party/boringssl/win-x86_64/crypto/fipsmodule/rdrand-x86_64.asm
diff --git a/third_party/gvr-android-sdk/BUILD.gn b/third_party/gvr-android-sdk/BUILD.gn index 4540008..37067797 100644 --- a/third_party/gvr-android-sdk/BUILD.gn +++ b/third_party/gvr-android-sdk/BUILD.gn
@@ -4,6 +4,11 @@ import("//build/config/android/rules.gni") +android_aar_prebuilt("controller_test_api_java") { + aar_path = "test-libraries/controller_test_api.aar" + proguard_configs = [ "test-libraries/proguard.txt" ] +} + android_aar_prebuilt("gvr_common_java") { aar_path = "common_library.aar" proguard_configs = [ "src/proguard-gvr.txt" ]
diff --git a/third_party/gvr-android-sdk/README.chromium b/third_party/gvr-android-sdk/README.chromium index be951d95..1ba339e 100644 --- a/third_party/gvr-android-sdk/README.chromium +++ b/third_party/gvr-android-sdk/README.chromium
@@ -33,3 +33,9 @@ are downloaded into test-apks/vr_services and test-apks/daydream_home, respectively. The downloaded APKs are the release APKs that are or were publicly available via the Play Store. +In order to run automated end-to-end tests that involve a Daydream controller, +controller_test_api.aar needs to be present. This allows us to send controller +events using broadcasts like a real controller sends them over Bluetooth. The +library is open-sourced similar to the other .aars, but since it's only useful +for Chromium at the moment, it is uploaded to storage instead of to GitHub like +the GVR SDK.
diff --git a/third_party/gvr-android-sdk/test-libraries/controller_test_api.aar.sha1 b/third_party/gvr-android-sdk/test-libraries/controller_test_api.aar.sha1 new file mode 100644 index 0000000..8fd6fe8 --- /dev/null +++ b/third_party/gvr-android-sdk/test-libraries/controller_test_api.aar.sha1
@@ -0,0 +1 @@ +2ef2878590caee4101008b2e4092133c69659c8e \ No newline at end of file
diff --git a/third_party/gvr-android-sdk/test-libraries/proguard.txt b/third_party/gvr-android-sdk/test-libraries/proguard.txt new file mode 100644 index 0000000..9c85a88 --- /dev/null +++ b/third_party/gvr-android-sdk/test-libraries/proguard.txt
@@ -0,0 +1,4 @@ +# Suppress some warnings that block compilation in release builds, but don't +# actually affect anything +-dontwarn java.awt.** +-dontwarn javax.lang.model.element.Modifier
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index d476b29..aca4835 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -22540,6 +22540,16 @@ </summary> </histogram> +<histogram name="Histogram.BadConstructionArguments" enum="HistogramNameHash"> + <owner>asvitkine@chromium.org</owner> + <owner>bcwhite@chromium.org</owner> + <summary> + The hash codes of histograms that were found to have bad construction + arguments. These would be DCHECK exceptions in debug builds but have simply + been logged and corrected as best as possible rather than crash. + </summary> +</histogram> + <histogram name="Histogram.InconsistenciesBrowser" enum="Inconsistencies"> <owner>asvitkine@chromium.org</owner> <summary> @@ -99889,6 +99899,13 @@ <int value="10" label="Persistent histograms created"/> </enum> +<enum name="HistogramNameHash" type="int"> + <summary> + These numbers are the lower 32 bits of the hash of the metric name. + </summary> + <int value="0" label="Missing hash value"/> +</enum> + <enum name="HistoryFaviconsRecoveryEnum" type="int"> <summary>Error states noted in thumbnail_database.cc recovery code.</summary> <obsolete>
diff --git a/tools/perf/benchmarks/blink_perf.js b/tools/perf/benchmarks/blink_perf.js index 465e1ff..bb764cf 100644 --- a/tools/perf/benchmarks/blink_perf.js +++ b/tools/perf/benchmarks/blink_perf.js
@@ -12,6 +12,24 @@ this.isDone = true; }; +testRunner.supportTracing = true; + +// If this is true, blink_perf tests is put on paused waiting for tracing to +// be started. |scheduleTestRun| should be invoked after tracing is started +// to continue blink perf test. +testRunner.isWaitingForTracingStart = false; + +testRunner.startTracing = function(tracingCategories, scheduleTestRun) { + this.tracingCategories = tracingCategories; + this.scheduleTestRun = scheduleTestRun; + this.isWaitingForTracingStart = true; +} + +testRunner.stopTracingAndMeasure = function(traceEventsToMeasure, callback) { + testRunner.traceEventsToMeasure = traceEventsToMeasure; + callback(); +} + window.GCController = {}; GCController.collect = function() {
diff --git a/tools/perf/benchmarks/blink_perf.py b/tools/perf/benchmarks/blink_perf.py index 64a55a45..5bc5efc9 100644 --- a/tools/perf/benchmarks/blink_perf.py +++ b/tools/perf/benchmarks/blink_perf.py
@@ -12,8 +12,14 @@ from telemetry.page import legacy_page_test from telemetry.page import shared_page_state from telemetry import story +from telemetry.timeline import bounds +from telemetry.timeline import model as model_module +from telemetry.timeline import tracing_config + from telemetry.value import list_of_scalar_values from telemetry.value import scalar +from telemetry.value import trace + from benchmarks import pywebsocket_server from measurements import timeline_controller @@ -73,6 +79,53 @@ return ps +def _ComputeTraceEventsThreadTimeForBlinkPerf( + renderer_thread, trace_events_to_measure): + """ Compute the CPU duration for each of |trace_events_to_measure| during + blink_perf test. + + Args: + renderer_thread: the renderer thread which run blink_perf test. + trace_events_to_measure: a list of string names of trace events to measure + CPU duration for. + + Returns: + a dictionary in which each key is a trace event' name (from + |trace_events_to_measure| list), and value is a list of numbers that + represents to total cpu time of that trace events in each blink_perf test. + """ + trace_cpu_time_metrics = {} + + # Collect the bounds of "blink_perf.runTest" events. + test_runs_bounds = [] + for event in renderer_thread.async_slices: + if event.name == "blink_perf.runTest": + test_runs_bounds.append(bounds.Bounds.CreateFromEvent(event)) + test_runs_bounds.sort(key=lambda b: b.min) + + for t in trace_events_to_measure: + trace_cpu_time_metrics[t] = [0.0] * len(test_runs_bounds) + + for event_name in trace_events_to_measure: + curr_test_runs_bound_index = 0 + for event in renderer_thread.IterAllSlicesOfName(event_name): + while (curr_test_runs_bound_index < len(test_runs_bounds) and + event.start > test_runs_bounds[curr_test_runs_bound_index].max): + curr_test_runs_bound_index += 1 + if curr_test_runs_bound_index >= len(test_runs_bounds): + break + curr_test_bound = test_runs_bounds[curr_test_runs_bound_index] + intersect_wall_time = bounds.Bounds.GetOverlapBetweenBounds( + curr_test_bound, bounds.Bounds.CreateFromEvent(event)) + intersect_cpu_time = ( + intersect_wall_time * event.thread_duration / event.duration) + trace_cpu_time_metrics[event_name][curr_test_runs_bound_index] += ( + intersect_cpu_time) + + return trace_cpu_time_metrics + + + class _BlinkPerfMeasurement(legacy_page_test.LegacyPageTest): """Tuns a blink performance test and reports the results.""" @@ -98,8 +151,53 @@ if 'content-shell' in options.browser_type: options.AppendExtraBrowserArgs('--expose-internals-for-testing') + def _ContinueTestRunWithTracing(self, tab): + tracing_categories = tab.EvaluateJavaScript( + 'testRunner.tracingCategories') + config = tracing_config.TracingConfig() + config.enable_chrome_trace = True + config.chrome_trace_config.category_filter.AddFilterString( + 'blink.console') # This is always required for js land trace event + config.chrome_trace_config.category_filter.AddFilterString( + tracing_categories) + tab.browser.platform.tracing_controller.StartTracing(config) + tab.EvaluateJavaScript('testRunner.scheduleTestRun()') + tab.WaitForJavaScriptCondition('testRunner.isDone') + return tab.browser.platform.tracing_controller.StopTracing() + + + def PrintAndCollectTraceEventMetrics(self, trace_cpu_time_metrics, results): + unit = 'ms' + print + for trace_event_name, cpu_times in trace_cpu_time_metrics.iteritems(): + print 'CPU times of trace event "%s":' % trace_event_name + cpu_times_string = ', '.join(['{0:.10f}'.format(t) for t in cpu_times]) + print 'values %s %s' % (cpu_times_string, unit) + avg = 0.0 + if cpu_times: + avg = sum(cpu_times)/len(cpu_times) + print 'avg', '{0:.10f}'.format(avg), unit + results.AddValue(list_of_scalar_values.ListOfScalarValues( + results.current_page, name=trace_event_name, units=unit, + values=cpu_times)) + print + print '\n' + def ValidateAndMeasurePage(self, page, tab, results): - tab.WaitForJavaScriptCondition('testRunner.isDone', timeout=600) + tab.WaitForJavaScriptCondition( + 'testRunner.isDone || testRunner.isWaitingForTracingStart', timeout=600) + trace_cpu_time_metrics = {} + if tab.EvaluateJavaScript('testRunner.isWaitingForTracingStart'): + trace_data = self._ContinueTestRunWithTracing(tab) + trace_value = trace.TraceValue(page, trace_data) + results.AddValue(trace_value) + + trace_events_to_measure = tab.EvaluateJavaScript( + 'window.testRunner.traceEventsToMeasure') + model = model_module.TimelineModel(trace_data) + renderer_thread = model.GetRendererThreadFromTabId(tab.id) + trace_cpu_time_metrics = _ComputeTraceEventsThreadTimeForBlinkPerf( + renderer_thread, trace_events_to_measure) log = tab.EvaluateJavaScript('document.getElementById("log").innerHTML') @@ -120,6 +218,8 @@ print log + self.PrintAndCollectTraceEventMetrics(trace_cpu_time_metrics, results) + # TODO(wangxianzhu): Convert the paint benchmarks to use the new blink_perf # tracing once it's ready.
diff --git a/tools/perf/benchmarks/blink_perf_unittest.py b/tools/perf/benchmarks/blink_perf_unittest.py new file mode 100644 index 0000000..cff0eeb --- /dev/null +++ b/tools/perf/benchmarks/blink_perf_unittest.py
@@ -0,0 +1,156 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +import os +import unittest + +from telemetry import decorators +from telemetry import story +from telemetry.page import page as page_module +from telemetry.testing import options_for_unittests +from telemetry.testing import page_test_test_case +from telemetry.timeline import async_slice +from telemetry.timeline import model as model_module + + +from benchmarks import blink_perf + + +class BlinkPerfTest(page_test_test_case.PageTestTestCase): + _BLINK_PERF_TEST_DATA_DIR = os.path.join(os.path.dirname(__file__), + '..', '..', '..', 'third_party', 'WebKit', 'PerformanceTests', + 'TestData') + + _BLINK_PERF_RESOURCES_DIR = os.path.join(os.path.dirname(__file__), + '..', '..', '..', 'third_party', 'WebKit', 'PerformanceTests', + 'resources') + def setUp(self): + self._options = options_for_unittests.GetCopy() + # pylint: disable=protected-access + self._measurement = blink_perf._BlinkPerfMeasurement() + # pylint: enable=protected-access + + def _CreateStorySetForTestFile(self, test_file_name): + story_set = story.StorySet(base_dir=self._BLINK_PERF_TEST_DATA_DIR, + serving_dirs={self._BLINK_PERF_TEST_DATA_DIR, + self._BLINK_PERF_RESOURCES_DIR}) + page = page_module.Page('file://' + test_file_name, story_set, + base_dir=story_set.base_dir) + story_set.AddStory(page) + return story_set + + def testBlinkPerfTracingMetricsForMeasureTime(self): + results = self.RunMeasurement(measurement=self._measurement, + ps=self._CreateStorySetForTestFile('append-child-measure-time.html'), + options=self._options) + self.assertFalse(results.failures) + self.assertEquals(len(results.FindAllTraceValues()), 1) + + frame_view_layouts = results.FindAllPageSpecificValuesNamed( + 'FrameView::layout') + self.assertEquals(len(frame_view_layouts), 1) + self.assertGreater(frame_view_layouts[0].GetRepresentativeNumber, 0.1) + + update_layout_trees = results.FindAllPageSpecificValuesNamed( + 'UpdateLayoutTree') + self.assertEquals(len(update_layout_trees), 1) + self.assertGreater(update_layout_trees[0].GetRepresentativeNumber, 0.1) + + @decorators.Disabled('android') # crbug.com/715685 + def testBlinkPerfTracingMetricsForMeasureFrameTime(self): + results = self.RunMeasurement(measurement=self._measurement, + ps=self._CreateStorySetForTestFile( + 'color-changes-measure-frame-time.html'), + options=self._options) + self.assertFalse(results.failures) + self.assertEquals(len(results.FindAllTraceValues()), 1) + + frame_view_prepaints = results.FindAllPageSpecificValuesNamed( + 'FrameView::prePaint') + self.assertEquals(len(frame_view_prepaints), 1) + self.assertGreater(frame_view_prepaints[0].GetRepresentativeNumber, 0.1) + + frame_view_painttrees = results.FindAllPageSpecificValuesNamed( + 'FrameView::paintTree') + self.assertEquals(len(frame_view_painttrees), 1) + self.assertGreater(frame_view_painttrees[0].GetRepresentativeNumber, 0.1) + + +# pylint: disable=protected-access +# This is needed for testing _ComputeTraceEventsThreadTimeForBlinkPerf method. +class ComputeTraceEventsMetricsForBlinkPerfTest(unittest.TestCase): + + def _AddBlinkTestSlice(self, renderer_thread, start, end): + s = async_slice.AsyncSlice( + 'blink', 'blink_perf.runTest', + timestamp=start, duration=end - start, start_thread=renderer_thread, + end_thread=renderer_thread) + renderer_thread.AddAsyncSlice(s) + + def testTraceEventMetricsSingleBlinkTest(self): + model = model_module.TimelineModel() + renderer_main = model.GetOrCreateProcess(1).GetOrCreateThread(2) + renderer_main.name = 'CrRendererMain' + + # Set up a main thread model that looks like: + # [ blink_perf.run_test ] + # | [ foo ] [ bar ] [ baz ] + # | | | | | | | | + # 100 120 140 400 420 500 550 600 + # | | | + # CPU dur: 15 18 70 + # + self._AddBlinkTestSlice(renderer_main, 100, 550) + + renderer_main.BeginSlice('blink', 'foo', 120, 122) + renderer_main.EndSlice(140, 137) + + renderer_main.BeginSlice('blink', 'bar', 400, 402) + renderer_main.EndSlice(420, 420) + + # Since this "baz" slice has CPU duration = 70ms, wall-time duration = 100ms + # & its overalapped wall-time with "blink_perf.run_test" is 50 ms, its + # overlapped CPU time with "blink_perf.run_test" is + # 50 * 70 / 100 = 35ms. + renderer_main.BeginSlice('blink', 'baz', 500, 520) + renderer_main.EndSlice(600, 590) + + self.assertEquals( + blink_perf._ComputeTraceEventsThreadTimeForBlinkPerf( + renderer_main, ['foo', 'bar', 'baz']), + {'foo': [15], 'bar': [18], 'baz': [35]}) + + + def testTraceEventMetricsMultiBlinkTest(self): + model = model_module.TimelineModel() + renderer_main = model.GetOrCreateProcess(1).GetOrCreateThread(2) + renderer_main.name = 'CrRendererMain' + + # Set up a main thread model that looks like: + # [ blink_perf.run_test ] [ blink_perf.run_test ] + # | [ foo ] [ bar ] | [ | foo ] | + # | | | | | | | | | | | + # 100 120 140 400 420 440 500 520 600 640 + # | | | + # CPU dur: 15 18 40 + # + self._AddBlinkTestSlice(renderer_main, 100, 440) + self._AddBlinkTestSlice(renderer_main, 520, 640) + + renderer_main.BeginSlice('blink', 'foo', 120, 122) + renderer_main.EndSlice(140, 137) + + renderer_main.BeginSlice('blink', 'bar', 400, 402) + renderer_main.EndSlice(420, 420) + + # Since this "foo" slice has CPU duration = 40ms, wall-time duration = 100ms + # & its overalapped wall-time with "blink_perf.run_test" is 80 ms, its + # overlapped CPU time with "blink_perf.run_test" is + # 80 * 40 / 100 = 32ms. + renderer_main.BeginSlice('blink', 'foo', 500, 520) + renderer_main.EndSlice(600, 560) + + self.assertEquals( + blink_perf._ComputeTraceEventsThreadTimeForBlinkPerf( + renderer_main, ['foo', 'bar', 'baz']), + {'foo': [15, 32], 'bar': [18, 0], 'baz': [0, 0]})
diff --git a/tools/perf/benchmarks/media.py b/tools/perf/benchmarks/media.py index f37ce44..32a408f9 100644 --- a/tools/perf/benchmarks/media.py +++ b/tools/perf/benchmarks/media.py
@@ -41,6 +41,8 @@ # android: See media.android.tough_video_cases below # crbug.com/565180: Only include cases that report time_to_play +@benchmark.Owner(emails=['crouleau@chromium.org'], + component='Internals>Media') @benchmark.Disabled('android') class MediaToughVideoCases(perf_benchmark.PerfBenchmark): """Obtains media metrics for key user scenarios.""" @@ -85,7 +87,8 @@ # crbug.com/565180: Only include cases that don't report time_to_play @benchmark.Disabled('android') -@benchmark.Owner(emails=['crouleau@chromium.org', 'videostack-eng@google.com']) +@benchmark.Owner(emails=['crouleau@chromium.org', 'videostack-eng@google.com'], + component='Internals>Media') class MediaExtra(perf_benchmark.PerfBenchmark): """Obtains extra media metrics for key user scenarios.""" test = media.Media @@ -96,8 +99,9 @@ return 'media.tough_video_cases_extra' -@benchmark.Disabled('android', 'mac') -@benchmark.Owner(emails=['crouleau@chromium.org', 'videostack-eng@google.com']) +@benchmark.Disabled('all') # crbug/676345 +@benchmark.Owner(emails=['crouleau@chromium.org', 'videostack-eng@google.com'], + component='Internals>Media') class MediaNetworkSimulation(perf_benchmark.PerfBenchmark): """Obtains media metrics under different network simulations.""" test = media.Media @@ -109,6 +113,8 @@ @benchmark.Disabled('l', 'android-webview') # WebView: crbug.com/419689. +@benchmark.Owner(emails=['crouleau@chromium.org', 'videostack-eng@google.com'], + component='Internals>Media') class MediaAndroidToughVideoCases(perf_benchmark.PerfBenchmark): """Obtains media metrics for key user scenarios on Android.""" test = media.Media @@ -154,7 +160,10 @@ ['--disable-gesture-requirement-for-media-playback']) +# This isn't running anywhere. See crbug/709161. @benchmark.Enabled('chromeos') +@benchmark.Owner(emails=['crouleau@chromium.org'], + component='Internals>Media') class MediaChromeOS4kOnly(perf_benchmark.PerfBenchmark): """Benchmark for media performance on ChromeOS using only is_4k test content. """ @@ -172,7 +181,10 @@ return 'media.chromeOS4kOnly.tough_video_cases' +# This isn't running anywhere. See crbug/709161. @benchmark.Enabled('chromeos') +@benchmark.Owner(emails=['crouleau@chromium.org'], + component='Internals>Media') class MediaChromeOS(perf_benchmark.PerfBenchmark): """Benchmark for media performance on all ChromeOS platforms. @@ -191,7 +203,8 @@ @benchmark.Disabled('android-webview') # crbug.com/419689 -@benchmark.Owner(emails=['crouleau@chromium.org', 'videostack-eng@google.com']) +@benchmark.Owner(emails=['crouleau@chromium.org', 'videostack-eng@google.com'], + component='Internals>Media>Source') class MediaSourceExtensions(perf_benchmark.PerfBenchmark): """Obtains media metrics for key media source extensions functions.""" test = _MSEMeasurement
diff --git a/tools/perf/benchmarks/webrtc.py b/tools/perf/benchmarks/webrtc.py index de21783..ea1e127 100644 --- a/tools/perf/benchmarks/webrtc.py +++ b/tools/perf/benchmarks/webrtc.py
@@ -51,6 +51,7 @@ return 'webrtc.datachannel' +@benchmark.Disabled('win') @benchmark.Owner(emails=['ehmaldonado@chromium.org', 'phoglund@chromium.org']) class WebrtcStressTest(perf_benchmark.PerfBenchmark): """Measures WebRtc CPU and GPU usage with multiple peer connections."""
diff --git a/ui/android/java/src/org/chromium/ui/base/EventForwarder.java b/ui/android/java/src/org/chromium/ui/base/EventForwarder.java index 77189db2..152e5b92 100644 --- a/ui/android/java/src/org/chromium/ui/base/EventForwarder.java +++ b/ui/android/java/src/org/chromium/ui/base/EventForwarder.java
@@ -148,10 +148,11 @@ || eventAction == MotionEvent.ACTION_POINTER_UP; } - @TargetApi(Build.VERSION_CODES.M) public boolean onMouseEvent(MotionEvent event) { TraceEvent.begin("sendMouseEvent"); + assert mNativeEventForwarder != 0; + MotionEvent offsetEvent = createOffsetMotionEvent(event); try { int eventAction = event.getActionMasked(); @@ -167,10 +168,10 @@ // behaving device, so mLastMouseButtonState is only nonzero on a buggy one. if (eventAction == MotionEvent.ACTION_HOVER_ENTER) { if (mLastMouseButtonState == MotionEvent.BUTTON_PRIMARY) { - sendMouseEvent(event.getEventTime(), MotionEvent.ACTION_BUTTON_RELEASE, - offsetEvent.getX(), offsetEvent.getY(), event.getPointerId(0), - event.getPressure(0), event.getOrientation(0), - event.getAxisValue(MotionEvent.AXIS_TILT, 0), + nativeOnMouseEvent(mNativeEventForwarder, event.getEventTime(), + MotionEvent.ACTION_BUTTON_RELEASE, offsetEvent.getX(), + offsetEvent.getY(), event.getPointerId(0), event.getPressure(0), + event.getOrientation(0), event.getAxisValue(MotionEvent.AXIS_TILT, 0), MotionEvent.BUTTON_PRIMARY, event.getButtonState(), event.getMetaState(), event.getToolType(0)); } @@ -192,11 +193,11 @@ return false; } - sendMouseEvent(event.getEventTime(), eventAction, offsetEvent.getX(), - offsetEvent.getY(), event.getPointerId(0), event.getPressure(0), - event.getOrientation(0), event.getAxisValue(MotionEvent.AXIS_TILT, 0), - event.getActionButton(), event.getButtonState(), event.getMetaState(), - event.getToolType(0)); + nativeOnMouseEvent(mNativeEventForwarder, event.getEventTime(), eventAction, + offsetEvent.getX(), offsetEvent.getY(), event.getPointerId(0), + event.getPressure(0), event.getOrientation(0), + event.getAxisValue(MotionEvent.AXIS_TILT, 0), getMouseEventActionButton(event), + event.getButtonState(), event.getMetaState(), event.getToolType(0)); return true; } finally { offsetEvent.recycle(); @@ -205,12 +206,11 @@ } @TargetApi(Build.VERSION_CODES.M) - public void sendMouseEvent(long timeMs, int action, float x, float y, int pointerId, - float pressure, float orientation, float tilt, int actionButton, int buttonState, - int metaState, int toolType) { - assert mNativeEventForwarder != 0; - nativeOnMouseEvent(mNativeEventForwarder, timeMs, action, x, y, pointerId, pressure, - orientation, tilt, actionButton, buttonState, metaState, toolType); + private int getMouseEventActionButton(MotionEvent event) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) return event.getActionButton(); + + // On <M, the only mice events sent are hover events, which cannot have a button. + return 0; } public boolean onMouseWheelEvent(
diff --git a/ui/compositor/layer_unittest.cc b/ui/compositor/layer_unittest.cc index ebc27076..a9fbea5 100644 --- a/ui/compositor/layer_unittest.cc +++ b/ui/compositor/layer_unittest.cc
@@ -1116,16 +1116,18 @@ WaitForDraw(); } -static void EmptyReleaseCallback(const gpu::SyncToken& sync_token, - bool is_lost) {} - // Checks that the damage rect for a TextureLayer is empty after a commit. TEST_F(LayerWithNullDelegateTest, EmptyDamagedRect) { + base::RunLoop run_loop; + cc::ReleaseCallback callback = + base::Bind([](base::RunLoop* run_loop, const gpu::SyncToken& sync_token, + bool is_lost) { run_loop->Quit(); }, + base::Unretained(&run_loop)); + std::unique_ptr<Layer> root(CreateLayer(LAYER_SOLID_COLOR)); cc::TextureMailbox mailbox(gpu::Mailbox::Generate(), gpu::SyncToken(), GL_TEXTURE_2D); - root->SetTextureMailbox(mailbox, cc::SingleReleaseCallback::Create( - base::Bind(EmptyReleaseCallback)), + root->SetTextureMailbox(mailbox, cc::SingleReleaseCallback::Create(callback), gfx::Size(10, 10)); compositor()->SetRootLayer(root.get()); @@ -1139,9 +1141,14 @@ WaitForCommit(); EXPECT_TRUE(root->damaged_region_for_testing().IsEmpty()); - compositor()->SetRootLayer(nullptr); - root.reset(); - WaitForCommit(); + // The texture mailbox has a reference from an in-flight texture layer. + // We clear the texture mailbox from the root layer and draw a new frame + // to ensure that the texture mailbox is released. + root->SetShowSolidColorContent(); + Draw(); + + // Wait for texture mailbox release to avoid DCHECKs. + run_loop.Run(); } void ExpectRgba(int x, int y, SkColor expected_color, SkColor actual_color) {
diff --git a/ui/ozone/platform/drm/host/drm_display_host_manager.cc b/ui/ozone/platform/drm/host/drm_display_host_manager.cc index c603352..f99ac41 100644 --- a/ui/ozone/platform/drm/host/drm_display_host_manager.cc +++ b/ui/ozone/platform/drm/host/drm_display_host_manager.cc
@@ -155,6 +155,7 @@ DrmDisplayHostManager::~DrmDisplayHostManager() { device_manager_->RemoveObserver(this); proxy_->UnRegisterHandlerForDrmDisplayHostManager(); + proxy_->RemoveGpuThreadObserver(this); } DrmDisplayHost* DrmDisplayHostManager::GetDisplay(int64_t display_id) {
diff --git a/ui/ozone/platform/drm/ozone_platform_gbm.cc b/ui/ozone/platform/drm/ozone_platform_gbm.cc index 58c83ab..f94f1c8 100644 --- a/ui/ozone/platform/drm/ozone_platform_gbm.cc +++ b/ui/ozone/platform/drm/ozone_platform_gbm.cc
@@ -239,6 +239,9 @@ bool using_mojo_; bool single_process_; + // Bridges the DRM, GPU and main threads in mus. This must be destroyed last. + std::unique_ptr<MusThreadProxy> mus_thread_proxy_; + // Objects in the GPU process. std::unique_ptr<DrmThreadProxy> drm_thread_proxy_; std::unique_ptr<GlApiLoader> gl_api_loader_; @@ -257,9 +260,6 @@ std::unique_ptr<DrmDisplayHostManager> display_manager_; std::unique_ptr<DrmOverlayManager> overlay_manager_; - // Bridges the DRM, GPU and main threads in mus. - std::unique_ptr<MusThreadProxy> mus_thread_proxy_; - #if BUILDFLAG(USE_XKBCOMMON) XkbEvdevCodes xkb_evdev_code_converter_; #endif